Вращение спрайта вокруг произвольной точки

Собственно классическое решение задачи поворота спрайта на заданный угол вокруг произвольной точки (чаще всего его центра) путем матричных преобразований описана в куче литературы и интернет-источниках и звучит следующим образом: перенос спрайта таким образом, чтобы точка совпадал с точкой 0.0,0.0 , поворот на заданный угол, перенос обратно.
Функция RotateAroundAxis представляет реализацию данного метода (Axis — ось или точка, вокруг которой будет повернут спрайт, Angle — угол поворота):

 

Вспомогательная функция CountWorldMatrix добавляет полученную матрицу трансформации к исходной матрице объекта, за счет чего и выполняется поворот:

 

 

При вызове функции RotateAroundAxis необходимо, чтобы координаты оси были заданны в той же самой системе координат, в которой находится сам поворачиваемый спрайт. Если не соблюдать это правило спрайт будет поворачиваться и убегать куда угодно, только не в ту точку, в которую его необходимо было поместить. Чаще же всего поворачивать спрайт удобнее всего вокруг точки, заданной в системе координат сцены, т.е. того контейнера в котором собираются все отображаемые спрайты. Поэтому, чтобы повернуть спрайт например вокруг центра экрана, сначала необходимо width/2 и height/2 перевести в систему координат спрайта.
Для этих целей служит функция globalToLocal, которая собственно умножает переданную в нее точку на обратную concatenated-матрицу объекта из которого вызывается. Однако же на практике ее использование оказалось достаточно своеобразным. Когда спрайт является чайлдом сцены — globalToLocal срабатывает правильно. Стоит же создать иерархию из 2-3 подчиненных уровней сцена -спрайт — чайлд спрайта — … начинаются нестыковки. В случаях, если спрайт сначала повернуть, после чего добавить ему чайлда и если к спрайту добавить уже повернутого чайлда, функция срабатывает далеко не так, как нужно. Поэтому функцию приходится переопределять (заодно переопределяется тип входного параметра на Vector2 — переопределенный Point со статическими методами операций над двумерными векторами):

 

 

Соответственно, делаем обертку над вызовом функции RotateAroundAxis:

 

 

Такое переопределение позволяет правильно вращать спрайт вокруг произвольной оси независимо от того, является он чьим-то чайлдом или нет.
Вращение спрайта вокруг центра сцены на 45 градусов будет выглядеть следующим образом:

 

 

0 0 голоса
Article Rating
Подписаться
Уведомить о
0 Комментарий
Новые
Старые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии