确定点是否在 3D 三角形内
Determine if point is inside triangle in 3D
我正在寻找关于确定点是否位于 3D 三角形内的方法的认识。
给定形式为 R(t) = e + td 的射线和一组构成三维三角形的三点 T = {V0, V1, V2},我知道如何找到参数方程对于三个点形成的平面以及如何确定射线是否与该平面相交。最后,如果它相交,我想知道交点是否真的在三角形边缘的边界内。
请看下面我的图片。
我在想的是,我可以计算每个边向量与从边向量中的第一条边到该点的向量之间的点积,并检查它们是否都是正数。像这样:
如果是这样,该点应该在三角形内部。正确的?这不就是计算机图形学判断背面的方法吗?
在图形中,人们通常使用重心坐标。在您的情况下,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)||
的面积。
你可以看看我放在我网站上的tutorial。
你要解决
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
并检查正性。
您可以使用点积来确定一个点是否在三角形中。首先找到测试点在每条边上的投影。点积的符号只有在直角的时候才有意义,投影会给你一个直角。
对于三角形 a
、b
、c
和点 p
计算每条边的 m
和 s
。 m
是 p
投影到边 ab
上的点。
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)
。
我来晚了一点(抱歉),但这是我的看法:
我曾经在 80 年代做过 ray-tracing。当时我想出了一个与你所讨论的非常相似的解决方案。
这个想法是,一个点总是在观察者顺时针走三角形边缘的右侧,那么这个点就在三角形内部。
为此,我们需要进行测试以查看该点是否位于每条边的右侧。交叉产品会很好,但正如所指出的那样,交叉产品会给你一个 cos 值。你想要的是一种罪恶,所以你可以拒绝那些有负面测试的点。这就是人们倾向于使用叉积的原因。但是叉积比点积需要更多的计算(在 80 年代这非常重要!)
但是我们可以通过简单的90度旋转将cos转换成sin!因此,我们不是用边计算点积,而是用从多边形平面中的边旋转 90 度的线来计算它。
起初这似乎很麻烦,但如果我们在其中一个主位面工作就不会了。 XY、YZ 或 XZ。因此,与其在三角形平面中进行 3D 工作,不如在其中一个主平面中进行 2D 工作。如果一个点在 3D 中位于多边形内,它也将位于其在 2D 平面上的投影内。当然,如果多边形平行于其中一个主平面,如果我们在错误的平面上投影,我们可能会遇到问题。
所以,select这个平面,只看三角形的法线和select离三角形平面较近的平面。如果 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 个边执行此操作,你就完成了 "inside" 测试。
在我作为 pre-processing 的解决方案中,我计算了一个值,给出了每个三角形的最大法线方向和符号。之后,我使用该值来了解我想在哪个平面上计算交点。 (负法线分量让我切换三角形的 "clockwise" 方向)。
判断点是否在多边形内的测试采用:
1"direction"用最大正常值测试(一个switch有6个case,XY,XZ或YZ,positive或negative)
3 "edge" 测试,每个测试有 4 个减法和 2 个乘法,还有 1 个测试。
如果点在多边形内,您只需执行 "edge" 测试 3 次。如果不是,它可能会在第一个或第二个边缘之后被拒绝...
所以,要知道一个点是否在三角形内需要 8 到 22 次操作。
我现在看到的大多数解决方案似乎都使用了比这更多的操作!
我正在寻找关于确定点是否位于 3D 三角形内的方法的认识。
给定形式为 R(t) = e + td 的射线和一组构成三维三角形的三点 T = {V0, V1, V2},我知道如何找到参数方程对于三个点形成的平面以及如何确定射线是否与该平面相交。最后,如果它相交,我想知道交点是否真的在三角形边缘的边界内。
请看下面我的图片。
我在想的是,我可以计算每个边向量与从边向量中的第一条边到该点的向量之间的点积,并检查它们是否都是正数。像这样:
如果是这样,该点应该在三角形内部。正确的?这不就是计算机图形学判断背面的方法吗?
在图形中,人们通常使用重心坐标。在您的情况下,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)||
的面积。
你可以看看我放在我网站上的tutorial。
你要解决
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
并检查正性。
您可以使用点积来确定一个点是否在三角形中。首先找到测试点在每条边上的投影。点积的符号只有在直角的时候才有意义,投影会给你一个直角。
对于三角形 a
、b
、c
和点 p
计算每条边的 m
和 s
。 m
是 p
投影到边 ab
上的点。
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)
。
我来晚了一点(抱歉),但这是我的看法:
我曾经在 80 年代做过 ray-tracing。当时我想出了一个与你所讨论的非常相似的解决方案。
这个想法是,一个点总是在观察者顺时针走三角形边缘的右侧,那么这个点就在三角形内部。
为此,我们需要进行测试以查看该点是否位于每条边的右侧。交叉产品会很好,但正如所指出的那样,交叉产品会给你一个 cos 值。你想要的是一种罪恶,所以你可以拒绝那些有负面测试的点。这就是人们倾向于使用叉积的原因。但是叉积比点积需要更多的计算(在 80 年代这非常重要!)
但是我们可以通过简单的90度旋转将cos转换成sin!因此,我们不是用边计算点积,而是用从多边形平面中的边旋转 90 度的线来计算它。
起初这似乎很麻烦,但如果我们在其中一个主位面工作就不会了。 XY、YZ 或 XZ。因此,与其在三角形平面中进行 3D 工作,不如在其中一个主平面中进行 2D 工作。如果一个点在 3D 中位于多边形内,它也将位于其在 2D 平面上的投影内。当然,如果多边形平行于其中一个主平面,如果我们在错误的平面上投影,我们可能会遇到问题。
所以,select这个平面,只看三角形的法线和select离三角形平面较近的平面。如果 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 个边执行此操作,你就完成了 "inside" 测试。
在我作为 pre-processing 的解决方案中,我计算了一个值,给出了每个三角形的最大法线方向和符号。之后,我使用该值来了解我想在哪个平面上计算交点。 (负法线分量让我切换三角形的 "clockwise" 方向)。
判断点是否在多边形内的测试采用:
1"direction"用最大正常值测试(一个switch有6个case,XY,XZ或YZ,positive或negative)
3 "edge" 测试,每个测试有 4 个减法和 2 个乘法,还有 1 个测试。
如果点在多边形内,您只需执行 "edge" 测试 3 次。如果不是,它可能会在第一个或第二个边缘之后被拒绝...
所以,要知道一个点是否在三角形内需要 8 到 22 次操作。
我现在看到的大多数解决方案似乎都使用了比这更多的操作!