获取由 3d 多边形包围的点

Posted

技术标签:

【中文标题】获取由 3d 多边形包围的点【英文标题】:Get points enclosed by a 3d polygon 【发布时间】:2011-03-01 11:22:56 【问题描述】:

我有一个位于 3D 平面上的多边形。我想得到这个多边形包围的所有点。有人能帮我吗? 我可以通过用平面替换扫描线并获得平面与我的多边形的交点来制作 3D 扫描线算法,但我想要一个更快的解决方案。 提前致谢。

【问题讨论】:

是否有任何额外的假设可用?例如,您的网格是否是凸的(这会使问题大大更容易) 哇,哇!也许我(和许多其他回应的人)误解了你。你在 3D 空间的某个地方有一个 2D 多边形吗?但如果是这样,那么问题可以在该平面的 2D-local-coordinate 空间中解决。 是的,它是一个凸的 3p 多边形,但它的所有点都在同一个平面上 【参考方案1】:

我现在可以看到的一种方法是从您要验证的每个点发射 随机 任意射线,并计算它与 3d 网格表面相交的次数。如果它是奇数 - 它在里面,如果是偶数 - 在外面。

【讨论】:

感谢 Cygnus 的帮助,但这是 poylgon 测试中的重点。问题是我想获得这个多边形中的所有点,所以我不能限制生成的随机点的数量,我应该测试 您可以测试的点数没有限制。您只需为您测试的每个点发射任意光线。【参考方案2】:

如果你的多边形是凸的,那么你可以使用以下方法:

多边形的每个面都是由公式ax + by + cz = d 给出的平面的一部分。找到所有面的这个方程,根据多边形内部描述点的关系将它们修改为< d> d,然后求解这个线性不等式系统。这应该为您提供一组 x、y 和 z 关系,只有多边形内的点才满足。

【讨论】:

这仅适用于假设 3d 网格是凸的!【参考方案3】:

CygnusX1 的答案是标准的多边形点测试,并且可以针对各种不同的系统进行修改(例如,我有一个编码用于处理球体的版本)。调整它的主要技巧是决定光线方向。 “随意”是一个比“随机”更好的词。对于 2d 欧几里得工作,我会在平行于其中一个轴(并垂直于另一个轴)的方向上拍摄它。对于球体,您使用其中一个极点。对于 3d 中的 2d 平面多边形,我很想选择一条垂直于其中一个轴的线。

或者我会转换我的坐标,以便所有计算都在平面内。这将大大简化实际的多边形内点测试。我认为这也会更快(对于大型多边形和许多测试来说尤其如此):每个多边形角只需要转换一次,但每个多边形中的点测试将在两个测试中使用它。

【讨论】:

同意,“任意”是一个更好的词。更新。谢谢!【参考方案4】:

“是的,它是一个凸的 3p 多边形,但它的所有点都在同一个平面上”

在这种情况下 - 只需将多边形和所有测试点转换为平面的 2D 局部坐标并使用 2D 算法:

2D 射线拍摄:您仍然可以使用与我的 3D 建议类似的算法 - 从您的测试点拍摄 2D 射线并计算您击中多边形边界的次数。

线性不等式:如果您的多边形是凸的,您可以按照 suszterpatt 的方法,将您的多边形定义为半平面的交集ax+by<d

进一步阅读:

http://en.wikipedia.org/wiki/Point_in_polygon http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html http://paulbourke.net/geometry/insidepoly/

【讨论】:

【参考方案5】:

将多边形投影到 (x,y) 平面上。现在它是一个二维问题。 2-D 投影内的每个点 (x,y) 表示 3-D 多边形内的一个点 (x,y,z)。 注意:如果您的平面垂直于 (x,y) 平面,这将不起作用;如果它几乎是垂直的,您将失去精度。所以在实践中,您将投影到与您的 3-D 平面垂直度最小的坐标平面上。

【讨论】:

通常你根据平面法线的最长分量将平面投影到 X、Y、Z 上,即如果你的法线向量 n =(1,2,3) 那么你应该投影它在XY平面上【参考方案6】:

我已经看到使用 matplotlib/scipy/numpy 之一实现了类似的东西。不过我记不太清算法了,看看this 是否有帮助。

【讨论】:

以上是关于获取由 3d 多边形包围的点的主要内容,如果未能解决你的问题,请参考以下文章

ZBrush常用3D术语

QT+PCL 点云学习

QT+PCL 点云学习

顶点定义框算法中的点?

给定表面法线,找到 3D 平面的旋转

如何在python中获取多边形内的点列表?