How to know the plane size in units? - c++

Well the thing is, that I wan't to picture mazes with a different width and height. I'm drawing them in units and my question is, how can I get the plane viewable dimensions in units that I would know how deep inside the screen I would have to draw my maze in order it would be fully seeable. For perspective view I use "::gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 100.0f);"
For example how I get the near plane dimensions(width and height) in OpenGL units or the far plane or any plane between those planes. If I want to picture something entirely seeable I need to know the plane dimensions in OpenGL units or is there another way?

A bit of trigonometry will tell you that: h_near = 2*near*tan(fovy/2) and the same for far: h_far = 2*far*tan(fovy/2)
Then, the ratio will give you the width.
For the "proof", just consider the right-angled triangle formed by the line of view, the vertical of the plane of rendering and back. The length of the line of view is near or far (depending), the angle at the eye position is fovy/2 (i.e. half the view angle) and the vertical on the plane is h_near/2 or h_far/2, as we only get half-way to the plane. Then, the tangent of the angle on a right-angled triangle is equal to the far-side divided by the near-side ...

Related

How to calculate near and far plane for glOrtho in OpenGL

I am using orthographic projection glOrtho for my scene. I implemented a virtual trackball to rotate an object beside that I also implemented a zoom in/out on the view matrix. Say I have a cube of size 100 unit and is located at the position of (0,-40000,0) far from the origin. If the center of rotation is located at the origin once the user rotate the cube and after zoom in or out, it could be position at some where (0,0,2500000) (this position is just an assumption and it is calculated after multiplied by the view matrix). Currently I define a very big range of near(-150000) and far(150000) plane, but some time the object still lie outside either the near or far plane and the object just turn invisible, if I define a larger near and far clipping plane say -1000000 and 1000000, it will produce an ungly z artifacts. So my question is how do I correctly calculate the near and far plane when user rotate the object in real time? Thanks in advance!
Update:
I have implemented a bounding sphere for the cube. I use the inverse of view matrix to calculate the camera position and calculate the distance of the camera position from the center of the bounding sphere (the center of the bounding sphere is transformed by the view matrix). But I couldn't get it to work. can you further explain what is the relationship between the camera position and the near plane?
A simple way is using the "bounding sphere". If you know the data bounding box, the maximum diagonal length is the diameter of the bounding sphere.
Let's say you calculate the distance 'dCC' from the camera position to the center of the sphere. Let 'r' the radius of that sphere. Then:
Near = dCC - r - smallMargin
Far = dCC + r + smallMargin
'smallMargin' is a value used just to avoid clipping points on the surface of the sphere due to numerical precision issues.
The center of the sphere should be the center of rotation. If not, the diameter should grow so as to cover all data.

How to set up OpenGL perspective correction?

I am dealing with an experimental setup where a simple picture is being displayed to a gene-modified fly. The picture is projected on a screen with certain distances to that fly.
Now it's my turn to set up the perspective correction, so that the displayed image, for example a horizontal bar, appears wider in a longer distance to the fly's point of view (experimental setup) . The code now looks like this:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(!USEFRUSTUM)
gluPerspective(90.0f, 2 * width/height, 0.1f, 100.0f);
else
glFrustum(92.3f, 2.3f, -25.0f, 65.0f, 50.0f, 1000.0f);
The values were entered by someone a few years ago and we figured out they are not accurate anymore. However, I am confused which values to enter or to change to make the projection work properly, because as you can see in the experimental setup the fly's field of view is a bit tilted.
I thought about those values:
fovy = angle between a and c
measure width and height on the projection screen
but what is zNear? Should I measure the distance from fly to the top or the bottom of the screen? I dont't get why somebody entered 0.1f, cause that seems for me too near.
How can I know the value of zFar? Is it the maximum distance of an object to the fly?
I got my information on glPerspective from: https://www.ntu.edu.sg/home/ehchua/programming/opengl/CG_BasicsTheory.html
I also checked Simplest way to set up a 3D OpenGL perspective projection , but this post doesn't treat my experimental setup, which is the source of my confusion.
Thank you for any help!
This is one of the prime examples where the frustum method is easier to use than perspective. A frustum is essentially a clipped pyramid. Imagine your fly at the tip of a four sided, tilted pyramid. The near value gives the distance to the pyramid's base and the left, right, bottom and top the perpendicular distance of each side of the pyramids base to the tip. It's perfectly reasonable that the tip is "outside" of the base area. Or in case of your fly the center might be just above the "left" edge.
So assuming your original picture we have this:
"Near" gives the "distance" to the projection screen and right (and of course also top, bottom and left) the respective distances of the tip, err, fly perpendicular to the edges of the screen.
"far" is not important for the projective features and is used solely for determining the depth range.
So what you can program into is the following:
double near = ${distance to screen in mm};
double left = ${perpendicular to left screen edge in mm};
double right = ${perpendicular to right screen edge in mm};
double top = ${perpendicular to top screen edge in mm};
double bottom = ${perpendicular to bottom screen edge in mm};
double s = ${scaling factor from mm into OpenGL units};
double zrange = ${depth range in OpenGL units the far plane is behind near};
glFrustum(s*left, s*right, s*bottom, s*top, s*near, s*near + zrange);
Keep in mind that left, right, top and bottom may be negative. So say you want a symmetrical (unshifted) view in one direction, that left = -bottom and a shift is essentially adding/subtracting to both the same offset.

