Мне нужно перевести 3d точки относительно треугольника, как если бы треугольник был где-то еще

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

Я описал мою проблему в следующем документе PDF, содержащем картину того, чего я пытаюсь достичь.

Чтобы дать более подробную информацию, я разделил пятиугольники додекаэдра (12 пятиугольников) на треугольники (5/ пятиугольник, всего 60 треугольников), а затем собрал набор точек данных относительно каждого из этих треугольников.

Идея состоит в том, чтобы генерировать сетки ландшафта для каждого отдельного треугольника. Для этого данные должны быть представлены плоско, в квадрате 32K x 32K (idTech4 Megatexture)

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

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

Я получил так же быстро, как и определение точки, которая принадлежит правому заднему углу. Все мои 3D точки изначально хранятся в парах широта / долгота. Я извлекаю трехмерные векторы следующим образом:

coord getcoord(point* p) 
{
    coord c;
    c.x=cos(p->lat*pi/180.l) * cos(p->lon*pi/180.l);
    c.y=cos(p->lat*pi/180.l) * sin(p->lon*pi/180.l);
    c.z=sin(p->lat*pi/180.l);
    return c;
};

Я думаю, что если я смогу найти центр моего треугольника и выяснить, как сместить мои углы, чтобы вектор от центра моей сферы к середине треугольника переместился на 90N, то мои точки уже были бы в правильной плоскости, если Я повернул их все под одинаковыми углами. Если я затем переведу их все в 3d и вычту радиус из y, они также будут в правильном положении y.

Тогда все, что мне нужно сделать, это вращение, масштабирование и перемещение в конечную позицию.

Есть несколько видов "центров" для треугольника, я думаю, что мне нужен тот, который равноудален от углов треугольника (Circumcenter?)

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

Похоже, что некоторые примеры данных в порядке, вот несколько из этих треугольников в формате файла obj:

v 0.000000 0.000000 3396.000000
v 2061.582356 0.000000 2698.646733
v 637.063983 1960.681333 2698.646733
f 1 2 3

И другой:

v -938.631230 2888.810129 1518.737455
v 637.063983 1960.681333 2698.646733
v 1030.791271 3172.449325 637.064076
f 1 2 3

Вы заметите, что каждая точка находится на расстоянии 3396 от 0,0,0, которые я упомянул "на сфере", что означает, что лицо, удаленное от центра сферы, - это лицо, которое должно стать "вершиной" при переводе в площадь.

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

Если я не ошибаюсь, я уже принял меры к тому, чтобы первая точка, которую вы видите здесь, всегда находилась напротив самой длинной границы, поэтому именно она должна идти в крайнем левом углу (тестирование 2 приведенных выше примеров подтверждает это, но Я все равно измеряю, просто чтобы быть уверенным) Теоретически обе ноги, ведущие от этой точки, должны иметь одинаковую длину, но опять же ошибки округления могут немного компенсировать это.

Если я сделал это правильно, то более длинная сторона в 1,113587 раз длиннее, чем две более короткие стороны. Если предположить, что они идентичны, а затем выполнить поиск цели в Excel, я могу сделать вывод, что конечные точки, если я только что перевел этот треугольник, должны выглядеть следующим образом:

v 16384.000000 0.000000 16384.000000
v -16384.000000 0.000000 9916.165306
v 9916.165306 0.000000 -16384.000000
f 1 2 3

Поэтому мне нужно настроить матрицу для выполнения этого преобразования, предпочтительно используя матрицу 4x4, как описано ниже.

1 ответ

Я бы порекомендовал использовать матрицы преобразования. Матрица трехмерного преобразования представляет собой структуру данных 4x4, которая описывает перемещение и вращение (и, возможно, масштаб). Если у вас есть матрица, вы можете преобразовать точку так

 result.x = (tmp->pt.x * m->element[0][0]) + 
            (tmp->pt.y * m->element[1][0]) + 
            (tmp->pt.z * m->element[2][0]) + 
            m->element[3][0];

 result.y = (tmp->pt.x * m->element[0][1]) + 
            (tmp->pt.y * m->element[1][1]) + 
            (tmp->pt.z * m->element[2][1]) + 
            m->element[3][1];
 result.z = (tmp->pt.x * m->element[0][2]) + 
            (tmp->pt.y * m->element[1][2]) + 
            (tmp->pt.z * m->element[2][2]) + 
            m->element[3][2];
 int w = (tmp->pt.x * m->element[0][3]) + (tmp->pt.y * m->element[1][3])
      + (tmp->pt.z * m->element[2][3]) + m->element[3][3];
 if (w!=0 || w!=1)
 result.x/=w; result.y/=w; result.z/=w;

Это преобразует трехмерную точку pt на матрицу m. Если у вас теперь есть небольшая математическая математика, вы увидите, что я просто умножаю свою исходную точку как вектор на матрицу (и выполняю небольшую нормализацию, если это косая матрица). Матрицы можно умножать вместе для формирования сложных преобразований, чтобы они очень полезны

Для получения подробной информации о создании матриц предлагаем прочитать эту ссылку. http://en.wikipedia.org/wiki/Transformation_matrix

Другие вопросы по тегам