Инвертирование вращения по осям X и Y при сохранении Z неизменным

У меня есть simd_float4x4 матрица, которая является матрицей преобразования камеры.

Внутри этой матрицы у нас есть tx, ty а также tz это вектор трансляции и 0x, 0y, 0z, 1x, 1y, 1z, 2x, 2y а также 2z, то есть матрица вращения.

┌                  ┐
|  0x  1x  2x  tx  |
|  0y  1y  2y  ty  |
|  0z  1z  2z  tz  |
|  0   0   0   1   |
└                  ┘

Когда я тестирую матрицу вращения, которая у меня есть в 3D-приложении, я вижу, что вращения по осям X и Y инвертированы, а вращение по Z правильное.

Таким образом, по осям X и Y любое вращение реальной камеры по часовой стрелке отображается против часовой стрелки.

Мне нужно инвертировать эти вращения.

Потерпите меня, потому что моя матричная алгебра заржавела.

Итак, матрицы вращения для оси, как указано на следующем рисунке этого ответа SO

Если я на правильном пути, мне нужно умножить матрицу вращения на Rx а также Ry, верно?

Если я хочу инвертировать вращения в X а также Yмой Rx а также Ry будет равно:

     ┌             ┐
     |  1   0   0  |
Rx = |  0  -1   0  |
     |  0   0  -1  |
     └             ┘

     ┌             ┐
     |  -1  0   0  |
Ry = |   0  1   0  |
     |   0  0  -1  |
     └             ┘

Я могу размножаться Rx а также Ry чтобы получить окончательную матрицу, я должен использовать:

    ┌              ┐
    |  -1   0   0  |
R = |   0  -1   0  |
    |   0   0   1  |
    └              ┘

Итак, все, что мне нужно сделать, это умножить мою матрицу вращения на R получить вращение X а также Y перевернутый, правда?

Нет, конечный результат тот же... единственное, что происходит, это то, что камера кажется повернутой по оси Y.

Я использую этот код

import simd

extension simd_float4x4 {

  var rotatedXY: simd_float4x4 {

    let c0 = SIMD3<Float>(-1.0, 0.0, 0.0)
    let c1 = SIMD3<Float>(0.0, -1.0, 0.0)
    let c2 = SIMD3<Float>(0.0,  0.0, 1.0)
    let inverse = simd_float3x3(c0,c1,c2)

    let cx0 = SIMD3<Float>(columns.0.x, columns.0.y, columns.0.z)
    let cx1 = SIMD3<Float>(columns.1.x, columns.1.y, columns.1.z)
    let cx2 = SIMD3<Float>(columns.2.x, columns.2.y, columns.2.z)
    let matrix = simd_float3x3(cx0,cx1,cx2)

    let multiplication = matrix * inverse

    var resultado = self

    resultado.columns.0.x = multiplication.columns.0.x
    resultado.columns.0.y = multiplication.columns.0.y
    resultado.columns.0.z = multiplication.columns.0.z

    resultado.columns.1.x = multiplication.columns.1.x
    resultado.columns.1.y = multiplication.columns.1.y
    resultado.columns.1.z = multiplication.columns.1.z

    resultado.columns.2.x = multiplication.columns.2.x
    resultado.columns.2.y = multiplication.columns.2.y
    resultado.columns.2.z = multiplication.columns.2.z

    return resultado
  }
}

Что мне не хватает?

1 ответ

Решение

Я понял, что у меня эта линия перевернута.

let multiplication = matrix * inverse

правильно

let multiplication = inverse * matrix
Другие вопросы по тегам