我试着用3D绘制一个由一组不等式定义的多面体。实际上,我试图在matplotlib中重现这个matlab plotregion库的功能。在
我的方法是得到相交点,构造它们的凸包,然后得到并绘制出结果面(simplice)。在
问题是许多简单化是共面的,它们无缘无故地使绘图变得非常繁忙(请参见下面的图中的所有对角线边)。在
有没有什么简单的方法可以只打印多面体的“外部”边缘,而不需要我自己一个一个地整合所有共面的简单体?在
谢谢你
from scipy.spatial import HalfspaceIntersection
from scipy.spatial import ConvexHull
import scipy as sp
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d as a3
import matplotlib.colors as colors
w = np.array([1., 1., 1.])
# ∑ᵢ hᵢ wᵢ qᵢ - ∑ᵢ gᵢ wᵢ <= 0
# qᵢ - ubᵢ <= 0
# -qᵢ + lbᵢ <= 0
halfspaces = np.array([
[1.*w[0], 1.*w[1], 1.*w[2], -10 ],
[ 1., 0., 0., -4],
[ 0., 1., 0., -4],
[ 0., 0., 1., -4],
[-1., 0., 0., 0],
[ 0., -1., 0., 0],
[ 0., 0., -1., 0]
])
feasible_point = np.array([0.1, 0.1, 0.1])
hs = HalfspaceIntersection(halfspaces, feasible_point)
verts = hs.intersections
hull = ConvexHull(verts)
faces = hull.simplices
ax = a3.Axes3D(plt.figure())
ax.dist=10
ax.azim=30
ax.elev=10
ax.set_xlim([0,5])
ax.set_ylim([0,5])
ax.set_zlim([0,5])
for s in faces:
sq = [
[verts[s[0], 0], verts[s[0], 1], verts[s[0], 2]],
[verts[s[1], 0], verts[s[1], 1], verts[s[1], 2]],
[verts[s[2], 0], verts[s[2], 1], verts[s[2], 2]]
]
f = a3.art3d.Poly3DCollection([sq])
f.set_color(colors.rgb2hex(sp.rand(3)))
f.set_edgecolor('k')
f.set_alpha(0.1)
ax.add_collection3d(f)
plt.show()
很确定matplotlib中没有本机代码。不过,找到属于一起的脸并不是特别困难。下面实现的基本思想是创建一个图,其中每个节点都是一个三角形。然后连接共面且相邻的三角形。最后,找到图的连接组件,以确定哪些三角形构成面。在
{a1}
应用于您的示例:
^{pr2}$注意
经过深思熟虑,函数
reordered
可能需要更多的工作。非常肯定这会打破奇怪/非凸形状,我甚至不能百分之百肯定它会永远适用于凸形状。不过,休息应该没问题。在以下是我的解决方案。它类似于@Paul的解决方案,它获取三角形,按它们所属的面分组,然后将它们连接到一个面上。在
区别主要在于此解决方案不使用}。许多必要的操作是通过重新编制索引、广泛使用
nx
或{unique
和一些线性代数来执行的。最终面顶点的顺序由
ConvexHull
决定。我认为这不应该是一个限制,因为(我认为)任何半空间的交集只能产生凸形。但是,我还添加了另一种方法,如果形状不是凸的(基于this question的思想)。在相关问题 更多 >
编程相关推荐