我试图找出确定一个点是否在平截头体内的最佳方法。我有一些工作,但不确定它是否太麻烦,也许我应该采取更优雅/有效的方式。
假设我想知道点' x'在一个frustrum里面:
一旦我得到了截头体的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对所有平面都是正的,那么它就在平截头体内。
所以这似乎有效,但我只是想知道我是否以愚蠢的方式做这件事。我甚至都不知道什么是交叉产品&#39;意味着直到昨天,所以这对我来说都是新鲜的,我可能会做一些相当愚蠢的事情。
答案 0 :(得分: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;
}
}
如果你有多个点可以测试相同的平截头体,你可以受益,因为你只计算一次平截头体深度(每对平行平面)。