【问题标题】:How to find the intersection of 2 convex hulls?如何找到2个凸包的交点?
【发布时间】:2022-01-23 20:45:09
【问题描述】:

我有两个凸包。假设它们被指定为scipy.spatial.ConvexHulls

import numpy as np


points1 = np.random.rand((10, 3))
points2 = np.random.rand((10, 3))
hull1 = ConvexHull(points1)
hull2 = ConvexHull(points2)

我想要作为这两个凸包交集的凸包,但找不到执行此操作的内置方法。

我认为这可以通过使用scipy.spatial.HalfspaceIntersection 以某种方式手动完成,通过使用hull1 定义的半空格来切断hull2,但仍然无法做到这一点,并且不敢相信这还没有在某处实现.


请注意,如果不使用 scipy,我不介意。

【问题讨论】:

  • 凸包是凸多面体。寻找与两个凸多面体相交或仅与两个多面体相交的实用程序。

标签: python 3d geometry computational-geometry convex-hull


【解决方案1】:

我会尝试pycddlib,它实现了多面体的双重描述。多面体的双重描述是:

  • V-description:顶点描述
  • H-description:线性不等式系统的描述

你可能有两个凸多面体的顶点。转换为H-描述,然后组合两个线性不等式系统,然后转换为V-表示。


这是一个例子。

import numpy as np
import pyvista as pv
import cdd as pcdd
from scipy.spatial import ConvexHull

# take one cube
cube1 = pv.Cube()
# take the same cube but translate it 
cube2 = pv.Cube() 
cube2.translate((0.5, 0.5, 0.5))

# plot 
pltr = pv.Plotter(window_size=[512,512])
pltr.add_mesh(cube1)
pltr.add_mesh(cube2)
pltr.show()

# I don't know why, but there are duplicates in the PyVista cubes;
# here are the vertices of each cube, without duplicates
pts1 = cube1.points[0:8, :]
pts2 = cube2.points[0:8, :]

# make the V-representation of the first cube; you have to prepend
# with a column of ones
v1 = np.column_stack((np.ones(8), pts1))
mat = pcdd.Matrix(v1, number_type='fraction') # use fractions if possible
mat.rep_type = pcdd.RepType.GENERATOR
poly1 = pcdd.Polyhedron(mat)

# make the V-representation of the second cube; you have to prepend
# with a column of ones
v2 = np.column_stack((np.ones(8), pts2))
mat = pcdd.Matrix(v2, number_type='fraction')
mat.rep_type = pcdd.RepType.GENERATOR
poly2 = pcdd.Polyhedron(mat)

# H-representation of the first cube
h1 = poly1.get_inequalities()

# H-representation of the second cube
h2 = poly2.get_inequalities()

# join the two sets of linear inequalities; this will give the intersection
hintersection = np.vstack((h1, h2))

# make the V-representation of the intersection
mat = pcdd.Matrix(hintersection, number_type='fraction')
mat.rep_type = pcdd.RepType.INEQUALITY
polyintersection = pcdd.Polyhedron(mat)

# get the vertices; they are given in a matrix prepended by a column of ones
vintersection = polyintersection.get_generators()

# get rid of the column of ones
ptsintersection = np.array([
    vintersection[i][1:4] for i in range(8)    
])

# these are the vertices of the intersection; it remains to take
# the convex hull
ConvexHull(ptsintersection)

【讨论】:

  • 感谢您的回答,一旦我将其实施到我的代码中,将投票并接受,希望很快。
猜你喜欢
  • 1970-01-01
  • 2021-10-23
  • 2016-11-04
  • 2017-07-04
  • 2021-08-22
  • 2015-05-24
  • 2015-08-19
  • 2014-06-03
  • 2015-08-09
相关资源
最近更新 更多