Как узнать матрицу вращения для ориентированной ограничительной рамки
Поэтому я использую набор данных Matterport 3D для своей задачи, и он описал ориентированную ограничивающую рамку с использованием стандартной структуры с одним изменением следующим образом:
"obb": {
"centroid":[3.39208,-1.72134,1.13262],
"axesLengths":[1.11588,0.619098,0.439177],
"dominantNormal":[-0.707107,-0.707107,0],
"normalizedAxes":[0,0,1,-0.707107,0.707107,0,-0.707107,-0.707107,0]
}
Я понимаю, что ориентированная ограничивающая рамка обычно определяется центроидом, осями локальной системы координат и длинами вдоль этих осей.
В моем случае, учитывая, что объект вращается только вокруг вертикальной оси (ось z) в мировой системе координат, я хочу выяснить угол, на который он вращается вокруг оси z. Но для этого мне нужна матрица вращения, которая преобразует мировую систему координат в локальную систему координат. В стандартном случае представления матрица вращения - это матрица размером всего 3х3 с осями в качестве векторов столбцов. Однако, в этом случае, если вы посмотрите на массив нормализованных осей, то будет дано 9 значений, без каких-либо соглашений относительно того, какая ось должна быть вектором первого столбца или вектором второго столбца в матрице вращения.
Предполагая, что положение объекта является вертикальным и поворачивается только вокруг оси z, я могу определить последний столбец матрицы вращения. Например, [0, 0, 1] в вышеупомянутом примере. Но как определить две другие оси? Есть ли способ принять во внимание "доминирующую нормальную" информацию при определении этого?
2 ответа
Давайте возьмем пример, приведенный в задаче. Нормализованные оси задаются, но не в каком-либо конкретном порядке, как указано ниже.
"normalizedAxes":[0,0,1,-0.707107,0.707107,0,-0.707107,-0.707107,0]
Поскольку мы знаем, что объект вращается только вокруг оси z, третий столбец в матрице вращения будет [0, 0, 1]. Так что это оставляет нас с двумя столбцами; давайте назовем их axis_0, axis_1.
Так,
axis_0 = [-0.707107, 0.707107, 0]
axis_1 = [-0.707107, -0.707107, 0]
Вы можете вычислить угол, который каждая из этих осей образует с осью X в глобальной системе координат, используя обратную касательную функцию. Скажем, угол, созданный axis_0 и axis_1, равен angle_0 и angle_1 соответственно.
Любое из следующих соотношений должно быть верным, поскольку мы знаем, что axis_0 и axis_1 ортогональны.
angle_0 = angle_1 + 90 or angle_1 = angle_0 + 90
Таким образом, с вышеупомянутым примером, вы можете заметить, что
angle_0 = 135 degrees
angle_1 = 225 degrees (-135 degrees)
Поскольку мы рассматриваем вращение против часовой стрелки как положительное, ось, которая составляет меньший угол, будет первым столбцом в матрице вращения, а другая ось будет вторым столбцом в матрице вращения.
В этом случае матрица вращения выглядит следующим образом:
[ [ -0.707107, -0.707107, 0],
[ 0.707107, -0.707107, 0],
[ 0, 0, 1],
]
Если вы используете arctan2
будьте осторожны при работе с особыми случаями, когда оси вращаются по часовой стрелке, а оси Y и X лежат в первом и четвертом квадранте соответственно.
Предполагая, что normalizeAxes
свойство имеет следующее значение:
[X1, X2, X3, Y1, Y2, Y3, Z1, Z2, Z3]
Тогда столбцы матрицы вращения локального мира равны векторам XYZ
:
| X1 Y1 Z1 |
R = | X2 Y2 Z2 |
| X3 Y3 Z3 |
Матрица поворота мира в локальные области, конечно, является лишь обратной (= транспонированной) этой:
| X1 X2 X3 |
inv(R) = | Y1 Y2 Y3 |
| Z1 Z2 Z3 |
Принимая перевод centroid = [C1, C2, C3]
во внимание:
| X1 Y1 Z1 C1 |
T = | X2 Y2 Z2 C2 |
| X3 Y3 Z3 C3 |
| 0 0 0 1 |
| X1 X2 X3 -dot(C, X) |
inv(T) = | Y1 Y2 Y3 -dot(C, Y) |
| Z1 Z2 Z3 -dot(C, Z) |
| 0 0 0 1 |
Не уверен что dominantNormal
представляет (по-видимому, нет открытой документации для него); может быть метаданными для затенения или мерой распределения геометрии в этом OBB.