简单渲染流水管线C++代码实现(六)---绕任意过原点的轴旋转矩阵
程序员文章站
2022-07-14 23:19:35
...
三维矩阵当中,绕x、y、z轴旋转其实是很简单的,这里不做推导了,和之前的二维旋转矩阵推导很类似,下面主要讲如何推导绕任意过原点的轴旋转矩阵。
//绕过原点指定轴旋转
Matrix4& Rotate(const Vector3& n, float a)
{
//单位化指定轴向量
Vector3 any_nomalize = n.Normalize();
//处理数据
float xx = any_nomalize.x * any_nomalize.x;
float yy = any_nomalize.y * any_nomalize.y;
float zz = any_nomalize.z * any_nomalize.z;
float xy = any_nomalize.x * any_nomalize.y;
float yz = any_nomalize.y * any_nomalize.z;
float zx = any_nomalize.z * any_nomalize.x;
float c = cos(a);
float one_sub_c = 1.0f - c;
float s = sin(a);
m[_M_11] = xx * one_sub_c + c;
m[_M_12] = xy * one_sub_c + any_nomalize.z * s;
m[_M_13] = zx * one_sub_c - any_nomalize.y * s;
m[_M_14] = 0.0f;
m[_M_21] = xy * one_sub_c - any_nomalize.z * s;
m[_M_22] = yy * one_sub_c + c;
m[_M_23] = yz * one_sub_c + any_nomalize.x * s;
m[_M_24] = 0.0f;
m[_M_31] = zx * one_sub_c + any_nomalize.y * s;
m[_M_32] = yz * one_sub_c - any_nomalize.x * s;
m[_M_33] = zz * one_sub_c + c;
m[_M_34] = 0.0f;
m[_M_41] = 0.0f;
m[_M_42] = 0.0f;
m[_M_43] = 0.0f;
m[_M_44] = 1.0f;
return *this;
}
补充三维向量Vector3、三维矩阵Matrix4的代码实现
#pragma once
#include "vector2.h"
class Vector3
{
public:
float x, y, z;
//构造
Vector3(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f) :x(_x), y(_y), z(_z) {}
void Set(float _x = 0.0f, float _y = 0.0f, float _z = 0.0f)
{
x = _x;
y = _y;
z = _z;
}
float Length() const
{
return sqrt(x * x + y * y + z * z);
}
Vector3 Normalize() const
{
float length = sqrt(x * x + y * y + z * z);
assert(!(length >= -0.001f && length <= 0.001f));
return Vector3(x / length, y / length, z / length);
}
//向量相等判定重载
bool IsEqual(const Vector3& that) const
{
if (x == that.x && y == that.y && z == that.z)
return true;
return false;
}
Vector3 operator + (const Vector3& that) const
{
return Vector3(x + that.x, y + that.y, z + that.z);
}
Vector3& operator += (const Vector3& that)
{
x += that.x;
y += that.y;
z += that.z;
return *this;
}
//负号重载
Vector3 operator - () const
{
return Vector3(-x, -y, -z);
}
//减号重载
Vector3 operator - (const Vector3& that) const
{
return Vector3(x - that.x, y - that.y, z - that.z);
}
Vector3& operator -= (const Vector3& that)
{
x -= that.x;
y -= that.y;
z -= that.z;
return *this;
}
//向量 * 标量
Vector3 operator * (float num) const
{
return Vector3(x * num, y * num, z * num);
}
//向量 *= 标量
Vector3& operator *= (float num)
{
x *= num;
y *= num;
z *= num;
return *this;
}
//向量 / 标量
Vector3 operator / (float t) const
{
//断言标量非零
assert(!(t >= -0.001f && t <= 0.001f));
return Vector3(x / t, y / t, z / t);
}
//向量 /= 标量
Vector3& operator /= (float t)
{
//断言标量非零
assert(!(t >= -0.001f && t <= 0.001f));
x /= t;
y /= t;
z /= t;
return *this;
}
//点乘
float Dot(const Vector3& that) const
{
return x * that.x + y * that.y + z * that.z;
}
//叉乘
Vector3 Cross(const Vector3& that) const
{
Vector3 r;
r.x = y * that.z - z * that.y;
r.y = z * that.x - x * that.z;
r.z = x * that.y - y * that.x;
return r;
}
//投影
Vector3 Projection(const Vector3& that) const
{
//得到that向量长度的平方
float that_length_power2 = that.x * that.x + that.y * that.y + that.z * that.z;
//断言长度非零
assert(!(that_length_power2 >= -0.001f && that_length_power2 <= 0.001f));
//得到this点乘that的结果
float this_dot_that = x * that.x + y * that.y + z * that.z;
//得到比值
float temp = this_dot_that / that_length_power2;
//返回投影量
return Vector3(that.x * temp, that.y * temp, that.z * temp);
}
};
//标量 * 向量
inline Vector3 operator * (float num, const Vector3& vec)
{
return Vector3(num * vec.x, num * vec.y, num * vec.z);
}
#pragma once
#include "matrix3.h"
#include "vector3.h"
//11,12,13,14
//21,22,23,24
//31,32,33,34
//41,42,43,44
//此处的宏定义主要是为了读者能区分矩阵元素的位置
#define _M_11 0
#define _M_12 1
#define _M_13 2
#define _M_14 3
#define _M_21 4
#define _M_22 5
#define _M_23 6
#define _M_24 7
#define _M_31 8
#define _M_32 9
#define _M_33 10
#define _M_34 11
#define _M_41 12
#define _M_42 13
#define _M_43 14
#define _M_44 15
class Matrix4
{
public:
float m[16];
//构造
Matrix4()
{
Indentity();
}
//单位化
Matrix4& Indentity()
{
m[_M_11] = 1.0f; m[_M_12] = 0.0f; m[_M_13] = 0.0f; m[_M_14] = 0.0f;
m[_M_21] = 0.0f; m[_M_22] = 1.0f; m[_M_23] = 0.0f; m[_M_24] = 0.0f;
m[_M_31] = 0.0f; m[_M_32] = 0.0f; m[_M_33] = 1.0f; m[_M_34] = 0.0f;
m[_M_41] = 0.0f; m[_M_42] = 0.0f; m[_M_43] = 0.0f; m[_M_44] = 1.0f;
return *this;
}
//平移
Matrix4& Translate(float x, float y, float z)
{
m[_M_11] = 1.0f; m[_M_12] = 0.0f; m[_M_13] = 0.0f; m[_M_14] = 0.0f;
m[_M_21] = 0.0f; m[_M_22] = 1.0f; m[_M_23] = 0.0f; m[_M_24] = 0.0f;
m[_M_31] = 0.0f; m[_M_32] = 0.0f; m[_M_33] = 1.0f; m[_M_34] = 0.0f;
m[_M_41] = x; m[_M_42] = y; m[_M_43] = z; m[_M_44] = 1.0f;
return *this;
}
Matrix4& Translate(const Vector3& v)
{
m[_M_11] = 1.0f; m[_M_12] = 0.0f; m[_M_13] = 0.0f; m[_M_14] = 0.0f;
m[_M_21] = 0.0f; m[_M_22] = 1.0f; m[_M_23] = 0.0f; m[_M_24] = 0.0f;
m[_M_31] = 0.0f; m[_M_32] = 0.0f; m[_M_33] = 1.0f; m[_M_34] = 0.0f;
m[_M_41] = v.x; m[_M_42] = v.y; m[_M_43] = v.z; m[_M_44] = 1.0f;
return *this;
}
//缩放
Matrix4& Scale(float x, float y, float z)
{
m[_M_11] = x; m[_M_12] = 0.0f; m[_M_13] = 0.0f; m[_M_14] = 0.0f;
m[_M_21] = 0.0f; m[_M_22] = y; m[_M_23] = 0.0f; m[_M_24] = 0.0f;
m[_M_31] = 0.0f; m[_M_32] = 0.0f; m[_M_33] = z; m[_M_34] = 0.0f;
m[_M_41] = 0.0f; m[_M_42] = 0.0f; m[_M_43] = 0.0f; m[_M_44] = 1.0f;
return *this;
}
Matrix4& Scale(const Vector3& v)
{
m[_M_11] = v.x; m[_M_12] = 0.0f; m[_M_13] = 0.0f; m[_M_14] = 0.0f;
m[_M_21] = 0.0f; m[_M_22] = v.y; m[_M_23] = 0.0f; m[_M_24] = 0.0f;
m[_M_31] = 0.0f; m[_M_32] = 0.0f; m[_M_33] = v.z; m[_M_34] = 0.0f;
m[_M_41] = 0.0f; m[_M_42] = 0.0f; m[_M_43] = 0.0f; m[_M_44] = 1.0f;
return *this;
}
//绕x轴旋转
Matrix4& RotateX(float a)
{
float s = sin(a);
float c = cos(a);
m[_M_11] = 1.0f; m[_M_12] = 0.0f; m[_M_13] = 0.0f; m[_M_14] = 0.0f;
m[_M_21] = 0.0f; m[_M_22] = c; m[_M_23] = s; m[_M_24] = 0.0f;
m[_M_31] = 0.0f; m[_M_32] = -s; m[_M_33] = c; m[_M_34] = 0.0f;
m[_M_41] = 0.0f; m[_M_42] = 0.0f; m[_M_43] = 0.0f; m[_M_44] = 1.0f;
return *this;
}
//绕y轴旋转
Matrix4& RotateY(float a)
{
float s = sin(a);
float c = cos(a);
m[_M_11] = c; m[_M_12] = 0.0f; m[_M_13] = -s; m[_M_14] = 0.0f;
m[_M_21] = 0.0f; m[_M_22] = 1.0f; m[_M_23] = 0.0f; m[_M_24] = 0.0f;
m[_M_31] = s; m[_M_32] = 0.0f; m[_M_33] = c; m[_M_34] = 0.0f;
m[_M_41] = 0.0f; m[_M_42] = 0.0f; m[_M_43] = 0.0f; m[_M_44] = 1.0f;
return *this;
}
//绕z轴旋转
Matrix4& RotateZ(float a)
{
float s = sin(a);
float c = cos(a);
m[_M_11] = c; m[_M_12] = s; m[_M_13] = 0.0f; m[_M_14] = 0.0f;
m[_M_21] = -s; m[_M_22] = c; m[_M_23] = 0.0f; m[_M_24] = 0.0f;
m[_M_31] = 0.0f; m[_M_32] = 0.0f; m[_M_33] = 1.0f; m[_M_34] = 0.0f;
m[_M_41] = 0.0f; m[_M_42] = 0.0f; m[_M_43] = 0.0f; m[_M_44] = 1.0f;
return *this;
}
//绕过原点指定轴旋转
Matrix4& Rotate(const Vector3& n, float a)
{
//单位化指定轴向量
Vector3 any_nomalize = n.Normalize();
//处理数据
float xx = any_nomalize.x * any_nomalize.x;
float yy = any_nomalize.y * any_nomalize.y;
float zz = any_nomalize.z * any_nomalize.z;
float xy = any_nomalize.x * any_nomalize.y;
float yz = any_nomalize.y * any_nomalize.z;
float zx = any_nomalize.z * any_nomalize.x;
float c = cos(a);
float one_sub_c = 1.0f - c;
float s = sin(a);
m[_M_11] = xx * one_sub_c + c;
m[_M_12] = xy * one_sub_c + any_nomalize.z * s;
m[_M_13] = zx * one_sub_c - any_nomalize.y * s;
m[_M_14] = 0.0f;
m[_M_21] = xy * one_sub_c - any_nomalize.z * s;
m[_M_22] = yy * one_sub_c + c;
m[_M_23] = yz * one_sub_c + any_nomalize.x * s;
m[_M_24] = 0.0f;
m[_M_31] = zx * one_sub_c + any_nomalize.y * s;
m[_M_32] = yz * one_sub_c - any_nomalize.x * s;
m[_M_33] = zz * one_sub_c + c;
m[_M_34] = 0.0f;
m[_M_41] = 0.0f;
m[_M_42] = 0.0f;
m[_M_43] = 0.0f;
m[_M_44] = 1.0f;
return *this;
}
};
inline Vector3* v3_x_M(const Vector3* v, const Matrix4* u, Vector3* r)
{
float temp[] =
{
v->x * u->m[_M_11] + v->y * u->m[_M_21] + v->z * u->m[_M_31] + u->m[_M_41],
v->x * u->m[_M_12] + v->y * u->m[_M_22] + v->z * u->m[_M_32] + u->m[_M_42],
v->x * u->m[_M_13] + v->y * u->m[_M_23] + v->z * u->m[_M_33] + u->m[_M_43],
v->x * u->m[_M_14] + v->y * u->m[_M_24] + v->z * u->m[_M_34] + u->m[_M_44],
};
r->x = temp[0] / temp[3];
r->y = temp[1] / temp[3];
r->z = temp[2] / temp[3];
return r;
}
inline Vector3 operator * (const Vector3& v, const Matrix4& m)
{
Vector3 r;
return *v3_x_M(&v, &m, &r);
}
inline Matrix4* M_x_M(const Matrix4* m1, const Matrix4* m2, Matrix4* r)
{
r->m[_M_11] =
m1->m[_M_11] * m2->m[_M_11] +
m1->m[_M_12] * m2->m[_M_21] +
m1->m[_M_13] * m2->m[_M_31] +
m1->m[_M_14] * m2->m[_M_41];
r->m[_M_12] =
m1->m[_M_11] * m2->m[_M_12] +
m1->m[_M_12] * m2->m[_M_22] +
m1->m[_M_13] * m2->m[_M_32] +
m1->m[_M_14] * m2->m[_M_42];
r->m[_M_13] =
m1->m[_M_11] * m2->m[_M_13] +
m1->m[_M_12] * m2->m[_M_23] +
m1->m[_M_13] * m2->m[_M_33] +
m1->m[_M_14] * m2->m[_M_43];
r->m[_M_14] =
m1->m[_M_11] * m2->m[_M_14] +
m1->m[_M_12] * m2->m[_M_24] +
m1->m[_M_13] * m2->m[_M_34] +
m1->m[_M_14] * m2->m[_M_44];
r->m[_M_21] =
m1->m[_M_21] * m2->m[_M_11] +
m1->m[_M_22] * m2->m[_M_21] +
m1->m[_M_23] * m2->m[_M_31] +
m1->m[_M_24] * m2->m[_M_41];
r->m[_M_22] =
m1->m[_M_21] * m2->m[_M_12] +
m1->m[_M_22] * m2->m[_M_22] +
m1->m[_M_23] * m2->m[_M_32] +
m1->m[_M_24] * m2->m[_M_42];
r->m[_M_23] =
m1->m[_M_21] * m2->m[_M_13] +
m1->m[_M_22] * m2->m[_M_23] +
m1->m[_M_23] * m2->m[_M_33] +
m1->m[_M_24] * m2->m[_M_43];
r->m[_M_24] =
m1->m[_M_21] * m2->m[_M_14] +
m1->m[_M_22] * m2->m[_M_24] +
m1->m[_M_23] * m2->m[_M_34] +
m1->m[_M_24] * m2->m[_M_44];
r->m[_M_31] =
m1->m[_M_31] * m2->m[_M_11] +
m1->m[_M_32] * m2->m[_M_21] +
m1->m[_M_33] * m2->m[_M_31] +
m1->m[_M_34] * m2->m[_M_41];
r->m[_M_32] =
m1->m[_M_31] * m2->m[_M_12] +
m1->m[_M_32] * m2->m[_M_22] +
m1->m[_M_33] * m2->m[_M_32] +
m1->m[_M_34] * m2->m[_M_42];
r->m[_M_33] =
m1->m[_M_31] * m2->m[_M_13] +
m1->m[_M_32] * m2->m[_M_23] +
m1->m[_M_33] * m2->m[_M_33] +
m1->m[_M_34] * m2->m[_M_43];
r->m[_M_34] =
m1->m[_M_31] * m2->m[_M_14] +
m1->m[_M_32] * m2->m[_M_24] +
m1->m[_M_33] * m2->m[_M_34] +
m1->m[_M_34] * m2->m[_M_44];
r->m[_M_41] =
m1->m[_M_41] * m2->m[_M_11] +
m1->m[_M_42] * m2->m[_M_21] +
m1->m[_M_43] * m2->m[_M_31] +
m1->m[_M_44] * m2->m[_M_41];
r->m[_M_42] =
m1->m[_M_41] * m2->m[_M_12] +
m1->m[_M_42] * m2->m[_M_22] +
m1->m[_M_43] * m2->m[_M_32] +
m1->m[_M_44] * m2->m[_M_42];
r->m[_M_43] =
m1->m[_M_41] * m2->m[_M_13] +
m1->m[_M_42] * m2->m[_M_23] +
m1->m[_M_43] * m2->m[_M_33] +
m1->m[_M_44] * m2->m[_M_43];
r->m[_M_44] =
m1->m[_M_41] * m2->m[_M_14] +
m1->m[_M_42] * m2->m[_M_24] +
m1->m[_M_43] * m2->m[_M_34] +
m1->m[_M_44] * m2->m[_M_44];
return r;
}
inline Matrix4 operator * (const Matrix4& m1, const Matrix4& m2)
{
Matrix4 r;
return *M_x_M(&m1, &m2, &r);
}