簡單渲染流水管線C++代碼實現(六)---繞任意過原點的軸旋轉矩陣

三維矩陣當中,繞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);
}
發佈了19 篇原創文章 · 獲贊 16 · 訪問量 1202
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章