У меня есть сфера в моей программе, и я собираюсь нарисовать несколько прямоугольников на расстоянии х от центра этой сферы. На рисунке выглядит что-то ниже:
Прямоугольники нарисованы в (x, y, z) точках, которые у меня уже есть в векторе 3d точек.
Скажем, расстояние х от центра равно 10. Обратите внимание на ориентацию этих прямоугольников, и они касаются воображаемой сферы радиуса 10 (перпендикулярно воображаемой линии от центра сферы к центру прямоугольника)
В настоящее время я делаю что-то вроде следующего:
Для n баллов vector<vec3f> pointsInSpace
где прямоугольники должны быть нанесены
for(int i=0;i<pointsInSpace.size();++i){
//draw rectnagle at (x,y,z)
}
который не имеет такой тангенциальной ориентации, которую я ищу.
Мне показалось, что я подал заявку roll,pitch,yaw
повороты для каждого из этих прямоугольников и использование кватернионов, чтобы сделать их касательными к тому, что я ищу.
Тем не менее, это выглядело немного сложным для меня, и я хотел спросить о каком-то лучшем способе сделать это.
Кроме того, прямоугольник в будущем может измениться на какую-то другую форму, поэтому будет приветствоваться своего рода общее решение.
Я думаю, что вы, по сути, хотите такое же преобразование, как и при использовании функции LookAt () (вы хотите, чтобы прямоугольник «смотрел» на сферу вдоль вектора от центра прямоугольника до ее начала).
Если ваш прямоугольник сформирован из точек:
(-1, -1, 0)
(-1, 1, 0)
( 1, -1, 0)
( 1, 1, 0)
Тогда нормаль прямоугольника будет указывать вдоль Z. Эта ось должна быть ориентирована на сферу.
Таким образом, нормализованный вектор от вашей точки до центра сферы — это ось Z.
Затем вам нужно определить отдельный вектор «вверх» — это типично (0,1,0), но вам нужно будет выбрать другой в случаях, когда ось Z направлена в одном направлении.
Пересечение осей «вверх» и «z» дает ось x, а затем пересечение осей «x» и «z» дает ось «y».
Эти три оси (x, y, z) непосредственно образуют матрицу вращения.
Эта результирующая матрица преобразования будет правильно ориентировать прямоугольник. Либо используйте конвейер фиксированной функции GL (yuk), и в этом случае вы можете просто использовать gluLookAt (), либо построить и использовать приведенную выше матрицу так, как это подходит для вашего собственного кода.
Лично я думаю, что ответ JasonD достаточно. Но вот некоторая информация о расчете.
Математически говоря, это довольно простая проблема. То, что у вас есть, это 2 известных вектора. Вы знаете вектор положения и сферы нормальный вектор. Так как квадрат можно произвольно вращать вокруг вектора от центра вашей сферы, вам нужно определить еще один вектор, вверх вектор. Без определения вверх вектор это становится невозможным решением.
Как только вы определили вектор с восходящим вектором, проблема становится простой. Предполагая, что ваш квадрат находится на плоскости XY как JasonD предложить выше. Тогда ваша матрица становится:
up_dot_n_dot_n.X up_dot_n_dot_n.Y up_dot_n_dot_n.Z 0
n.X n.y n.z 0
up_dot_n.x up_dot_n.x up_dot_n.z 0
p.x p.y p.z 1
Где n — это нормальный единичный вектор p — центра сферы (который является тривиальным, если сфера находится в центре системы координат), up — произвольный единичный вектор. P следует за определением формы и является позицией.
Решение имеет некоторую особенность в направлении вверх сферы. Альтернативное решение — повернуть первые 360 вокруг вверх, а 180 вокруг повернутой оси — вверх. Производит одно и то же, другой подход, нет проблемы сингулярности.