How to get the distance of camera from objects plane?

Hello,

I am working on rendering vector plot. I have the following projection settings

 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 glOrtho(centerp.x-screenwidth/2, centerp.x+screenwidth/2, 
         centerp.y-screenheight/2, centerp.y+screenheight/2, 1.0, 10000.0);

With the above projection, how can I calculate the distance of the object’s plane to the camera’s plane. i.e. how can I find from how much distance, I am viewing the object?

I need this, in order to perform scaling of vector arrows(glyphs). i.e. as I zoom in/out, the vector arrows should be scaled in order to maintain its actual dimension. So I thought probably based on the distance of camera from the object plane, the vector arrows can be scaled.

Any suggestions or comments?

Thanks & Regards
Rakesh Patil

[QUOTE=rakeshthp;1255140]I am working on rendering vector plot. I have the following projection settings

 glOrtho(centerp.x-screenwidth/2, centerp.x+screenwidth/2, 
         centerp.y-screenheight/2, centerp.y+screenheight/2, 1.0, 10000.0);

With the above projection, how can I calculate the distance of the object’s plane to the camera’s plane. i.e. how can I find from how much distance, I am viewing the object?[/QUOTE]
That question isn’t meaningful. An orthographic projection has the viewpoint infinitely far away from any object.

You can’t “zoom” an orthographic projection; the field-of-view angle is always zero.

 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 glOrtho(centerp.x-screenwidth/2, centerp.x+screenwidth/2, 
         centerp.y-screenheight/2, centerp.y+screenheight/2, 1.0, 10000.0);

With the above projection, how can I calculate the distance of the object’s plane to the camera’s plane. i.e. how can I find from how much distance, I am viewing the object? I need this, in order to perform scaling of vector arrows(glyphs). i.e. as I zoom in/out, the vector arrows should be scaled in order to maintain its actual dimension. So I thought probably based on the distance of camera from the object plane, the vector arrows can be scaled.
Not really sure what you are asking. Do you want the arrows to change size as you zoom in or out? Or, do you want them to remain the same size as you zoom in and out? Are your arrows raster patterns (like raster font), or are they OpenGL lines, polygons, etc.

@GClements:
I perform zooming by changing the values of left, right, top and bottom. I perform panning also by changing the left, right, top and bottom parameters. I don’t know whether it is correct way of doing, but it does work for 2D data. If this is not the correct approach, then kindly guide me how to get correct zooming and panning.

@Carmine:
My arrows are opengl lines only currently. To answer your first question, suppose I am viewing at four cars from a distance ‘d’ where all four cars appear to be of actual size. Now if I move away from those cars, in real world, the cars would appear small sized. And if I move near to them they would appear much bigger, or in some case, some part of car would be out of my vision if I go more closer. I don’t want this effect with the arrows. I want the arrows to look of same size, irrelevant of the distance of camera. So, it is quite obvious that as the camera moves away from arrows, the arrows must be scaled with large value to get the same size, and the arrows must be scaled with small value as the camera moves towards the arrow.

I hope I’ve made it more clearer as what I want to achieve.

Thanks & Regards
Rakesh Patil

Hi Rakesh, since you are using glOrtho you are doing parallel projection in your scene. Thus your objects (the arrows) will not change in size on your viewing plane regardless of the distance of the camera. I believe this is what GClements is saying :slight_smile:

Thus your objects (the arrows) will not change in size on your viewing plane regardless of the distance of the camera

Yes. I agree, and that’s why I want to scale the arrows as the camera moves front and back.

Thanks & regards

Rakesh Patil

My arrows are opengl lines only currently. To answer your first question, suppose I am viewing at four cars from a distance ‘d’ where all four cars appear to be of actual size. Now if I move away from those cars, in real world, the cars would appear small sized. And if I move near to them they would appear much bigger, or in some case, some part of car would be out of my vision if I go more closer. I don’t want this effect with the arrows. I want the arrows to look of same size, irrelevant of the distance of camera. So, it is quite obvious that as the camera moves away from arrows, the arrows must be scaled with large value to get the same size, and the arrows must be scaled with small value as the camera moves towards the arrow.
So your are zooming in and out by changing the width (w) and height (h) in your glOrtho command. There is really no distance from the camera to your objects in an orthographic projection, which is why you can’t figure out what ‘d’ is. What should be done is to scale each car around its centroid by the inverse of the relative change in w and/or h. For example, say you double the width of your window but don’t change the height. Each car should be scaled by 0.5 in the x direction and no scaling in y. The GL command would be glScalef (0.5, 1.0, 1.0), where 0.5 is the inverse of the relative change in viewport width. A more detailed example: if the original window was 500 units wide and 300 units high, and the new window is 700 units wide by 400 units high, the gl command would be glScalef (sx, sy, 1), where sx = 500/700, and sy = 300/400. The scale command must be applied to each car individually about its centroid. This means: translate the car to the origin, apply the scaling, then transfer the car back to where it started. Give this a try and let us know how it goes.

