3D Python中共面点的面积

2024-06-10 12:18:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我得到了一组坐标(x,y,z)的三维共面点,以及它们所属平面p的方程。我想知道如何使用Python获取窗格上这些点所占用的区域。我尝试过3d中的Convhull,但我得到了一个错误,因为我所有的点都是共面的。你知道吗

谢谢


Tags: 区域错误平面方程窗格convhull面点
0条回答
网友
1楼 · 发布于 2024-06-10 12:18:35

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

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)为我们提供了一些建议,以防您的数据是低维的。正如您所说,您已经知道数据是共面的,它可以投影到平面中,并由二维点表示

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

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

总之:

  • 找到平面和单位xy平面之间的角度,如果需要精确答案,请旋转数据
  • 如果你想要一个快速的解决方案,并且高精度不是问题,那么使用选项"QJ"(我实际上不知道答案离事实有多远)

更新

Qhull FAQ

The area is the area of the surface of the convex hull, while the volume is the total volume of the convex hull.

In 2-d, the convex hull is a polygon. Its surface is the edges of a polygon. So in 2-d, the 'area' is the length of the polygon's edges, while the 'volume' is the area of the polygon.

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

  • hull.area / 2用于三维点(使用选项QJ的原始点)
  • hull.volume用于二维点(如果旋转点并去除一维)

为了帮助澄清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

相关问题 更多 >