Мои мысли и проекты

Поворот точки (вектора) + масштабирование и перенос

Навигация
Счетчики
Cпoнcоры

Поворот точки (вектора) + масштабирование и перенос

Все повороты в 3D графике происходят через матрицы. Однако в файлах слоев параметры поворота задаются в виде углов вокруг осей X и Z. Так что нужно разобраться как преобразовывать точки в соответствии с этими углами.
Матрицы поворота вокруг осей X и Z выглядят вот так:



(матрицы были взяты из исходников движка Ogre3D из файла OgreMatrix3.cpp в котором указано, что код в свою очередь был взят и адаптирован с сайта http://www.geometrictools.com/ :) )
Можно создать класс матрицы поворота с поддержкой перемножения матриц по всем правилам. Тогда нужно будет: создавать две эти матрицы поворота, перемножать их, а затем умножать нужный вектор на итоговую матрицу. По правилам перемножения матрицы перемножаются вот так:



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



Не сложно заметить, что нулевых слагаемых получается очень много и мы можем сократить вычисление произведения матриц на 20! операций умножения (операции сложения не считаем, так как они по сравнению с умножением выполняются достаточно шустро). Также можно убрать умножение на элементы, которые равны 1. В результате получаем очень простую матрицу, которую и следует умножать на наш вектор (точку), которую нужно повернуть:



Вектор [21,22,23] это и есть наша исходная точка, требующая поворота, где 21 = x, 22 = y, 23 = z
В результате получим итоговый вектор:



который содержит всего 12 операций умножения. При этом можно сократить это количество ещё на 2 операции, предварительно вычислив произведения 14*21 и 15*22, которые повторяются дважды.
С масштабированием всё гораздо проще. Достаточно перед поворотом умножить исходный вектор на коэффициенты масштаба.
Перенос тоже достаточно тривиален: нужно после поворота вектора прибавить к нему значения переноса.

P.S. Умные люди указали на тот факт, что скорость вычисления sin/cos на порядок тормознее произведения. Так что повороты лучше хранить в МАТРИЦЕ 3x3 и при повороте умножать именно на матрицу. Т.е. вычисление sin/cos следует минимизировать.

Категории: OSM 3D