3D数学方阵、转置矩阵、矩阵运算及坐标系转换详解
1. 方阵基础
方阵是行数等于列数的矩阵,在3D图形学中扮演着至关重要的角色,特别是在表示空间变换和坐标系转换方面。
1.1 方阵的定义与特性
方阵是一个n×n的矩阵,即具有相同的行数和列数。
cpp
// 通用方阵类模板
template <int N>
class SquareMatrix {
private:
float elements[N][N];
public:
// 默认构造函数:创建零矩阵
SquareMatrix() {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
elements[i][j] = 0.0f;
}
}
}
// 构造单位矩阵
static SquareMatrix<N> identity() {
SquareMatrix<N> result;
for (int i = 0; i < N; i++) {
result.elements[i][i] = 1.0f;
}
return result;
}
// 访问元素
float& operator()(int row, int col) {
return elements[row][col];
}
float operator()(int row, int col) const {
return elements[row][col];
}
// 打印矩阵
void print() const {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
std::cout << elements[i][j] << "\t";
}
std::cout << std::endl;
}
}
};
// 常用的3D方阵类型定义
using Matrix2x2 = SquareMatrix<2>;
using Matrix3x3 = SquareMatrix<3>;
using Matrix4x4 = SquareMatrix<4>;
1.2 方阵的特殊类型
在3D图形学中,最常用的方阵有以下几种特殊类型:
1.2.1 单位矩阵(Identity Matrix)
对角线元素为1,其他元素为0的方阵。它是矩阵乘法的单位元素,任何矩阵与单位矩阵相乘保持不变。
cpp
// 创建单位矩阵
template <int N>
SquareMatrix<N> createIdentityMatrix() {
return SquareMatrix<N>::identity();
}
// 检查是否为单位矩阵
template <int N>
bool isIdentityMatrix(const SquareMatrix<N>& matrix, float epsilon = 1e-5f) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
float expected = (i == j) ? 1.0f : 0.0f;
if (fabs(matrix(i, j) - expected) > epsilon) {
return false;
}
}
}
return true;
}
1.2.2 对角矩阵(Diagonal Matrix)
只有对角线上的元素可能非零,其他元素都为0的方阵。
cpp
// 创建对角矩阵
template <int N>
SquareMatrix<N> createDiagonalMatrix(const float* diagonal) {
SquareMatrix<N> result;
for (int i = 0; i < N; i++) {
result(i, i) = diagonal[i];
}
return result;
}
// 检查是否为对角矩阵
template <int N>
bool isDiagonalMatrix(const SquareMatrix<N>& matrix, float epsilon = 1e-5f) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (i != j && fabs(matrix(i, j)) > epsilon) {
return false;
}
}
}
return true;
}
1.2.3 三角矩阵(Triangular Matrix)
上三角矩阵或下三角矩阵只有对角线及以上或以下的元素可能非零。
cpp
// 检查是否为上三角矩阵
template <int N>
bool isUpperTriangular(const SquareMatrix<N>& matrix, float epsilon = 1e-5f) {
for (int i = 1; i < N; i++) {
for (int j = 0; j < i; j++) {
if (fabs(matrix(i, j)) > epsilon) {
return false;
}
}
}
return true;
}
// 检查是否为下三角矩阵
template <int N>
bool isLowerTriangular(const SquareMatrix<N>& matrix, float epsilon = 1e-5f) {
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
if (fabs(matrix(i, j)) > epsilon) {
return false;
}
}
}
return true;
}
1.2.4 正交矩阵(Orthogonal Matrix)
满足A·A^T = I的矩阵,即其转置等于其逆。在3D图形学中,旋转矩阵是正交矩阵的重要例子。
cpp
// 检查是否为正交矩阵
template <int N>
bool isOrthogonalMatrix(const SquareMatrix<N>& matrix, float epsilon = 1e-5f) {
// 计算 M·M^T
SquareMatrix<N> result = multiplyMatrices(matrix, transposeMatrix(matrix));
// 检查结果是否接近单位矩阵
return isIdentityMatrix(result, epsilon);
}
2. 转置矩阵
转置矩阵是将原矩阵的行与列互换得到的新矩阵。在3D图形学中,转置操作常用于各种矩阵变换。
2.1 转置矩阵的定义
对于矩阵A,其转置矩阵A^T满足A^T[i][j] = A[j][i]。
cpp
// 计算矩阵的转置
template <int M, int N>
Matrix<N, M> transposeMatrix(const Matrix<M, N>& matrix) {
Matrix<N, M> result;
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
result(j, i) = matrix(i, j);
}
}
return result;
}
// 方阵的转置
template <int N>
SquareMatrix<N> transposeMatrix(const SquareMatrix<N>& matrix) {
SquareMatrix<N> result;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
result(j, i) = matrix(i, j);
}
}
return result;
}
2.2 转置矩阵的性质
转置矩阵具有许多重要性质:
- (A^T)^T = A
- (A + B)^T = A^T + B^T
- (AB)^T = B^T·A^T(注意乘法顺序反转)
- 对于正交矩阵,A^T = A^(-1)
cpp
// 验证转置的乘法性质:(AB)^T = B^T·A^T
template <int M, int N, int P>
bool verifyTransposeMultiplicationProperty(const Matrix<M, N>& A, const Matrix<N, P>& B) {
Matrix<M, P> AB = multiplyMatrices(A, B);
Matrix<P, M> ABtranspose = transposeMatrix(AB);
Matrix<P, N> Btranspose = transposeMatrix(B);
Matrix<N, M> Atranspose = transposeMatrix(A);
Matrix<P, M> BtAtranspose = multiplyMatrices(Btranspose, Atranspose);
// 比较两个结果是否相等
for (int i = 0; i < P; i++) {
for (int j = 0; j < M; j++) {
if (fabs(ABtranspose(i, j) - BtAtranspose(i, j)) > 1e-5f) {
return false;
}
}
}
return true;
}
2.3 转置在3D图形学中的应用
在3D图形学中,转置操作常用于:
- 计算旋转矩阵的逆(对于正交矩阵)
- 将法线向量从模型空间变换到世界空间(需要使用模型矩阵的逆转置)
- 优化某些矩阵计算
cpp
// 使用转置计算正交矩阵的逆
Matrix3x3 calculateInverseRotationMatrix(const Matrix3x3& rotationMatrix) {
// 验证是否为正交矩阵
if (!isOrthogonalMatrix(rotationMatrix)) {
throw std::runtime_error("Matrix is not orthogonal");
}
// 正交矩阵的逆等于其转置
return transposeMatrix(rotationMatrix);
}
// 计算法线变换矩阵(模型矩阵的逆转置)
Matrix3x3 calculateNormalMatrix(const Matrix4x4& modelMatrix) {
// 提取模型矩阵的3x3部分(不包含平移)
Matrix3x3 modelRotScale;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
modelRotScale(i, j) = modelMatrix(i, j);
}
}
// 计算逆矩阵
Matrix3x3 inverse = calculateInverseMatrix(modelRotScale);
// 返回逆矩阵的转置
return transposeMatrix(inverse);
}
3. 矩阵的运算
矩阵运算是3D图形学的基础,包括加减法、乘法和求逆等操作。
3.1 矩阵加法和减法
相同维度的矩阵可以相