карта точек между двумя треугольниками в трехмерном пространстве - PullRequest
2 голосов
/ 23 сентября 2010

EDIT

Не знаю, важно ли это, но углы треугольника назначения могут отличаться от углов источника. Делает ли этот факт преобразование неаффинным? (я не уверен)

alt text

У меня есть два треугольника в трехмерном пространстве. Учитывая, что я знаю (x, y, z) точки в первом треугольнике и знаю векторы V1, V2, V3. Мне нужно найти точку (x ', y', z '). Какое преобразование я должен сделать, чтобы указать (x, y, z) с векторами V1, V2, V3, чтобы получить эту преобразованную точку во втором треугольнике?

Спасибо за помощь !!!

Ответы [ 6 ]

3 голосов
/ 23 сентября 2010

Думаю, вы ищете барицентрические координаты?

3 голосов
/ 23 сентября 2010

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

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

<b><i>u</i></b> = <u<sub>0</sub>, u<sub>1</sub>, u<sub>2</sub>, 1>
<b><i>u'</i></b> = <u<sub>0</sub>', u<sub>1</sub>', u<sub>2</sub>', 1>

<b><i>v</i></b> = <v<sub>0</sub>, v<sub>1</sub>, v<sub>2</sub>, 1>
<b><i>v'</i></b> = <v<sub>0</sub>', v<sub>1</sub>', v<sub>2</sub>', 1>

<b><i>w</i></b> = <w<sub>0</sub>, w<sub>1</sub>, w<sub>2</sub>, 1>
<b><i>w'</i></b> = <w<sub>0</sub>', w<sub>1</sub>', w<sub>2</sub>', 1>

Обычно ваша проблема решается путем идентификации линейного преобразования формы:

    |a<sub>0,0</sub>  a<sub>0,1</sub>  a<sub>0,2</sub>  a<sub>0,3</sub>|
A = |a<sub>1,0</sub>  a<sub>1,1</sub>  a<sub>1,2</sub>  a<sub>1,3</sub>|
    |a<sub>2,0</sub>  a<sub>2,1</sub>  a<sub>2,2</sub>  a<sub>2,3</sub>|
    |0<sub>   </sub>  0<sub>   </sub>  0<sub>   </sub>  1<sub>   </sub>|

такой, что:

<b>A<i>u</i></b> = <b><i>u'</i></b>
<b>A<i>v</i></b> = <b><i>v'</i></b>
<b>A<i>w</i></b> = <b><i>w'</i></b>

Эта формулировка необходима, потому что преобразование кажется трехмерным аффинным преобразованием, а не трехмерным линейным преобразованием. Если бы это было линейное преобразование, любой треугольник, содержащий начало координат, обязательно отображался бы в другой треугольник, содержащий начало координат. Расширение до 4-мерного пространства позволяет использовать 4-D линейное преобразование для выполнения 3-D аффинного преобразования.

Тем не менее, первое, что следует отметить, это то, что эта проблема недооценена (9 уравнений с 12 неизвестными); нет уникального решения. Их на самом деле бесконечно много. Тем не менее, ваша проблема несколько более ограничена, так что есть некоторая надежда. У вас есть дополнительные ограничения, заданные вектором

<b><i>p</i></b> = <p<sub>0</sub>, p<sub>1</sub>, p<sub>2</sub>, 1>

найти

<b>A<i>p</i></b> = <b><i>p'</i></b> = <p<sub>0</sub>', p<sub>1</sub>', p<sub>2</sub>', 1>

такой, что (используя ваши векторы определения a , b и c )

|<b><i>u</b></i> - <b><i>p</b></i>|   |<b><i>u'</b></i> - <b><i>p'</b></i>|
------- = ---------
|<b><i>u</b></i> - <b><i>a</b></i>|   |<b><i>u'</b></i> - <b>A<i>a</b></i>|

|<b><i>v</b></i> - <b><i>p</b></i>|   |<b><i>v'</b></i> - <b><i>p'</b></i>|
------- = ---------
|<b><i>v</b></i> - <b><i>b</b></i>|   |<b><i>v'</b></i> - <b>A<i>b</b></i>|

|<b><i>w</b></i> - <b><i>p</b></i>|   |<b><i>w'</b></i> - <b><i>p'</b></i>|
------- = ---------
|<b><i>w</b></i> - <b><i>c</b></i>|   |<b><i>w'</b></i> - <b>A<i>c</b></i>|

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

Тем не менее, вот некоторые возможные подходы:

  • Для решения проблемы используйте выпуклое программирование. Хотя решить их труднее, чем линейные, на самом деле их не так сложно решить.
  • Вернитесь к 2D-случаю, а не к 3D-случаю. Это можно сделать, не прибегая к нелинейным ограничениям, накладываемым этими измерениями расстояния.
  • Выберите четвертую точку и вместо работы с треугольниками работайте над тетраэдрами. Это снова удаляет нелинейность из задачи.

ОБНОВЛЕНИЕ: Я задумался над этим и нашел способ генерировать правильное аффинное преобразование без использования выпуклого программирования. Это можно сделать, генерируя четвертую вершину для каждого из треугольников, называемых <b><i>y</b></i> и <b><i>y'</b></i>:

<b><i>y</b></i> = <b><i>u</b></i> + (<b><i>v</b></i>-<b><i>u</b></i>)×(<b><i>w</b></i>-<b><i>u</b></i>)
<b><i>y'</b></i> = <b><i>u'</b></i> + (<b><i>v'</b></i>-<b><i>u'</b></i>)×(<b><i>w'</b></i>-<b><i>u'</b></i>)

, где × - это трехмерное перекрестное произведение двух векторов (т. Е. Пропустите конечную 1 в каждом векторе; но не забудьте добавить 1 к y и y ', как только вы их вычислите). Оттуда вы можете применить стандартную технику создания матриц M и M 'из векторов столбцов:

 <b>M</b> = <<b><i>u</b></i>, <b><i>v</b></i>, <b><i>w</b></i>, <b><i>y</b></i>>
 <b>M'</b> = <<b><i>u'</b></i>, <b><i>v'</b></i>, <b><i>w'</b></i>, <b><i>y'</b></i>>

и используйте метод, предложенный Стивом Эммерсоном (в 4-D, а не 3-D):

<b>AM</b> = <b>M'</b>
<b>AMM</b><sup>-1</sup> = <b>M'M</b><sup>-1</sup>
<b>A</b> = <b>M'M</b><sup>-1</sup>
2 голосов
/ 13 января 2011

проверить andand комментарии для теории

// Qt code

QMatrix4x4 m;
QMatrix4x4 t1;
QMatrix4x4 t2;

QVector3D v1(0,0,0);
QVector3D v2(0,1,0);
QVector3D v3(1,0,0);
QVector3D v4 = v1 + QVector3D::crossProduct(v2-v1, v3-v1);

QVector3D v1p(0,0,2);
QVector3D v2p(0,3,2);
QVector3D v3p(1,0,1);
QVector3D v4p = v1p + QVector3D::crossProduct(v2p-v1p, v3p-v1p);

t1.setColumn(0, QVector4D(v1, 1));
t1.setColumn(1, QVector4D(v2, 1));
t1.setColumn(2, QVector4D(v3, 1));
t1.setColumn(3, QVector4D(v4, 1));

t2.setColumn(0, QVector4D(v1p, 1));
t2.setColumn(1, QVector4D(v2p, 1));
t2.setColumn(2, QVector4D(v3p, 1));
t2.setColumn(3, QVector4D(v4p, 1));

m = t2 * t1.inverted();

for(float i=0.0; i<2.5; i+=0.05)
{
    QVector4D p(0.2+i,i,0,1);
    QVector4D pp( m * p );

    glBegin(GL_LINE_STRIP);
    glColor4f(1,1,1,1);
    glVertex3d(p.x(), p.y(), p.z());

    glColor4f(1,0,1,1);
    glVertex3d(pp.x(), pp.y(), pp.z());
    glEnd();
}

И видео этого кода в действии: http://www.youtube.com/watch?v=yOU90pBoyZY

1 голос
/ 23 сентября 2010

Требуется матричное преобразование T такое, что T X = X ', где X - матрица, столбцы которой являются координатами вершин первого треугольника, а X' - то же самое для второго треугольника. Умножение каждой стороны на инверсию X дает T = X 'X -1 .

0 голосов
/ 23 сентября 2010

Пусть

 x = αx1 + βx2 + γx3 

Тогда x '= αx1' + βx2 '+ γx3' Так

x' = α(x1+V1) + β(x2+V2) + γ(x3+V3)
0 голосов
/ 23 сентября 2010

Просто добавьте векторы к каждой точке.Точка + Вектор == Новая Точка.Это в основном противоположно созданию вектора в первую очередь: V1 == (x1'-x1, y1'-y1, z1'-z1), поэтому (x1 ', y1', z1 ') == (x1 +V1x, y1 + v1y, z1 + V1z).

...