Должны ли основанные на кватернионах трехмерные камеры накапливать кватернионы или углы Эйлера?

StackOverflow https://stackoverflow.com/questions/319189

Вопрос

Итак, я написал 3D-камеру на основе Quaternion, ориентированную на новых программистов, поэтому им очень легко интегрироваться и начинать использовать.

Пока я его разрабатывал, сначала я принимал пользовательский ввод в качестве углов Эйлера, а затем генерировал кватернион на основе входных данных для этого кадра. Затем я взял бы кватернион камеры и умножил его на тот, который мы сгенерировали для входа, и теоретически это должно просто добавить вращение входа к текущему состоянию вращения камеры, и все будет полным и счастливым. Давайте назовем это: накопление кватернионов, потому что мы храним и добавляем только кватернионы.

Но я заметил, что с этим методом возникла проблема. Чем больше я его использовал, даже если бы я вращался только на один угол Эйлера, скажем Yaw, он через некоторые итерации начинал бы перетекать в другой, скажем Pitch. Это было незначительно, но довольно неприемлемо.

Итак, я провел еще какое-то исследование и обнаружил статью, в которой говорилось, что лучше накапливать углы Эйлера, поэтому камера сохраняет свое текущее вращение в виде углов Эйлера, и ввод в них просто добавляется к каждому кадру. Затем я генерирую кватернион из них каждый кадр, который, в свою очередь, используется для генерации моей матрицы вращения. И это исправило проблему вращения вращения в неправильные оси.

Итак, есть ли у кого-либо из участников Stackoverflow понимание этой проблемы? Это правильный способ делать вещи?

Это было полезно?

Решение

Умножающиеся кватернионы будут страдать от накопления проблем округления с плавающей точкой (даже простые углы, такие как 45 градусов, не будут точными). Это отличный способ составного вращения, но точность каждого из ваших компонентов кватерниона со временем будет падать. Выпуск является одним из побочных эффектов, визуально хуже, хотя ваш кватернион может начать включать масштабный коэффициент - чтобы восстановить это, вам в любом случае придется перенормировать обратно в углы Эйлера. Угол Эйлера с фиксированной точкой не будет накапливать округление.

Пересчет кватерниона на кадр минимален. Я бы не стал пытаться оптимизировать его. Возможно, вы могли бы позволить накопиться нескольким кватернионам, прежде чем перенормировать, чтобы вернуть точность, но это действительно не стоит усилий.

Другие советы

Накопление - это неточный процесс. Накопление большого количества инкрементных вращений накапливает ошибку округления независимо от того, делаете ли вы это с кватернионами или матрицами.

Я представляю что-то вроде этого: ваш код запущен и работает, но вы заметили, что после определенного количества навигации ваша камера раздражающе кренится - нарушая инвариант, о котором вы заранее не думали. По сути, вы поняли, что не хотите накапливать вращения; вместо этого вы хотите сделать что-то еще.

Вы можете рассматривать это как проблему проектирования интерфейса, а не как проблему числовой точности. По сути, люди ожидают, что камера будет перемещаться в зависимости от высоты, рыскания и поворота, поэтому выбор прямого управления и представления углов может избежать многих проблем.

Облом здесь в том, что кватерионы, похоже, стали избыточными (по крайней мере, для этого конкретного использования). Вы все еще хотите кватернионы, хотя - интерполяция с необработанными углами тангажа / рыскания / крена может быть некрасивой. Опять же, это вопрос дизайна интерфейса: вам нужно выяснить, где вам понадобятся кватернионы, и как их вводить и выводить ...

Я видел, как оба аргументировали. Я думаю, что реальный вопрос, с которым вам придется столкнуться, - это гибкость вашей системы камер. ИМО рыскание, как правило, более интересно в представлении от третьего лица (потому что вы собираетесь вращаться вокруг вертикальной оси персонажа). В то время как вы можете, возможно, «рыскать» вокруг вертикали в виде от первого лица, я не уверен, что это действительно одно и то же.

Тем не менее, я считаю, что перерасчет ваших кватернионов для каждого кадра - это пустая трата времени. Возможно, было бы лучше хранить последние кватернионы и помечать их как грязные, если ваш кадр получает входные данные?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top