Вращение матрицы 4x4 вызывает масштабирование с течением времени

Я использую glm::rotate для поворота матрицы преобразования для куба в сцене.

"cube->t = glm::rotate(cube->t, stepTime * 50.f, glm::vec3(0.f, 1.f, 0.f));" вызывается один раз за кадр, где cube->t — рассматриваемая матрица.

Странно то, что в течение 20 минут (или двух минут, если я поверну на stepTime * 5000.f вместо stepTime * 50.f) куб заметно масштабируется по осям X и Z, причем масштабирование по этим двум осям всегда одинаково ( высота куба никогда не меняется, но ширина и глубина изменяются точно на ту же величину). В случае 5000.f становится меньше, а при обычном 50.f или 100.f становится больше.

Я думал, что это может быть вопрос ошибки округления, но кроме этого я понятия не имею, что может быть причиной этого. Это ошибка округления? Могу ли я решить эту проблему, нормализуя матрицу на регулярной основе? Есть ли в glm функция нормализации матриц, или я должен сам ее написать?


person Miles    schedule 29.06.2012    source источник
comment
Вы задаете интересный вопрос, раскрывая практическую разницу между математическим анализом и итерационными численными результатами. Подозреваю, что вы правы в нормализации матрицы.   -  person thb    schedule 30.06.2012
comment
Звучит как ошибка округления, но я пока не трогал OpenGL — нормализация матрицы звучит как идея. Вы пытались изменить параметры вращения, чтобы увидеть, по-разному ли они влияют на разные векторы вращения?   -  person Charleh    schedule 30.06.2012
comment
Я не пробовал с разными векторами. Я скажу вам, что произойдет, как только я протестирую его.   -  person Miles    schedule 30.06.2012
comment
Да, кажется, что он масштабируется только по осям X и Y, когда я вращаю куб по оси Z. Так что он реагирует так же   -  person Miles    schedule 30.06.2012


Ответы (2)


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

Редактировать: в ответ на обсуждение с Майлзом более подходящий ответ:

Если вы можете разделить вращательные и поступательные компоненты матрицы преобразования, и проблема в основном связана с накоплением вращения, вызывающим сдвиг или масштабирование, вы можете исправить проблему, извлекая угол из вращательного компонента и воссоздавая матрицу вращения с помощью этот угол, а единица длины.

person Alex Wilson    schedule 29.06.2012
comment
Я хотел бы использовать матрицы для видеоигры, где изменения должны сохраняться постепенно. Как предотвратить масштабирование моделей с течением времени? - person Miles; 30.06.2012
comment
@ Майлз Руфат-Латр. Если они должны храниться постепенно, они должны храниться постепенно. Однако, если вы видите проблемы с кумулятивной точностью, лучшим (наиболее стабильным/оправданным/надежным) решением является сохранение оригинала и некоторой структуры данных, представляющей применяемое кумулятивное преобразование. Вы уверены, что в вашем случае это невозможно? В противном случае вы можете попробовать нормализацию. Вы применяете переводы, а также повороты? - person Alex Wilson; 30.06.2012
comment
Да, я буду использовать как переводы, так и повороты в одних и тех же матрицах. (и я ни в коем случае не могу избежать инкрементального хранения преобразований: игра включает в себя множество симуляций 3D-физики, отслеживание преобразований любым другим способом ограничило бы функциональность) - person Miles; 30.06.2012
comment
Есть ли у кватернионов такая же проблема с масштабированием при вращении? (Я не возражаю, если повороты будут неточными, если в результате не происходит масштабирование) - person Miles; 30.06.2012
comment
@MilesRufat-Latre: Если вы можете отделить перевод от вращения, то, я думаю, вы можете извлечь угол поворота, а затем воссоздать матрицу вращения единичной длины с представлением этого конкретного угла. Это то, что вы имеете в виду под нормализацией? - person Alex Wilson; 30.06.2012
comment
На самом деле, это звучит намного лучше, чем то, что я делаю сейчас. Я не это имел в виду, но так будет лучше. Я имел в виду взять первые три члена диагонали и нормализовать их, как если бы вы нормализовали 3-вектор, в результате чего получилась бы немасштабируемая матрица. Я не знаю, будут ли эти изменения совместимы с моей текущей настройкой физического движка. - person Miles; 30.06.2012
comment
@Miles: я думаю, что это больше соответствует тому результату, который, как я думаю, вы хотите. - person Alex Wilson; 30.06.2012
comment
@Майлз. Спасибо. Дайте мне знать, адекватно ли я представил нашу дискуссию. - person Alex Wilson; 30.06.2012
comment
Вам не нужно разделять эти фрагменты информации, если вы не планируете масштабировать куб. Все, что вам нужно сделать, это ортонормировать вращательную часть матрицы после каждого шага вращения. (Google для ортонормализации Грама Шмидта) - person datenwolf; 30.06.2012

Да, это ошибка округления. Разумным решением будет хранить ориентацию как одно число и в каждом кадре строить матрицу с нуля.

person Juraj Blaho    schedule 29.06.2012
comment
Смотрите мой комментарий к ответу выше. - person Miles; 30.06.2012