三维矩阵当中,绕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);
}
//向量 /= 标