3d - 计算 3D 空间中的视锥体

标签 3d geometry trigonometry lwjgl frustum

我已经绘制了如何计算viewing frustum的边界点的图表。在一个三维空间中。首先,我有两组数据,每组包含三个值:相机的 xyz 坐标和围绕 x、y 和 z 轴的旋转。给定一定的视距,应该可以计算 6 个平面中每个平面的边界点。我一直在使用这些方程来计算远平面的宽度和高度:

hfar = 2 * tan(45/2) * view_distance
wfar = hfar * ratio

hfar 是远平面的高度, wfar 是宽度, ratio 是视口(viewport)宽度除以高度的比率。我一直在使用下图来尝试弄清楚:

enter image description here

我需要找到由 (?,?,?) 注释的点。几天来我一直在尝试计算这些值,但无济于事。任何帮助,将不胜感激。

此外,可以找到一些提供有关该主题信息的好资源 herehere .

编辑:
我制作的另一张图片显示了通过 y 轴的单个切片,俯视 x 轴。它显示了与上图相同的信息,但也显示了我的问题:我无法为远平面的每个边界点计算正确的 z 轴值。

enter image description here

请记住,可以通过 x 轴进行相同的切割,以显示相同的过程,但具有玩家向上或向下看的角度。

最佳答案

计算近平面和远平面的中心点:

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

计算近平面和远平面的宽度和高度:
    real nearHeight = 2 * tan(fovRadians/ 2) * nearDistance;
    real farHeight = 2 * tan(fovRadians / 2) * farDistance;
    real nearWidth = nearHeight * viewRatio;
    real farWidth = farHeight * viewRatio;

计算近平面和远平面的角点:
    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);

从平面的任意三个角计算每个平面,顺时针或逆时针缠绕到指向内(取决于坐标系)。
    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);

关于3d - 计算 3D 空间中的视锥体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13665932/

相关文章:

python - 使用 Mayavi 和 tvkt 进行纹理映射

python - 在Python中如何确定一个点是否在某个平行四边形内部?

geometry - "ray through vertex"检测多边形中的点时的特殊情况

java - 自定义数学函数与提供的数学函数?

actionscript-3 - ActionScript 3 : translating coordinates from object's 3D space to another's?

wolfram-mathematica - 将 Mathematica 中的多个 3D 对象放在同一个 3D 框中

jquery - 3D 变换效果在 Firefox 和 Internet Explorer 中不起作用

matlab:重叠圆圈下的区域

c++ - 绕圆旋转时计算方向

matlab - 在 MatLab 中创建正弦波