How to draw a ray/line from the near clipping plane w/ perspective projection?

Simply put - I want to draw a ray/line from the near clipping plane out to the far clipping plane using a perspective projection. I have what I believe are correctly normalized world coordinates generated from a mouse click using methods describe in various OpenGL/graphics programming guides.
The problem I am having is that it seems my ray is being drawn from outside the near clipping plane.
Background: This is for a simple model viewer I am building in Qt that requires a picking capability. I need to draw the ray in order to calculate intersections with objects in the scene. However, my basic problem is that I can seem to draw the ray correctly.
My perspective projection is defined:
gluPerspective(_fov, aspect, 0.1, 100.0);
where _fov is 45.0 degress, and aspect is the ratio of the window width/height.
Using my picking code, I've generated what I believe to be correctly normalized world coordinates based off of mouse clicks. An example of these coordinates:
-0.385753,-0.019608,-0.100000
However, when I try to draw a ray starting at that point, it looks like it is being drawn from outside of the clipping plane:
Maybe I am expecting something different, but in the example above I clicked on the nose of the airplane, generated the world coordinates above, and I am drawing the ray incorrectly (or so I believe). I was hoping to see the line being drawn from the location of the mouse click into the airplane model.
When I draw the ray I first load the identity matrix, and then draw a line from the near clipping plane coordinates to the far plane. Then I draw a sphere at the end of the ray (in this screenshot it is behind the plane).
glPushMatrix();
glLoadIdentity();
glColor3f(0,0,1);
glBegin(GL_LINES);
glVertex3f(_near_ray.x(), _near_ray.y(), _near_ray.z());
glVertex3f(_far_ray.x(), _far_ray.y(), _far_ray.z());
glEnd();
glTranslatef(_far_ray.x(), _far_ray.y(), _far_ray.z());
glColor3f(1,0,0);
glutWireSphere(1, 10, 10);
glPopMatrix();
Any hints as to what I am doing wrong? The _far_ray coordinates are the same as the _near_ray except for the Z field. I want the ray to be drawn straight into the scene.
In The End... I'd just like to know how the draw the ray itself. I understand that there might be errors in my code that generates the coordinates, but what if I just wanted to draw an arbitrary ray from the near clipping plane straight into the scene. That is that I'd like answered.
With perspective projection, a line looks like a point on the screen if and only if it passes through the eye position.
Since you revert modelview matrix to identity, the eye is located at the origin (according to this question). Pass (0, 0, 0) as one of the vertices, and hopefully you'll see that line degenerates into a point.
Generally, the two 3d vectors used as vertices must be collinear.
If you do not revert modelview matrix, then you can draw a line from (eye) to (eye + dir), where eye is the first vector passed to gluLookAt, and dir is the any sufficiently large vector looking into proper direction.

How to get the projection plane in OpenGL

I use the gluPerspective and glLookAt to set my projection matrix and view matrix. If I want to get the coordinate of the eye, it's the first three arguments in the gluLookAt, right?
However, now I need to get the projection plane, that is, the position of the screen in the world coordinate system. You know, if I can calculate the left-bottom corner point and the right-top corner point, the plane is right there!
Could anyone give me a hint about how to do this calculation?
You could use gluUnProject with screen space coordinates (mapping viewport width and height to 0…1) A=(0,0,0), B=(1,0,0) and C=(1,0,0) giving the coplanar points of the projection plane. Adding a fourth point (1,1,0) you get the rectangular limits.

Get rectangle vertices by center, normal, length and height

I am looking for a way to get all the vertices of a rectangle whose center, normal, length and height I know. I am a little weak in maths so please help me.
Edit : the plane is in 3D space.
You can easily calculate the x and y coordinates of the vertices of a rectangle in 2D space given the center, width and height by subtracting/adding half the width/height from the x/y position of the center point.
If you need this in 3D space, this becomes a little more tricky and relies on a bit of trigonometry, but still follows the same principle. You'll need one extra piece of information. You need some way of fixing the orientation of the square in some direction; ie, which direction is the rectangle 'facing'. The normal will allow you to work out what plane the rectangle is on, but without some orientation on that plane, the best you can do is work out a set of possible values in a circle around the center for each of the vertices.