Повернуть 2D, 3D вектор на заданный угол


#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;
}