Рассчитать объем трехмерного многогранника с помощью Python?

Я пытаюсь найти лучший способ вычисления объема трехмерного многогранника с помощью Python, и я надеюсь, что есть простое решение, которое я не могу найти.

Пример многогранникаПример многогранника

Я нашел этот пост, в котором описано вычисление площади плоского многоугольника в трехмерном пространстве, но это, похоже, не помогает.

2 ответа

Решение

Если у вас есть только выпуклые многогранники, вы можете использовать привязку QHull scipy.spatial.ConvexHull.

    import numpy as np
    from scipy.spatial import Convexhull

    points = np.array([[....]])  # your points
    volume = Convexhull(points).volume

Кроме того, модуль Делоне может триангулировать ваши пройденные точки в тетраэдры для других вещей.

Ваш полигон таков, что вы можете найти точку внутри, чтобы вы могли соединить каждую вершину с точкой, не пересекая грани? Если это так, вы можете разделить каждое лицо на треугольники. Вы можете сделать это легко, позволив одной вершине грани быть точкой поворота и рисуя линии от других вершин до вершины поворота. Например, пятиугольник делится на три треугольника, которые разветвляются из общей вершины. Каждый треугольник сформирует тетраэдр (3-стороннюю пирамиду) с точкой внутри. Затем вы можете сложить объемы всех тетраэдров для каждого лица. Нижеследующее относится к выпуклому многограннику, окружающему начало координат (x=0,y=0,z=0). Предполагается, что существует список граней f, и у каждой грани есть список вершин v.

def volume(self):
  ''' calculate volume of polyhedron '''
  vol = 0.
  for f in self.f: # the faces
    n = len(f.v)
    v2 = f.v[0] # the pivot of the fan
    x2 = v2.x
    y2 = v2.y
    z2 = v2.z
    for i in range(1,n-1): # divide into triangular fan segments
      v0 = f.v[i]
      x0 = v0.x
      y0 = v0.y
      z0 = v0.z
      v1 = f.v[i+1]
      x1 = v1.x
      y1 = v1.y
      z1 = v1.z
      # Add volume of tetrahedron formed by triangle and origin
      vol += math.fabs(x0 * y1 * z2 + x1 * y2 * z0 \
                     + x2 * y0 * z1 - x0 * y2 * z1 \
                    - x1 * y0 * z2 - x2 * y1 * z0)
 return vol/6.
Другие вопросы по тегам