Вращение трехмерного многоугольника в плоскость xy с сохранением ориентации

У меня есть многоугольник, ориентированный каким-либо образом и расположенный в любом месте в трехмерном пространстве. Мне нужно преобразовать многоугольник в плоскость xy, чтобы я мог выполнять над ним различные операции (в частности, создавать сетку точек через ограничительную рамку многоугольника) в 2d, а не в 3d, а затем преобразовать его обратно.

Проблема возникает с ориентацией преобразованного многоугольника. Если бы я просто хотел повернуться в плоскости, я мог бы взять угол между нормалью многоугольника и плоскостью xy и повернуть вокруг оси, ортогональной обеим (перекрестное произведение). Однако я требую, чтобы ограничивающая рамка многоугольника была ориентирована таким образом, чтобы нижний край (наименьшее значение z) ограничивающей рамки находился в одной плоскости с плоскостью xy как до, так и после преобразования. Другими словами, ограничивающая рамка опирается на одну сторону, параллельную земле. После преобразования это ребро будет параллельно оси x. Это сделано для того, чтобы сетка точек, которую я генерирую на поверхности, всегда имела ряды, идущие параллельно земле, независимо от ориентации полигона.

Мой подход заключается в выполнении двух вращений; сначала поверните вокруг оси z на угол между линией, образованной пересечением плоскости многоугольника и плоскости xy, и осью x. Это гарантирует, что нижняя часть ограничивающей рамки не выйдет за пределы плоскости xy. Затем снова поверните вокруг оси x на угол между нормалью многоугольника (новой) и плоскостью xz. Вот шаги:

  1. Найдите уравнение плоскости многоугольника (по нормали).
  2. Найдите пересечение плоскости многоугольника и плоскости xy. Это линия в плоскости xy.
  3. Найдите угол между этой линией и осью x.
  4. Поверните многоугольник на этот угол вокруг оси Z.
  5. Определить новую норму.
  6. Найдите угол между новой нормалью и нормалью плоскости xy.
  7. Поверните многоугольник на этот угол вокруг оси x.
  8. Теперь полигон должен находиться в плоскости xy; создать ограничивающую рамку, используя максимальные/минимальные значения x и y, создать сетку точек и т. д., а затем преобразовать все обратно в исходное положение.

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

Я не эксперт по графике; может кто посоветует эту технику? Есть ли способ лучше? Мой подход звучит правильно? Я разрабатываю Java и рассматриваю использование класса Transform3D для поворотов.


person Tony R    schedule 16.05.2011    source источник
comment
Я голосую за то, чтобы закрыть свой вопрос. Вероятно, это слишком локализовано, и мой метод все равно был более или менее правильным. Это было бы лучше подходит для графического форума. Акт написания вопроса помог мне решить проблему.   -  person Tony R    schedule 01.06.2011
comment
Большое спасибо за этот вопрос, это именно то, что мне было нужно! Возможно, вы могли бы опубликовать свое решение в качестве ответа, чтобы я мог проголосовать за него :-)   -  person andygeers    schedule 20.11.2019


Ответы (2)


Для обработки 3D-полигонов обычно просто игнорируют координату Z (которая эффективно проецирует плоскость непосредственно на плоскость XY) для ваших отображений, а затем просто восстанавливают координаты Z позже.

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

person Alnitak    schedule 16.05.2011
comment
Я не понимаю, как это помогает. Создание точечной сетки на проекции — это не то же самое, что нанесение ее на настоящий полигон. - person Tony R; 17.05.2011
comment
ах, да, поскольку, если вы интерполировали новую точку XY, вам также пришлось бы вычислять новую координату Z. Хм... - person Alnitak; 17.05.2011

Вам нужна следующая матрица, чтобы изменить координаты вершин с кадра x0,y0,z0 на x1,y1,z1 и, в конечном итоге, смещение, чтобы совпасть начала координат.

     // F0 changes x0,y0,z0 to world X,Y,Z            
     F0[0, 0] = X0.X;
     F0[0, 1] = X0.Y;
     F0[0, 2] = X0.Z;
     F0[1, 0] = Y0.X;
     F0[1, 1] = Y0.Y;
     F0[1, 2] = Y0.Z;
     F0[2, 0] = Z0.X;
     F0[2, 1] = Z0.Y;
     F0[2, 2] = Z0.Z;
     F0[3, 3] = 1.0;

     // F1 changes world X,Y,Z to x1,y1,z1            
     F1[0, 0] = X1.X;
     F1[0, 1] = Y1.X;
     F1[0, 2] = Z1.X;
     F1[1, 0] = X1.Y;
     F1[1, 1] = Y1.Y;
     F1[1, 2] = Z1.Y;
     F1[2, 0] = X1.Z;
     F1[2, 1] = Y1.Z;
     F1[2, 2] = Z1.Z;
     F1[3, 3] = 1.0;

     matrix = F1*F0
person abenci    schedule 17.05.2011