检查平面点的哪一侧

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:平面点排序(结构体专题)(附完整源码)

ZZNUOJ_用C语言编写程序实现1184:平面点排序(结构体专题)(附完整源码)

感知器算法

支持向量机介绍