tags:

views:

148

answers:

1

I'm using CML to manage the 3D math in an OpenGL-based interface project I'm making for work. I need to know the width of the viewing frustum at a given distance from the eye point, which is kept as a part of a 4x4 matrix that represents the camera. My goal is to position gui objects along the apparent edge of the viewport, but at some distance into the screen from the near clipping plane.

CML has a function to extract the planes of the frustum, giving them back in Ax + By + Cz + D = 0 form. This frustum is perpendicular to the camera, which isn't necessarily aligned with the z axis of the perspective projection.

I'd like to extract x and z coordinates so as to pin graphical elements to the sides of the screen at different distances from the camera. What is the best way to go about doing it?

Thanks!

+1  A: 

This seems to be a duplicate of http://stackoverflow.com/questions/1243801/finding-side-length-of-a-cross-section-of-a-pyramid-frustum-truncated-pyramid, if you already have a cross-section of known width a known distance from the apex. If you don't have that and you want to derive the answer yourself you can follow these steps.

  1. Take two adjacent planes and find their line of intersection L1. You can use the steps here. Really what you need is the direction vector of the line.
  2. Take two more planes, one the same as in the previous step, and find their line of intersection L2.
  3. Note that all planes of the form Ax + By + Cz + D = 0 go through the origin, so you know that L1 and L2 intersect.
  4. Draw yourself a picture of the direction vectors for L1 and L2, tails at the origin. These form an angle; call it theta. Find theta using the formula for the angle between two vectors, e.g. here.
  5. Draw a bisector of that angle. Draw a perpendicular to the bisector at the distance d you want from the origin (this creates an isosceles triangle, bisected into two congruent right triangles). The length of the perpendicular is your desired frustum width w. Note that w is twice the length of one of the bases of the right triangles.
  6. Let r be the length of the hypotenuses of the right triangles. Then r*cos(theta/2)=d and r*sin(theta/2)=w/2, so tan(theta/2)=(w/2)/d which implies w=2d*tan(theta/2). Since you know d and theta, you are done.

Note that we have found the length of one side of a cross-section of a frustrum. This will work with any perpendicular cross-section of any frustum. This can be extended to adapt it to a non-perpendicular cross-section.

Glenn
I think that post was a little different, in that he new all the dimensions of frustum, where as I have just the parametric form. I can get the dimensions of the near plane because the D values of left,right,top,and bottom are on it, but didn't know how to get another cross section. I think the main problem is that I don't really understand what to do with that parametric form. But, I do know the FOV angle and distance to the camera, so all I really needed was 6, in the end.
structolite