Вращение вектора в трехмерном пространстве
Я делаю Android-проект в OpenGLES, в котором используется акселерометр для расчета изменений в конкретных осях, и моя цель - вращать вектор движения объекта, похожего на космический корабль. Проблема в том, что я не могу понять математику за матрицами вращения. Вектор движения по умолчанию равен 0,1,0, значит + y, поэтому объект вначале смотрит вверх. и я пытаюсь повернуть вектор его движения, чтобы я мог переместить объект туда, куда он указывает. Я могу собирать изменения ротации в телефоне. ось X: вращение [0], ось Y: вращение [1], ось Z: вращение [2]. Как я могу вращать свой вектор движения, используя матрицу вращения?
3 ответа
Если вы хотите повернуть вектор, вы должны построить так называемую матрицу вращения.
Вращение в 2D
Скажем, вы хотите повернуть вектор или точку на θ, тогда тригонометрия утверждает, что новые координаты
x' = x cos θ - y sin θ y' = x sin θ + y cos θ
Чтобы продемонстрировать это, давайте возьмем кардинальные оси X и Y; когда мы поворачиваем ось X на 90° против часовой стрелки, мы должны получить ось X, преобразованную в ось Y. Ось X как единичный вектор
единичный вектор вдоль оси X = <1, 0> x' = 1 cos 90 - 0 sin 90 = 0 у '= 1 грех 90 + 0, потому что 90 = 1 Новые координаты вектора == <0, 1> => ось Y.
Когда вы понимаете это, создание матрицы для этого становится простым. Матрица - это всего лишь математический инструмент, позволяющий выполнять это удобным и обобщенным образом, чтобы различные преобразования, такие как вращение, масштабирование и перемещение (перемещение), можно было объединить и выполнить за один шаг, используя один общий метод. Из линейной алгебры, чтобы повернуть точку или вектор в 2D, матрица должна быть построена
|cos θ −sin θ| | Х | = |x cos θ - y sin θ| = |x'| |sin θ cos θ| | У | |x sin θ + y cos θ| | У '|
Вращение в 3D
Это работает в 2D, а в 3D нам нужно учесть третью ось. Поворот вектора вокруг начала координат (точки) в 2D означает просто поворот его вокруг оси Z (линии) в 3D; поскольку мы вращаемся вокруг оси Z, его координаты должны оставаться постоянными, то есть 0° (вращение происходит на плоскости XY в 3D). В 3D вращение вокруг оси Z будет
|cos θ −sin θ 0| | Х | | x cos θ - y sin θ | | Х '| |sin θ cos θ 0| | У | = |x sin θ + y cos θ| = |y'| | 0 0 1| | Г | | z| | Г '|
вокруг оси Y будет
| cos θ 0 sin θ| | Х | | x cos θ + z sin θ| | Х '| | 0 1 0| | У | = | у | = |y'| |−sin θ 0 cos θ| | Г | |−x sin θ + z cos θ| | Г '|
вокруг оси X будет
|1 0 0| | Х | | х | | Х '| |0 cos θ −sin θ| | У | = |y cos θ - z sin θ| = |y'| |0 sin θ cos θ| | Г | |y sin θ + z cos θ| | Г '|
Обратите внимание, что ось, вокруг которой выполняется вращение, не имеет элементов sin или cos в матрице. Я надеюсь, что это делает случай вращения ясным.
Состав
Вышеупомянутые матрицы вращают объект так, как будто объект находится на расстоянии r = √(x² + y²) от начала координат; ищите полярные координаты, чтобы знать почему. Это вращение будет относительно мирового космического происхождения. Обычно нам нужно вращать объект вокруг его собственной рамки / оси, а не вокруг мира. Поскольку не все объекты имеют мировое происхождение, вращение с использованием этих матриц не даст желаемого результата вращения вокруг собственной рамки объекта. Следовательно, вам нужно узнать и о переводе. Сначала вы должны перевести (переместить) объект в начало мира (чтобы источник объекта выровнялся с миром, тем самым сделав r = 0), выполнить вращение с одной (или более) из этих матриц, а затем снова перевести его обратно. на прежнее место. Порядок, в котором применяются преобразования, имеет значение.
Я призываю вас прочитать о линейных и аффинных преобразованиях и их композиции для выполнения нескольких преобразований за один раз, прежде чем играть с преобразованиями в коде. Без понимания основных математических основ отладка преобразований была бы кошмаром. Я нашел это видео лекции очень хорошим ресурсом. Другой ресурс - это учебное пособие по трансформациям, которое стремится быть интуитивно понятным и иллюстрирует идеи с помощью анимации.
Примечание. Этот метод выполнения поворотов основан на системе углов Эйлера, которую проще учить и понимать. Это прекрасно работает для 2D и для простых 3D случаев; но когда вращение необходимо выполнять вокруг всех трех осей одновременно, то углов Эйлера для этого недостаточно из-за присущего этой системе недостатка, который проявляется в виде блокировки карданного подвеса. В таких ситуациях люди прибегают к кватерниону, который более продвинут, чем этот, но при правильном использовании не страдает от карданных замков.
Ссылки на документы здесь: http://developer.android.com/reference/android/opengl/Matrix.html
- Построить матрицу вращения
- Преобразовать вектор с матрицей
Вам не нужно понимать математику, библиотечные функции выполнят свою работу.
Я рассудил, что компонент X вашего вектора должен быть M * cos (o) cos(t)+x, компонент Y должен быть Mcos(t)sin (o) +y, а компонент z должен быть Mcos (o ) *sin(t)+z, где M - величина вектора, o - угол поворота в вертикальной плоскости, t - угол поворота в горизонтальной плоскости, x - значение x центра вращения, y - значение y центра вращения, а z - значение z центра вращения. Скажите, пожалуйста, работает ли это для вас.