Как узнать матрицу вращения для ориентированной ограничительной рамки

Поэтому я использую набор данных 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.

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