glOrtho() is good for taking measurements off the screen, but not for undistorted viewing with the screen at arms length, or with a large screen in a small room. For that you should use gluPerspective() if viewing on-axis, or glFrustum() if viewing off-axis.

To do what you want with glOrtho, you just need to keep track of the scaling and rotating you are doing (in eye coordinates) in your projection matrix with glOrtho, and undo that scaling and rotation in Object coordinates for your arrow: Place the head of your arrow at (0,0,0) in arrow object coordinates. Place the tail some standard distance away in +x. Then do the following matrix multiplies on the arrow-side (right side) of the m-v-p transformation, 1) inverse-glOrtho-scale, 2) inverse-glOrtho-rotate 3) translate in car coordinates to place on the car, then multiply on the left by the model-view-projection matrix you use to view the car. I can be more explicit if you need.

@Roaoul
Are you trying to explain the same thing what carmine explained?

[QUOTE=rakeshthp;1255227]@Roaoul
Are you trying to explain the same thing what carmine explained?[/QUOTE]
Not much. I think we have different ideas of what you are trying to do. Carmine’s directions would replace calling glOrtho() on resizing/shaping your window, I believe. If you follow those directions to replace the projection matrix, and you also separately scale your cars as directed, then I think you’ll get a doubling of the scaling of the cars, not a zeroing of scaling of arrows.

But I interpreted your post as that you are trying to zoom in and out of some cars, using glOrtho() on the projection matrix, and want some annotation arrows you are drawing pointing to the cars to remain the same size on screen regardless of whether the cars are tiny or huge. Right?

My earlier post mistakenly included rotation considerations. You have none in the projection matrix to worry about, so please disregard all my rotation remarks (step 2). The rest is good. But you know, if you rotate your view (with modelView), then the arrows will also rotate unless you undo that too.

So anyway, given a beginning r,l,t,b,n,f inputs for your reference glOrtho() projection matrix, here is how to zoom and leave your arrows unchanged in size on screen:
When you zoom, you must change l-r and t-b and n-f all by the same factor, say zf. Zoom out is zf > 1; zoom in is zf < 1. In your code above, you would multiply screenwidth and screenheight by zf. Also make sure your new n-f ends up zf(n_old-f_old), or your near and far clipping planes won’t zoom in and out (and you might get artifacts if you rotate your view).
Place your camera with the model-view matrix, and push it before placing each car. Place the car with glTranslate on the modelview matrix. Render the car and push the matrix for the arrows. For each arrow on that car, call glTranslate for where on the car you want the arrow to point, glScale(1/zf, 1/zf, 1/zf) (undoes your zoom), render your arrow, and pop for the next arrow. After the arrows, pop for the next car. I hope that helps!

@Roaoul

Thanks for the explaination. Firstly, I am sorry for improperly presenting what I require. The car’s post was just an example. What I actually need is to render vector plot (quiver plot). The car has nothing to do with the arrows. I am working on a scientific application where I need to display vectors over a mesh. Like this one here. The concept of arrows what you interpreted is right. Regardless of what amount user zoom’s in/out, the size of arrows should appear same for the user.

Let me explain why I need to scale the arrow size. Suppose the mesh is a huge mesh and the mesh nodes are very densely placed (i.e. very close to each other node). In this case I would get vector plot also dense. i.e. a black patch would appear at that region. So as a user, I would like to zoom that area and see what exactly is happening in that area. Now when I zoom, if I do not scale arrows, they will appear as a patch only. If I scale those arrows, then user will get clear idea what is going on. That’s the main Idea behind it.

Anyways, I shall try what you told and get back to you. If you have any further clarification of suggestions, kindly post it here.

Thanks & Regards
Rakesh Patil

@rakeshthp

How cool. I did something similar for my dissertation, but did it all in PostScript written by FORTRAN, since OpenGL wasn’t available way back then. I still have the code. Is your mesh flat like a desktop or curved like a ball? What I gave you should work for flat, but you would probably want more for a curved surface (various rotation features).

Regards, Paul

[QUOTE=Roaoul;1255250]@rakeshthp

How cool. I did something similar for my dissertation, but did it all in PostScript written by FORTRAN, since OpenGL wasn’t available way back then. I still have the code. Is your mesh flat like a desktop or curved like a ball? What I gave you should work for flat, but you would probably want more for a curved surface (various rotation features).

Regards, Paul[/QUOTE]

Thanks a lot Paul. That really helped me a lot. Well, I would need your advice later stage also. Because presently this is for a two dimensional grid in a single plane (flat). For 3d grid whether it will be same technique, or it would change?

Thanks & Regards
Rakesh Patil