В три JS Object3D.applyMatrix4 не является непрерывным - PullRequest
1 голос
/ 25 февраля 2020

Я преобразовывал объект с матрицей A, используя Object3D.applyMatrix4, и обнаружил, что в какой-то момент он не сохранил направление собственного вектора.
Поэтому я попытался анимировать интерполяцию между Identity Matrix I и A и я нашел это:

enter image description here

Как преобразование может быть не непрерывным?

Ответы [ 2 ]

2 голосов
/ 25 февраля 2020

Линейная интерполяция матриц вращения не является математически обоснованной. Векторы, составляющие матрицу вращения, должны быть единичной длины ... или, по крайней мере, оставаться постоянной длины.

Представьте себе часы с стрелкой на 12 и стрелкой на 6. Если вы линейно интерполируете точку в Кончик стрелки 12 часов, до кончика стрелки 6 часов точка перемещается по прямой линии от верха часов к основанию.

Чтобы интерполировать вращение, представленное матрицей 4x4, вы можете преобразовать повороты матриц к кватернионам и .slerp (сферическая линейная интерполяция) между этими кватернионами, а затем преобразование обратно в матрицу.

И затем линейная интерполяция object.position. (хотя опять-таки .. это предполагает линейное движение между ключевыми кадрами).

Теперь, если вращение мало, вы можете избежать линейной интерполяции матрицы, но вам нужно будет ортонормировать ее на каждом шаге, преобразовать me sh в тот, который имеет постоянные векторы длины, которые ортогональны друг другу. Это не так сложно ... вы используете комбинацию точечных произведений, умножаете и складывает векторы, образующие строки матрицы (или я забыл, что столбцы), чтобы ортонормировать матрицу. Но это больше боли и менее точно, чем просто использование кватернионов и .slerp.

1 голос
/ 25 февраля 2020

@ ответ manthrax указал на фундаментальную проблему линейной интерполяции матрицы, о которой я не знал в то время, и он был прав в этом. Но реальная проблема заключалась в том, что Object3D.applyMatrix4 не была правильной функцией для явного определения локальной матрицы. Я попытался установить свойство Object3D.matrix напрямую, и это сработало. И линейная интерполяция (хотя я не должен этого делать) стала непрерывной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...