3D 中共面点的面积 - Python
Area of coplanar points in 3D - Python
我得到一组坐标(x,y,z)的3D共面点以及它们所属的平面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) 为我们提供了一些建议,以防您的数据是低维数据。如您所说,您已经知道您的数据是共面的,并且可以将其投影到平面中并由二维点表示。
如错误消息中所建议的,投影数据的替代方法是使用选项 QJ
来调整输入 (option doc)。如果我理解正确的话,这个“joggle”通过向你的数据引入随机噪声使你的数据“非共面”,从而允许优化继续进行。
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
用于 3D 点(您的原始点带有选项 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
。
我得到一组坐标(x,y,z)的3D共面点以及它们所属的平面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) 为我们提供了一些建议,以防您的数据是低维数据。如您所说,您已经知道您的数据是共面的,并且可以将其投影到平面中并由二维点表示。
如错误消息中所建议的,投影数据的替代方法是使用选项 QJ
来调整输入 (option doc)。如果我理解正确的话,这个“joggle”通过向你的数据引入随机噪声使你的数据“非共面”,从而允许优化继续进行。
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
用于 3D 点(您的原始点带有选项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
。