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

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

问题描述

我正在尝试找出确定某个点是否在视锥内部的最佳方法。我有工作的方法,但不确定是否太麻烦,也许应该有一种更优雅/更有效的方法。

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 将给出正确的法线。 / p>

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

所以这似乎可行,但我只是想知道我是否以一种愚蠢的方式这样做。直到昨天,我什至不知道交叉产品的含义,所以这对我来说还很陌生,我可能做的事情很愚蠢。

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天全站免登陆