3D中共面点的面积-Python

问题描述 投票:0回答:1

我在坐标(x,y,z)的3D中获得了一组共平面点,以及它们所属的平面P的方程。我想知道如何使用Python获取窗格上这些点所占据的区域。我已经在3d中尝试过Convhull,但由于我的所有点确实是共面的,因此出现错误。你有什么主意吗?

谢谢!

python scipy geometry plane
1个回答
0
投票

首先,我试图通过创建一些随机的共面点并尝试拟合凸包来重现您的问题:

import numpy as np
from scipy.spatial import ConvexHull

# 4 random 3D points
points = np.random.rand(4, 3)
# A set of coplanar points where their third dimension is 1.
coplanar = np.array([np.array([x[0], x[1], 1.0]) for x in points])

hull = ConvexHull(coplanar)

这确实会产生错误:

Traceback (most recent call last):
  File "main.py", line 9, in <module>
    hull = ConvexHull(coplanar)
  File "qhull.pyx", line 2428, in scipy.spatial.qhull.ConvexHull.__init__
  File "qhull.pyx", line 357, in scipy.spatial.qhull._Qhull.__init__
scipy.spatial.qhull.QhullError: QH6154 Qhull precision error: Initial simplex is flat (facet 1 is cop
lanar with the interior point)

..... OMITTING SOME LINES ....

If the input is lower dimensional:
  - use 'QJ' to joggle the input and make it full dimensional
  - use 'Qbk:0Bk:0' to delete coordinate k from the input.  You should
    pick the coordinate with the least range.  The hull will have the
    correct topology.
  - determine the flat containing the points, rotate the points
    into a coordinate plane, and delete the other coordinates.
  - add one or more points to make the input full dimensional.

我们可以看到,底层库(qhull)为我们提供了一些建议,以防您的数据是低维的。如您所说,您已经知道您的数据是共面的,可以将其投影到平面中并由2D点表示。

根据错误消息的建议,投影数据的另一种方法是使用选项QJ来微动输入(option doc)。如果我正确理解的话,这种“微动”会在数据中引入随机噪声,从而使数据“非共面”,从而使优化得以进行。

hull = ConvexHull(coplanar, qhull_options="QJ")
hull.area
> 0.3100618849870332

摘要:

  • 确定平面与单位xy平面之间的角度,如果需要精确的答案,请旋转数据
  • 如果需要快速解决方案且精度高不是问题(请使用选项"QJ"(实际上我不知道答案与事实有多远)]

更新

来自Qhull FAQ

[面积是凸包表面的面积,而体积是凸包的总体积。

在二维图中,凸包是多边形。它的表面是多边形的边缘。因此,在二维中,“面积”是多边形边缘的长度,而“体积”是多边形的面积。

根据这些陈述,我认为您应该使用:

  • hull.area / 2用于3D点(您的原始点带有选项QJ
  • hull.volume用于2D点(如果旋转点并摆脱一维)

[为了帮助阐明ConvexHull的用法,我使用了一个简单的示例

square2D = np.array([
    [0.0, 0.0],
    [2.0, 0.0],
    [2.0, 2.0],
    [0.0, 2.0]
])
hull = ConvexHull(square2D)
hull.area
> 8.0
hull.volume
> 4.0

结果与文档一致。

现在,要了解选项QJ的效果,我在前面的几点上增加了一个维度:

coplanar = np.array([
    [0.0, 0.0, 0.0],
    [2.0, 0.0, 0.0],
    [2.0, 2.0, 0.0],
    [0.0, 2.0, 0.0]
])
hull = ConvexHull(coplanar, qhull_options="QJ")
hull.area
> 8.000000000306578
hull.volume
> 5.719619827513867e-11

对于最后一个示例,我将凸包想象为具有两个大平面的近似“平坦”的3D对象(由于引入的噪声)。这就是为什么我认为您可以在这种情况下使用hull.area / 2的原因。

© www.soinside.com 2019 - 2024. All rights reserved.