Площадь компланарных точек в 3D - Python - PullRequest
0 голосов
/ 06 апреля 2020

Я получил набор копланарных точек в трехмерных координатах (x, y, z), а также уравнение плана P, к которому они принадлежат. Я хотел бы знать, как получить площадь, занятую этими точками на панели, используя Python. Я пробовал Convhull в 3d, но получаю ошибку, потому что все мои очки действительно копланарны. У вас есть идеи?

Спасибо!

1 Ответ

0 голосов
/ 06 апреля 2020

Сначала я попытался воспроизвести вашу проблему, создав несколько случайных копланарных точек и пытаясь подогнать выпуклую оболочку:

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, чтобы переключать вход (опция делает c). Если я правильно понял, это «колебание» делает ваши данные «не компланарными», создавая случайный шум в ваших данных, позволяя продолжить оптимизацию.

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

В итоге:

  • найдите угол между плоскостью и плоскостью устройства xy и поверните свои данные, если хотите получить точный ответ
  • используйте опцию "QJ", если вы хотите быстрое решение, а высокая точность не проблема (на самом деле я не знаю, насколько далеко может ответить go от истины)

Обновление

С Qhull FAQ :

Площадь - это площадь поверхности выпуклой оболочки, а объем - это общий объем выпуклой оболочки.

На 2-м плане выпуклая оболочка представляет собой многоугольник. Его поверхность - это края многоугольника. Таким образом, в 2-й области «площадь» - это длина ребер многоугольника, а «объем» - это площадь многоугольника.

Из этих утверждений я интерпретировал, что вы должны использовать:

  • hull.area / 2 для 3D-точек (ваши исходные точки с опцией QJ)
  • hull.volume для 2D-точек (если вы поворачиваете свои точки и избавляетесь от одного измерения )

Чтобы прояснить использование 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

В этом последнем примере я представляю выпуклую оболочку как приблизительно «плоский» трехмерный объект (потому что введенного шума) с двумя большими гранями. Вот почему я подумал, что вы можете использовать hull.area / 2 в этом случае.

...