【问题标题】:Determine if point is in frustum确定点是否在平截头体中
【发布时间】:2017-04-30 23:44:21
【问题描述】:

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

假设我想知道点 'x' 是否在截锥体内:

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

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

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

Right_normal = V x U

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

Vector xNBR = x - NBR

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

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

如果 x 对于所有平面都是正数,那么它在截锥体内。

所以这似乎可行,但我只是想知道我是否以愚蠢的方式这样做。直到昨天我才知道“交叉产品”是什么意思,所以这对我来说是全新的,我可能会做一些相当愚蠢的事情。

【问题讨论】:

标签: c++ 3d unreal-engine4 frustum


【解决方案1】:

要调整您采用的方法,而不是完全改变它,您可以利用 2 对平面平行的事实。只为那对平面创建一个法线。您已经对位于其中一个平面“前面”的点进行了测试,但假设您知道平截头体的深度,您可以使用相同的距离来测试该点相对于另一个平行面。

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;
    }
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 2013-01-18
    • 2018-02-28
    • 1970-01-01
    • 2021-11-25
    • 2010-10-10
    • 1970-01-01
    相关资源
    最近更新 更多