我正在寻找对我对确定一个点是否位于三角形内部的方法的认知的认可。
给定R(t)= e + td形式的光线以及三维三角形的三个点T = {V0,V1,V2}的集合,我知道如何找到该方程的参数方程这三个点形成的平面以及如何确定光线是否与该平面相交。最后,如果它相交,我想知道交点是否实际上在三角形边的范围内。
请参阅下面的图片。
我在想的是我可以计算每个边缘矢量和从边缘矢量中的第一个边缘到该点的矢量之间的点积,并检查它们是否都是正的。像这样:
如果是这种情况,该点应位于三角形内。对?这种方法不是用于确定计算机图形背面的方法吗?
答案 0 :(得分:1)
在图形中,人们通常使用重心坐标。在您的情况下,P可以描述为P = aV0 + bV1 + cV2,其中a + b + c = 1。当且仅当0 <= a,b,c <= 1时,P在内部。如果由v1,P,v2形成的三角形具有区域S1,则由P形成的三角形,v0,v2具有S2的面积,并且P,V0,V1具有S3的面积。然后a = S1 / S,b = S2 / S并且c = S3 / S,其中S是三角形V0,V1,V2的区域。找到S = 1/2 ||(V0-V1)creosspdoruct(V0-V2)||的面积。你可以在这里查看我放在我网站上的教程: http://pages.cpsc.ucalgary.ca/~amahdavi/pmwiki-2.2.8/uploads/Site/RayTracing3.ppt
答案 1 :(得分:1)
我参加聚会有点晚了(抱歉),但这是我的看法:
我曾经在80年代进行射线追踪。当时我想出了一个与您所讨论的解决方案非常相似的解决方案。
这个想法是,一个点始终位于观察者的右侧,该观察者顺时针方向走三角形的边缘,然后该点位于三角形内部。
为此,我们需要进行测试以查看该点是否在每个边缘的右侧。交叉乘积会很好,但正如前面指出的那样,Cros乘积将为您带来cos价值。您想要的是一种罪过,因此您可以拒绝测试结果为阴性的分数。这就是为什么人们倾向于使用叉积的原因。但是叉积比点积(在80年代确实很重要!)需要更多的计算。
但是我们可以通过简单的90度旋转将cos转换为正弦!因此,我们不使用边缘计算点积,而是使用在多边形平面中相对于边缘旋转90度的直线来计算点积。
起初,这看起来很麻烦,但如果我们在其中一架主飞机上工作,就不会那么麻烦。 XY,YZ或XZ。因此,与其在三角形平面中进行3D处理,不如在一个主平面中进行2D处理。如果点在3D中处于多边形内部,则它也将在2D平面上的投影内部。当然,如果多边形平行于一个主平面,则在错误的平面上投影可能会出现问题。
因此,要选择此平面,只需查看三角形的法线并选择更接近三角形平面的平面。如果X分量最大,则使用YZ平面等。此外,该分量的符号会告诉我们投影的多边形是顺时针还是逆时针。
在这些2D平面之一中,边沿旋转90度只是在其中之一上交换符号更改值。
例如,在XY平面中,V0和V1之间的边为:
V0V1x = v1x-v0x
V0V1y = V1y-v0y
V0和P之间的向量为:
V0Px = Px-V0x
V0Py = Py-V0y
A -90度给定边的旋转给定x'= y和y'= -x;所以我们为第一条边计算的标量积将为
标量=(Px-V0x)*(V1y-V0y)+(Py-V0y)*(V0x-V1x)
如果该值<0,则该点不在内部。
使用其他2条边线进行此操作,然后进行“内部”测试。
在我的解决方案中,作为预处理,我计算了一个值,该值为我提供了每个三角形的最大法线方向和正负号。之后,我使用该值知道要在哪个平面上计算交点。 (负法向分量使我切换三角形的“顺时针”方向。)
知道该点是否在多边形内的测试
1个具有最大正常值的“方向”测试(带有XY,XZ或YZ 6个案例的开关,正或负)
3个“边缘”测试,每个测试有4个减法,2个乘法和1个测试。
如果点在多边形内,则只能进行“边缘”测试3次。如果没有,它可能会在第一个或第二个边缘之后被拒绝...
因此,知道一个点是否在三角形内将需要进行8到22次运算。
我现在看到的大多数解决方案似乎都在使用更多的操作!
答案 2 :(得分:0)
你想解决
E + t.D = a.V0 + b.V1 + c.V2
,其中
t, a, b, c >= 0, a + b + c = 1
使用c = 1 - a - b
,您将获得一个3x3线性系统(分解为x
,y
,z
)
a.(V0 - V2) + b.(V1 - V2) - t.D = E - V2
您可以解决t
,a
,b
,然后c
并检查肯定性。
答案 3 :(得分:0)
您可以使用点积来确定点是否在三角形中。首先找到测试点到每个边缘的投影。点积的符号仅在直角处有意义,投影将为您提供直角。
对于每个边缘的三角形a
,b
,c
和点p
计算m
和s
。 m
是p
投射到边缘ab
上的点。{/ p>
m = (p - a) • (b - a) / |b - a|² * (b - a) + a
s = (p - m) • (c - m)
如果s
为肯定,则p
和c
位于ab
的同一侧。对每条边重复此测试。如果p
和相对的顶点位于每条边的同一侧,则p
位于三角形中。
这种平面分裂技术通常用交叉产品完成,但这种方式可能更有效。
对于|b - a|²
,如果长度平方不可用,则可以使用(b - a) • (b - a)
。