检查 3D 点是否在基于正方形的金字塔中
Check if a 3D point is in a square based pyramid or not
如果我有一个基于正方形的金字塔,我知道其中的每个点(全部 5 个),确定给定点是否在该金字塔内的算法是什么?我在这里看到了类似的问题 Algorithm for checking if 3D point inside convex polyhedron (square pyramid) and here How to check whether the point is in the tetrahedron or not?。那里给出的答案并没有真正帮助,数学也不适合我。我见过为每个平面(4 个三角形 + 1 个正方形)创建法线并检查该点位于平面的哪一侧的方法......但是我不知道正确的数学方法。
如果有人可以帮助我 math/algorithm(最好有解释),那真的很有帮助。
visualization
示例输入:
# Pyarmid Points
A = np.array([2, 2, 4]) # pyramid top
B = np.array([1, 1, 1])
C = np.array([1, 3, 3])
D = np.array([3, 3, 1])
E = np.array([3, 1, 1])
# Example points
point_inside = np.array([2, 2, 2])
point_outside = np.array([3, 3, 3])
示例期望:
def check_point_in_pyramid(A, B, C, D, E, Point):
# math...
if point_inside_pyramid:
return true
return false
所以对于 point_inside 函数 return 为真,对于 point_outside 为假。
是的,你可以使用法线解决这个问题。
为了获得正常,计算每个平面的两条边的叉积。小心法线方向 - 严格按顺序使用顶点以获得所有外部法线或所有内部法线。
然后检查所有平面法向量对的点积符号(平面中的顶点 - 要检查的点)。
在内部点的情况下,所有点积将具有相同的符号(或者当点属于平面时为零)。
外部点示例 - 注意不同的符号:
nabc = np.cross(B - A, C - A)
nacd = np.cross(C - A, D - A)
nade = np.cross(D - A, E - A)
naeb = np.cross(E - A, B - A)
nbcd = np.cross(D - B, C - B)
r = np.dot(point_outside - A, nabc)
print(r)
r = np.dot(point_outside - A, nacd)
print(r)
r = np.dot(point_outside - A, nade)
print(r)
r = np.dot(point_outside - A, naeb)
print(r)
r = np.dot(point_outside - B, nbcd)
print(r)
8
-4
-4
8
8
我这里是右为正左为负:
根据您的金字塔,它由 5 个面定义,因此也可以由 5 个平面定义。平面只是一个平面(没有体积;只有面积)表面。
,由方程 ax + by + cz + d = 0
定义。但是,要回答您的问题,我们只需要平面的法线,它由上面等式的三个系数给出 N = (a, b, c)
.
假设我们使用了您图像中的平面 ACD
。我们还可以通过这样的叉积找到平面的法线:(D - A) x (C - A)
,这给了我们法线,N
.
现在我们还需要一个方向向量,即从我们正在测试的3D点指向平面上的任何一点。为了简化,我们可以只使用其中一个点:A
、C
或 D
(让我们使用 A
),因为它们仍然被认为是平面的一部分。
像这样:directionVector = point_outside - A
现在我们有这样的方法:
现在,如果我们对方向向量和法线进行点积 (float value = directionVector . N
),我们只会得到一个数值。
然而数值的符号告诉我们该点是在内部还是外部(3D 点在平面的哪一侧)。
所以如果 value > 0
,点在金字塔内部(在平面的右侧)并且如果 value < 0
,该点在金字塔外部(在平面的左侧)。
现在,如果对金字塔的所有其他 4 个平面重复此过程。如果全部 return一个正值,那么该点确实金字塔内部.但是,如果其中 一个 return 是 负 值,则该点位于金字塔外 .
注意 1:确保平面的法线朝向金字塔外面而不是里面。
注意2:如果你把正负两边颠倒了(如果现在左为正右为负),一定要把不等式也颠倒过来
如果我有一个基于正方形的金字塔,我知道其中的每个点(全部 5 个),确定给定点是否在该金字塔内的算法是什么?我在这里看到了类似的问题 Algorithm for checking if 3D point inside convex polyhedron (square pyramid) and here How to check whether the point is in the tetrahedron or not?。那里给出的答案并没有真正帮助,数学也不适合我。我见过为每个平面(4 个三角形 + 1 个正方形)创建法线并检查该点位于平面的哪一侧的方法......但是我不知道正确的数学方法。
如果有人可以帮助我 math/algorithm(最好有解释),那真的很有帮助。
visualization
示例输入:
# Pyarmid Points
A = np.array([2, 2, 4]) # pyramid top
B = np.array([1, 1, 1])
C = np.array([1, 3, 3])
D = np.array([3, 3, 1])
E = np.array([3, 1, 1])
# Example points
point_inside = np.array([2, 2, 2])
point_outside = np.array([3, 3, 3])
示例期望:
def check_point_in_pyramid(A, B, C, D, E, Point):
# math...
if point_inside_pyramid:
return true
return false
所以对于 point_inside 函数 return 为真,对于 point_outside 为假。
是的,你可以使用法线解决这个问题。
为了获得正常,计算每个平面的两条边的叉积。小心法线方向 - 严格按顺序使用顶点以获得所有外部法线或所有内部法线。
然后检查所有平面法向量对的点积符号(平面中的顶点 - 要检查的点)。
在内部点的情况下,所有点积将具有相同的符号(或者当点属于平面时为零)。
外部点示例 - 注意不同的符号:
nabc = np.cross(B - A, C - A)
nacd = np.cross(C - A, D - A)
nade = np.cross(D - A, E - A)
naeb = np.cross(E - A, B - A)
nbcd = np.cross(D - B, C - B)
r = np.dot(point_outside - A, nabc)
print(r)
r = np.dot(point_outside - A, nacd)
print(r)
r = np.dot(point_outside - A, nade)
print(r)
r = np.dot(point_outside - A, naeb)
print(r)
r = np.dot(point_outside - B, nbcd)
print(r)
8
-4
-4
8
8
我这里是右为正左为负:
根据您的金字塔,它由 5 个面定义,因此也可以由 5 个平面定义。平面只是一个平面(没有体积;只有面积)表面。
,由方程 ax + by + cz + d = 0
定义。但是,要回答您的问题,我们只需要平面的法线,它由上面等式的三个系数给出 N = (a, b, c)
.
假设我们使用了您图像中的平面 ACD
。我们还可以通过这样的叉积找到平面的法线:(D - A) x (C - A)
,这给了我们法线,N
.
现在我们还需要一个方向向量,即从我们正在测试的3D点指向平面上的任何一点。为了简化,我们可以只使用其中一个点:A
、C
或 D
(让我们使用 A
),因为它们仍然被认为是平面的一部分。
像这样:directionVector = point_outside - A
现在我们有这样的方法:
现在,如果我们对方向向量和法线进行点积 (float value = directionVector . N
),我们只会得到一个数值。
然而数值的符号告诉我们该点是在内部还是外部(3D 点在平面的哪一侧)。
所以如果 value > 0
,点在金字塔内部(在平面的右侧)并且如果 value < 0
,该点在金字塔外部(在平面的左侧)。
现在,如果对金字塔的所有其他 4 个平面重复此过程。如果全部 return一个正值,那么该点确实金字塔内部.但是,如果其中 一个 return 是 负 值,则该点位于金字塔外 .
注意 1:确保平面的法线朝向金字塔外面而不是里面。
注意2:如果你把正负两边颠倒了(如果现在左为正右为负),一定要把不等式也颠倒过来