检查平面点的哪一侧
Posted
技术标签:
【中文标题】检查平面点的哪一侧【英文标题】:Check which side of a plane points are on 【发布时间】:2013-03-19 06:26:31 【问题描述】:我正在尝试获取一组 3D 点和一个平面,然后根据它们所在的平面的哪一侧将这些点分成 2 个数组。在我开始深入调试之前,我想发布我计划做的事情,以确保我对如何做到这一点的理解能够奏效。
基本上我有 3 个点的飞机,我使用(伪代码):
var v1 = new vector(plane.b.x-plane.a.x, plane.b.y-plane.a.y, plane.b.z-plane.a.z);
var v2 = new vector(plane.c.x-plane.a.x, plane.c.y-plane.a.y, plane.c.z-plane.a.z);
我取这两个向量的叉积得到法线向量。
然后我遍历我的点数组并将它们转换为向量并计算与法线的点积。
然后我使用点积来确定点所在的一侧。
这听起来可行吗?
【问题讨论】:
听起来确实可行。但是,我还要指出,您可以通过将点plane.a
乘以法线向量来将“向量化”从内部循环中取出,以获得恒定的偏移量。这消除了2个减法,和@Ali的解决方案基本相同:他的d
是- dot(plane_normal, plane.a)
我需要在高焦时重新学习这一点,而且谷歌的***结果很难看到精神,所以我想添加一个简化的答案:(a,b,c)是飞机的正常, (x, y, z) 是重点,没有“d”,它是假的,不会伤害你,移动两者,使平面停在 (0, 0, 0),无需标准化任何东西......它是基本上是abovePlane = a*x + b*y + c*z > 0.0;
【参考方案1】:
按照前面给出的“将点放入平面方程并检查符号”的方法。使用SymPy 可以轻松获得方程。我用它在点列表中查找点的位置(保存为 numpy 数组)。
from sympy import Point3D, Plane
plane=Plane(Point3D(point1), Point3D(point2), Point3D(point3))
for point in pointList:
if plane.equation(x=point[0], y=point[1],z=point[2]) > 0:
print "point is on side A"
else:
print "point is on side B"
与上面提到的其他方法相比,我没有测试过它的速度,但绝对是最简单的方法。
【讨论】:
【参考方案2】:让a*x+b*y+c*z+d=0
成为确定您的飞机的方程式。
将点的[x,y,z]
坐标代入等式的左侧(我的意思是a*x+b*y+c*z+d
)并查看结果的符号。
具有相同符号的点在平面的同一侧。
老实说,我没有检查您所写内容的细节。我想你同意我的建议更简单。
【讨论】:
把它放在dot( (a,b,c,d), (x,y,z,1) ) > 0
的形式中,正点积在平面前面,负点积在后面可能有用/更快。
@LucasW 它是点形式:如果你扩展dot( (a,b,c,d), (x,y,z,1) )
,你会得到a*x+b*y+c*z+d
。 :)
你能用线性代数的语言解释一下这个方法吗?点积是正数还是负数是什么意思?
@dagang 平面将空间分成两个半空间。平面的法线向量指向这些半空间之一,我们称之为半空间H
。如果点在H
中,则点积为正,否则为负。如果它正好在飞机上,则为零。
@Saladsamurai 有很好的案例,是的,但请记住,高阶事物要复杂得多。例如,您将如何定义具有 两张纸 的 hyperboloid 的“同一侧”?高阶事物会使事情变得复杂,因此需要格外小心。对不起,我不能比这更具体。 :-(【参考方案3】:
你的方法听起来不错。但是,当您说“并将它们转换为向量”时,它可能并不好(取决于您的句子的含义)。
您应该通过计算当前点与平面中的一个点之间的坐标差来“将您的点转换为矢量”(例如,定义飞机)。在你写的时候,听起来你可能误解了;但除此之外,没关系!
【讨论】:
以上是关于检查平面点的哪一侧的主要内容,如果未能解决你的问题,请参考以下文章
ZZNUOJ_用C语言编写程序实现1183:平面点排序(结构体专题)(附完整源码)