三维Python中共面点的面积



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

谢谢!

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

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来慢跑输入(选项doc(。如果我理解正确的话;慢跑;使您的数据";非共面";通过在数据中引入随机噪声,允许进行优化。

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

总结:

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

更新

来自Qhull常见问题解答:

面积是凸包曲面的面积,而体积是凸包的总体积。

在二维中,凸包是一个多边形。它的表面是多边形的边。因此,在二维中,"面积"是多边形边的长度,而"体积"是多边形的面积。

根据这些语句,我认为您应该使用:

  • 3D点的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

最新更新