#include <math.h> struct Point2 { float x,y; }; typedef float matrix2x2[2][2]; Point2 Point2_Mat2x2_Mul(Point2 p, matrix2x2 m) { Point2 t; t.x = p.x * m[0][0] + p.y * m[1][0]; t.y = p.x * m[0][1] + p.y * m[1][1]; return t; } int main (void) { Point2 p = { 0, 100 }; float PI = 3.14159265358979f; matrix2x2 m = { cosf(PI), sinf(PI), -sinf(PI), cosf(PI) }; Point2 t = Point2_Mat2x2_Mul(p, m); return 0; }
Что бы вектор повернуть на заданный угол, необходимо его умножить на матрицу поворота. Умножение вектора на матрицу может быть 2D или 3D. Если это 3D поворот вектора- необходимо взять матрицу поворота по оси X, Y, Z - в зависимости от того вокруг какой оси необходимо повернуть вектор. В случае 2D поворота, Z ось не учитываеться при расчете, фактически 2D поворот- это 3D поворот вокруг оси Z. Для поворота вектора на угол, необходимо владеть навыками как умножить вектор на матриицу. Есть исходный вектор, есть матрица поворота- в матрицу поворота подставляеться нужный угол поворота, таким образом у нас есть матрица поворота на заданный угол. Умножаем вектор на эту матрицу и в результате получим вектор смещенный на заданный угол повотора. Угол поворота задаеться в матрице поворота в радианах.
Подитожим сказанное. В 3D вращении есть три матрицы- матрица поворота вокруг оси X, есть матрица поворота вокруг оси Y и есть матрица поворота вокруг оси Z. 2D вращение это просто 3D вращение вокруг оси Z. Что бы повернуть вектор на заданный угол необходимо:
В примере выше, поворачиваеться вектор Point2 p = { 0, 100 }; на угол 180 градусов, то есть это PI. Начало вектора в точке Point2 p1 = { 0, 0 }; - то есть в начале координатной системы. В результате выполнения кода выше мы получим вектор Point2 p = { 0, -100 }; и как видно значение Y было 100, после поворота значение Y -100 что очевидно нам удалось повернуть исходный вектор на 180 градусов.
Вот как выглядят матрицы вращения по осям X,Y,Z, где angle это угол поворота в радианах.
typedef float matrix4x4[4][4]; matrix4x4 mxRotateX = { 1.0, 0.0, 0.0, 0.0, 0.0, cos(angle), sin(angle), 0.0, 0.0, -sin(angle), cos(angle), 0.0, 0.0, 0.0, 0.0, 1.0 }; matrix4x4 mxRotateY = { cosf(angle), 0.0, sinf(angle), 0.0, 0.0, 1.0, 0.0, 0.0, -sinf(angle), 0.0, cosf(angle), 0.0, 0.0, 0.0, 0.0, 1.0 }; matrix4x4 mxRotateZ = { cosf(angle), sinf(angle), 0.0, 0.0, -sinf(angle), cosf(angle), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 };
Вот так выглядит функция умножения вектора на матрицу:
struct vertex { float x,y,z; }; typedef float matrix4x4[4][4]; vertex Vec3_Mat4x4_Mul(vertex v, matrix4x4 m) { vertex t; t.x = v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]; t.y = v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]; t.z = v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]; return t; }