问题描述:

I have drawn diagram after diagram of how to calculate the bounding points of the viewing frustum in a three-dimensional space. To start, I have a two sets of data containing three values each: the xyz coordinates of the camera and the rotation around the x, y, and z axis. Given a certain view distance, it should be possible to calculate the bounding points of each of the 6 planes. I have been using these equations to calculate the width and height of the far plane:

`hfar = 2 * tan(45/2) * view_distance`

wfar = hfar * ratio

hfar being the height of the far plane, wfar being the width, and ratio being the ratio of the view port width divided by the height. I have been using the following diagram to try and figure it out:

I need to find the points annotated by (?,?,?). I have been trying to calculate these values for a few days now but to no avail. Any help would be appreciated.

Also, some nice sources providing information on the topic can be found here and here.

EDIT:

Another image I whipped up shows a single slice through the y axis looking down on the x axis. It shows the same information as the image above, but it also shows my issue: I can't calculate the proper z axis values for each of the bounding points of the far plane.

Keep in mind, the same cut could be made through the x axis to show the same process but with the angle at which the player is looking up or down.

I think the general problem you're looking to solve is how to rotate an object in 3d. From what I understand, you know how to get the magnitude of your camera's vectors, but not their orientation. You have angular rotations defined about the x,y and z axes that you want to apply to your camera's [up],[side] and [view/lookAt] vectors.

The above picture illustrates what I mean by up, side and lookAt vectors. They're relevant to your frustum as shown in the below pic.

Here is some rough code in C++ that'll rotate a point given an axis and an angle:

```
Vec3 RotatedBy(Vec3 const &axisVec, double angleDegCCW)
{
if(!angleDegCCW)
{ return Vec3(this->x,this->y,this->z); }
Vec3 rotatedVec;
double angleRad = angleDegCCW*3.141592653589/180.0;
rotatedVec = this->ScaledBy(cos(angleRad)) +
(axisVec.Cross(*this)).ScaledBy(sin(angleRad)) +
axisVec.ScaledBy(axisVec.Dot(*this)).ScaledBy(1-cos(angleRad));
return rotatedVec;
}
```

Once you have the rotated up, view and side vectors you can find your far plane's corners.

Compute the center points of the near and far planes:

```
vec3 nearCenter = camPos - camForward * nearDistance;
vec3 farCenter = camPos - camForward * farDistance;
```

Compute the widths and heights of the near and far planes:

```
real nearHeight = 2 * tan(fovRadians/ 2) * nearDistance;
real farHeight = 2 * tan(fovRadians / 2) * farDistance;
real nearWidth = nearHeight * viewRatio;
real farWidth = farHeight * viewRatio;
```

Compute the corner points from the near and far planes:

```
vec3 farTopLeft = farCenter + camUp * (farHeight*0.5) - camRight * (farWidth*0.5);
vec3 farTopRight = farCenter + camUp * (farHeight*0.5) + camRight * (farWidth*0.5);
vec3 farBottomLeft = farCenter - camUp * (farHeight*0.5) - camRight * (farWidth*0.5);
vec3 farBottomRight = farCenter - camUp * (farHeight*0.5) + camRight * (farWidth*0.5);
vec3 nearTopLeft = nearCenter + camY * (nearHeight*0.5) - camX * (nearWidth*0.5);
vec3 nearTopRight = nearCenter + camY * (nearHeight*0.5) + camX * (nearWidth*0.5);
vec3 nearBottomLeft = nearCenter - camY * (nearHeight*0.5) - camX * (nearWidth*0.5);
vec3 nearBottomRight = nearCenter - camY * (nearHeight*0.5) + camX * (nearWidth*0.5);
```

Compute each plane from any three corners of the plane, wound CW or CCW to point inward (depending on coordinate system).

```
vec3 p0, p1, p2;
p0 = nearBottomLeft; p1 = farBottomLeft; p2 = farTopLeft;
vec3 leftPlaneNormal = Normalize(Cross(p1-p0, p2-p1));
vec3 leftPlaneOffset = Dot(leftPlaneNormal, p0);
p0 = nearTopLeft; p1 = farTopLeft; p2 = farTopRight;
vec3 topPlaneNormal = Normalize(Cross(p1-p0, p2-p1));
vec3 topPlaneNormal = Dot(topPlaneNormal , p0);
p0 = nearTopRight; p1 = farTopRight; p2 = farBottomRight;
vec3 rightPlaneNormal = Normalize(Cross(p1-p0, p2-p1));
vec3 rightPlaneNormal = Dot(rightPlaneNormal , p0);
p0 = nearBottomRight; p1 = farBottomRight; p2 = farBottomLeft;
vec3 bottomPlaneNormal = Normalize(Cross(p1-p0, p2-p1));
vec3 bottomPlaneNormal = Dot(bottomPlaneNormal , p0);
```

您可能感兴趣的文章：

- http - Is Heroku overriding my 500 error message?
- java - Migrate EJB 2.1 from WebSphere 6.1 to JBoss EAP 6.1
- jquery - How can I bind appended elements?
- java - Loop invariants quicksort
- asp.net web api - Web Api 2 with OWIN OAuth Bearer tokens
- php - Reading a specific line from a text file
- clr - Any implementation of an Unrolled Linked List in C#?
- Finding Hudson Log Files
- Forward to a payment-gateway together with POST data using cURL (or any other PHP server side solution)
- WCF in Winforms app - is it always single-threaded?

随机阅读：

**推荐内容**-

**热点内容**-
- php - Reading a specific line from a text file
- clr - Any implementation of an Unrolled Linked List in C#?
- Finding Hudson Log Files
- Forward to a payment-gateway together with POST data using cURL (or any other PHP server side solution)
- WCF in Winforms app - is it always single-threaded?
- git svn - git svn fetch does not fetch a Subversion commit message modified after initial clone
- java me - Why I am getting the bad length exception when I am running this application?
- java - How to get string.format to complain at compile time
- ruby on rails - Trigger observer of parent class on change
- python - Issue with URL pattern in Django with webmonkey tutorial