确定点是否在截锥体中 [英] Determine if point is in frustum

查看:19
本文介绍了确定点是否在截锥体中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找出确定一个点是否在截锥体内的最佳方法.我有一些工作,但不确定它是否太麻烦,也许我应该有一种更优雅/更有效的方式来做到这一点.

I'm trying to work out the best way to determine whether a point is inside a frustum. I have something working, but not sure whether it is too cumbersome, and perhaps there is a more elegant / efficient way I should be doing this.

假设我想知道点x"是否在截锥体中:

Suppose I want to find out whether point 'x' is inside a frustrum:

一旦我获得了截锥体的 8 个点(4 个近点,4 个远点)的位置,我将根据由三个点组成的三角形计算截锥体每个平面的法线.例如(如上图所示),对于右侧,我从三个点制作两个向量:

Once I have the locations of the 8 points of the frustrum (4 near points, four far points), I am calculating the normal for each plane of the frustum based on a triangle made from three of the points. For example (as in the diagram above), for the right side, I am making two vectors from three of the points:

Vector U = FBR - NBR
Vector V = FTR - NBR

然后我在这两个向量之间做叉积,确保法线指向截锥体内部的缠绕顺序是正确的,在这种情况下 V x U 将给出正确的法线.

Then I am making the cross product between these two vectors, ensuring that the winding order is correct for the normal to be pointing inside the frustum, in this case V x U will give the correct normal.

Right_normal = V x U

一旦我有了每个平面的法线,我就会通过从 x 到平面的一个点绘制一个向量来检查点 x 是在平面的前面还是后面:

Once I have the normal for each plane, I am then checking whether point x is in front of or behind the plane by drawing a vector from x to one of the plane's points:

Vector xNBR = x - NBR

然后我正在做这个向量和法线之间的点积并测试答案是否为正,确认点 x 是否是截头体平面的正确一侧:

Then I am doing the dot product between this vector and the normal and testing whether the answer is positive, confirming whether point x is the correct side of that plane of the frustrum:

if ( xNBR . Right_normal < 0 )
{
    return false;
}
else continue testing x against other planes...

如果所有平面的 x 都是正的,那么它在截锥体内.

If x is positive for all planes, then it is inside the frustum.

所以这似乎有效,但我只是想知道我是否以愚蠢的方式这样做.直到昨天我才知道交叉产品"是什么意思,所以这对我来说很新鲜,我可能会做一些很愚蠢的事情.

So this seems to work, but I'm just wondering whether I'm doing this in a stupid way. I didn't even know what 'cross product' meant until yesterday, so it's all rather new to me and I might be doing something rather silly.

推荐答案

为了适应您采用的方法,而不是完全改变它,您可以利用两个平面对平行的事实.只为那对平面创建一个法线.您已经对位于其中一个平面前面"的点进行了测试,但假设您知道截锥体的深度,则可以使用相同的距离来测试该点与另一个平行面的相对位置.

To adapt the approach you have taken, rather than change it totally, you can make use of the fact that 2 of the pairs of planes are parallel. Create only one normal for that pair of planes. You already have the test for the point being "in front" of one of the planes, but assuming you know the depth of the frustum, you can use the same distance to test the point against the other parallel face.

double distancePastFrontPlane = xNBR . Right_normal;
if (distancePastFrontPlane < 0 )
{
    // point is in front of front plane
    return false;
    if(distancePastFrontPlane > depthFaceRtoFaceL)
    {
        // point is behind back plane
        return false;
    }
}

如果您有多个点要针对同一个平截头体进行测试,您会受益,因为您只需计算一次平截头体深度(每对平行平面).

If you have multiple points to test against the same frustum you can benefit because you only calculate the frustum depth once (per pair of parallel planes).

这篇关于确定点是否在截锥体中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