Вычислительная геометрия, тетраэдр подписанный том

Я не уверен, если это правильное место, чтобы спросить, но здесь идет...

короткая версия: Я пытаюсь вычислить ориентацию треугольника на плоскости, образованной пересечением 3 ребра, без явного вычисления точек пересечения.

версия: мне нужно триангулировать PSLG на треугольнике в 3D. Вершины PSLG определяются пересечениями отрезков линии с плоскостью через треугольник и являются гарантированно лежит внутри треугольника. Предполагая, что у меня есть точки пересечения, я мог бы проецировать в 2D и использовать тест точки-линии-стороны (или треугольника), чтобы определить ориентацию треугольника между любыми 3 точками пересечения.

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

поскольку я не могу явно вычислить точки пересечения, мне интересно, если существует способ выразить тот же расчет 2D-ориентации в 3D, используя только исходные точки. Если есть 3 ребра, поражающие треугольник, который дает мне 9 очков в общей сложности, чтобы играть. Предполагая, что то, что я прошу, даже возможно (используя только тесты 3D orient), то я предполагаю, что мне нужно будет сформировать некоторое подмножество всех возможных тетраэдров между этими 9 точками. Мне трудно даже представить это, не говоря уже о том, чтобы перегнать его в формулу или код. Я даже не могу google это, потому что я не знаю, какая стандартная терминология может быть для этого типа проблем.

есть идеи, как это сделать? Спасибо. Возможно, мне также следует спросить MathOverflow...

EDIT: после прочтения некоторых комментариев, одна вещь, которая приходит мне в голову... Возможно, если бы я мог поместить неперекрывающиеся тетраэдры между тремя сегментами линии, то ориентация любого из тех, которые пересекли плоскость, была бы ответом, который я ищу. Кроме случаев, когда ребра заключают простая треугольная призма, я не уверен, что эта подзадача также разрешима.

EDIT: запрошенное изображение. alt text

4 ответов


Я отвечаю на это как на MO & SO, расширяя комментарии, которые я сделал на MO.

мое чувство заключается в том, что никакой вычислительный трюк с подписанными томами тетраэдров не позволит избежать проблем точности, которые являются вашей главной заботой. Это потому, что, если у вас плотно скрученные сегменты, ориентация треугольника зависит от точного позиционирования плоскости резания.
[изображения удалены, см. ниже]
В приведенном выше примере, верхняя плоскость пересекает отрезков в порядке (a, b, c) [ccw сверху]: (красный,синий,зеленый), в то время как нижняя плоскость пересекается в обратном порядке (c, b, A): (зеленый,синий,красный). Высота плоскость резания может быть определена вашим последним битом точности.

следовательно, я думаю, что имеет смысл просто идти вперед и вычислять точки пересечения в плоскость вырезывания, используя достаточную точность для того чтобы сделать вычисление точным. Если координаты конечных точек сегмента и коэффициентов самолета L биты точности, тогда необходимо только небольшое увеличение постоянного фактора. Хотя я точно не знаю, что это за фактор, он невелик-возможно, 4. Вам не понадобится, например,L2 бит, потому что вычисление решает линейные уравнения. Таким образом, не будет взрыва в точности, необходимой для точного вычисления этого.

удачи!

(Я не отправляю потому что у меня нет репутации. Видеть the ответ МО.)

редактировать: видите ответ MO, но вот изображение:

Image


Я бы написал символические векторные уравнения, вы знаете, с точечными и перекрестными произведениями, чтобы найти Нормаль треугольника пересечения. Затем знак точечного произведения этой нормали с начальным треугольником дает ориентацию. Итак, наконец, вы можете выразить это в знаке формы (F (p1,...,p9)), где p1-p9-ваши точки, А F () - уродливая формула, включающая точки и перекрестные произведения различий (pi-pj). Не знаю, можно ли это сделать проще, но этот общий подход делает работа.


как я понимаю, у вас есть три линии, пересекающие плоскость, и вы хотите рассчитать ориентацию треугольника, образованного точками пересечения, без расчета самих точек пересечения?

если это так: у вас есть самолет

N·(x - x0) = 0

и шесть очков...

l1a, l1b, l2a, l2b, l3a, l3b

...образуя три линии

l1 = l1a + t(l1b - l1a)
l2 = l2a + u(l2b - l2a)
l3 = l3a + v(l3b - l3a)

точки пересечения этих линий с плоскостью происходят при определенных значениях t, u, v, которые я буду называть tя, uя, vя

N·(l1a + ti(l1b - l1a) - x0) = 0

      N·(x0 - l1a)
ti =  ----------------
      N·(l1b - l1a)
(similarly for ui, vi)

тогда конкретные точки пересечения являются

intersect1 = l1a + ti(l1b - l1a)
intersect2 = l2a + ui(l2b - l2a)
intersect3 = l3a + vi(l3b - l3a)

наконец, ориентация вашего треугольника

orientation = direction of (intersect2 - intersect1)x(intersect3 - intersect1)

(x является кросс-продуктом) работайте в обратном направлении, подключая значения, и у вас будет уравнение для ориентации, основанное только на N, x0, и свои шесть очков.


давайте назовем ваши вершины треугольника T[0], T[1], T[2], а конечными точками сегмента первой строки являются L[0] и L[1], второй -L[2] и L[3], третья -L[4] и L[5]. Я полагаю, вы хотите функцию

int Orient(Pt3 T[3], Pt3 L[6]); // index L by L[2*i+j], i=0..2, j=0..1

который возвращает 1, Если пересечения имеют ту же ориентацию, что и треугольник, и -1 в противном случае. Результат должен быть симметричным при обмене j значения, антисимметричные при обмене i значения и T индексы. Пока вы можете вычислить количество с помощью этих симметрий, это все, что вам нужно.

попробуем

Sign(Product( Orient3D(T[i],T[i+1],L[2*i+0],L[2*i+1]) * -Orient3D(T[i],T[i+1],L[2*i+1],L[2*i+0]) ), i=0..2))

где произведение должно быть взято над циклическими перестановками индексов (по модулю 3). Я считаю, что это имеет все необходимые свойства симметрии. Orient3D это 4-точечный тест ориентации плоскости Шевчука, который, я полагаю, вы используете.