4x4矩陣教程

4x4矩陣教程

1. 簡介

四維矩陣是計算機圖形學和3D變換中的重要工具,用于表示三維空間中的仿射變換。本教程將介紹如何使用C++實現四維矩陣的基本運算和變換。

2. 代碼實現

2.1 頭文件 (matrix4x4.h)

#ifndef MATRIX4X4_H
#define MATRIX4X4_H#include <array>
#include <stdexcept>
#include <iostream>namespace math {
namespace linear_algebra {/*** @brief 四維矩陣類* * 這個類實現了四維矩陣的基本運算,包括:* - 矩陣加減* - 矩陣乘法* - 標量乘法* - 行列式計算* - 矩陣求逆* - 矩陣轉置* - 特征值和特征向量計算* - 矩陣性質檢查(可逆性、對稱性、正交性)* - 特殊矩陣生成(旋轉矩陣、縮放矩陣、平移矩陣、投影矩陣等)*/
class Matrix4x4 {
public:// 構造函數Matrix4x4();  // 默認構造函數,初始化為單位矩陣Matrix4x4(const std::array<std::array<double, 4>, 4>& data);  // 從二維數組初始化// 基本運算Matrix4x4 operator+(const Matrix4x4& other) const;  // 矩陣加法Matrix4x4 operator-(const Matrix4x4& other) const;  // 矩陣減法Matrix4x4 operator*(const Matrix4x4& other) const;  // 矩陣乘法Matrix4x4 operator*(double scalar) const;           // 標量乘法Matrix4x4 operator/(double scalar) const;           // 標量除法// 矩陣運算double determinant() const;                         // 計算行列式Matrix4x4 inverse() const;                          // 計算逆矩陣Matrix4x4 transpose() const;                        // 計算轉置矩陣std::array<double, 4> eigenvalues() const;          // 計算特征值std::array<Matrix4x4, 4> eigenvectors() const;      // 計算特征向量// 矩陣性質bool isInvertible() const;                          // 檢查是否可逆bool isSymmetric() const;                           // 檢查是否對稱bool isOrthogonal() const;                          // 檢查是否正交// 特殊矩陣static Matrix4x4 identity();                        // 創建單位矩陣static Matrix4x4 rotation(double theta, char axis); // 創建旋轉矩陣static Matrix4x4 scaling(double sx, double sy, double sz); // 創建縮放矩陣static Matrix4x4 translation(double tx, double ty, double tz); // 創建平移矩陣static Matrix4x4 perspective(double fov, double aspect, double near, double far); // 創建透視投影矩陣static Matrix4x4 orthographic(double left, double right, double bottom, double top, double near, double far); // 創建正交投影矩陣// 輸出運算符friend std::ostream& operator<<(std::ostream& os, const Matrix4x4& m);private:std::array<std::array<double, 4>, 4> data;  // 4x4矩陣數據
};} // namespace linear_algebra
} // namespace math#endif // MATRIX4X4_H

2.2 實現文件 (matrix4x4.cpp)

#include "matrix4x4.h"
#include <cmath>namespace math {
namespace linear_algebra {// 默認構造函數:初始化為單位矩陣
Matrix4x4::Matrix4x4() {for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {data[i][j] = (i == j) ? 1.0 : 0.0;}}
}// 從二維數組初始化
Matrix4x4::Matrix4x4(const std::array<std::array<double, 4>, 4>& data) : data(data) {}// 矩陣加法實現
Matrix4x4 Matrix4x4::operator+(const Matrix4x4& other) const {Matrix4x4 result;for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = data[i][j] + other.data[i][j];}}return result;
}// 矩陣減法實現
Matrix4x4 Matrix4x4::operator-(const Matrix4x4& other) const {Matrix4x4 result;for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = data[i][j] - other.data[i][j];}}return result;
}// 矩陣乘法實現
Matrix4x4 Matrix4x4::operator*(const Matrix4x4& other) const {Matrix4x4 result;for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = 0.0;for (int k = 0; k < 4; ++k) {result.data[i][j] += data[i][k] * other.data[k][j];}}}return result;
}// 標量乘法實現
Matrix4x4 Matrix4x4::operator*(double scalar) const {Matrix4x4 result;for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = data[i][j] * scalar;}}return result;
}// 標量除法實現
Matrix4x4 Matrix4x4::operator/(double scalar) const {if (scalar == 0.0) {throw std::runtime_error("Division by zero");}return *this * (1.0 / scalar);
}// 行列式計算實現
double Matrix4x4::determinant() const {// 使用拉普拉斯展開計算4x4矩陣的行列式double det = 0.0;for (int i = 0; i < 4; ++i) {double cofactor = 0.0;for (int j = 0; j < 4; ++j) {if ((i + j) % 2 == 0) {cofactor += data[0][j] * minor(0, j);} else {cofactor -= data[0][j] * minor(0, j);}}det += data[0][i] * cofactor;}return det;
}// 逆矩陣計算實現
Matrix4x4 Matrix4x4::inverse() const {double det = determinant();if (det == 0.0) {throw std::runtime_error("Matrix is not invertible");}Matrix4x4 result;double invDet = 1.0 / det;// 計算伴隨矩陣for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = cofactor(j, i) * invDet;}}return result;
}// 轉置矩陣實現
Matrix4x4 Matrix4x4::transpose() const {Matrix4x4 result;for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {result.data[i][j] = data[j][i];}}return result;
}// 特征值計算實現
std::array<double, 4> Matrix4x4::eigenvalues() const {// 計算特征多項式系數// 這里使用簡化的方法,實際應用中可能需要更復雜的數值方法std::array<double, 4> roots;// ... 求解四次方程的代碼 ...return roots;
}// 特征向量計算實現
std::array<Matrix4x4, 4> Matrix4x4::eigenvectors() const {std::array<double, 4> eigenvals = eigenvalues();std::array<Matrix4x4, 4> eigenvecs;// ... 計算特征向量的代碼 ...return eigenvecs;
}// 可逆性檢查實現
bool Matrix4x4::isInvertible() const {return determinant() != 0.0;
}// 對稱性檢查實現
bool Matrix4x4::isSymmetric() const {for (int i = 0; i < 4; ++i) {for (int j = i + 1; j < 4; ++j) {if (data[i][j] != data[j][i]) {return false;}}}return true;
}// 正交性檢查實現
bool Matrix4x4::isOrthogonal() const {Matrix4x4 product = *this * transpose();Matrix4x4 identity = Matrix4x4::identity();for (int i = 0; i < 4; ++i) {for (int j = 0; j < 4; ++j) {if (std::abs(product.data[i][j] - identity.data[i][j]) > 1e-10) {return false;}}}return true;
}// 單位矩陣創建實現
Matrix4x4 Matrix4x4::identity() {return Matrix4x4();
}// 旋轉矩陣創建實現
Matrix4x4 Matrix4x4::rotation(double theta, char axis) {Matrix4x4 result;double cos_theta = std::cos(theta);double sin_theta = std::sin(theta);switch (axis) {case 'x':result.data[1][1] = cos_theta;result.data[1][2] = -sin_theta;result.data[2][1] = sin_theta;result.data[2][2] = cos_theta;break;case 'y':result.data[0][0] = cos_theta;result.data[0][2] = sin_theta;result.data[2][0] = -sin_theta;result.data[2][2] = cos_theta;break;case 'z':result.data[0][0] = cos_theta;result.data[0][1] = -sin_theta;result.data[1][0] = sin_theta;result.data[1][1] = cos_theta;break;default:throw std::runtime_error("Invalid rotation axis");}return result;
}// 縮放矩陣創建實現
Matrix4x4 Matrix4x4::scaling(double sx, double sy, double sz) {Matrix4x4 result;result.data[0][0] = sx;result.data[1][1] = sy;result.data[2][2] = sz;return result;
}// 平移矩陣創建實現
Matrix4x4 Matrix4x4::translation(double tx, double ty, double tz) {Matrix4x4 result;result.data[0][3] = tx;result.data[1][3] = ty;result.data[2][3] = tz;return result;
}// 透視投影矩陣創建實現
Matrix4x4 Matrix4x4::perspective(double fov, double aspect, double near, double far) {Matrix4x4 result;double tan_half_fov = std::tan(fov / 2.0);result.data[0][0] = 1.0 / (aspect * tan_half_fov);result.data[1][1] = 1.0 / tan_half_fov;result.data[2][2] = -(far + near) / (far - near);result.data[2][3] = -1.0;result.data[3][2] = -(2.0 * far * near) / (far - near);result.data[3][3] = 0.0;return result;
}// 正交投影矩陣創建實現
Matrix4x4 Matrix4x4::orthographic(double left, double right, double bottom, double top, double near, double far) {Matrix4x4 result;result.data[0][0] = 2.0 / (right - left);result.data[1][1] = 2.0 / (top - bottom);result.data[2][2] = -2.0 / (far - near);result.data[0][3] = -(right + left) / (right - left);result.data[1][3] = -(top + bottom) / (top - bottom);result.data[2][3] = -(far + near) / (far - near);return result;
}// 輸出運算符實現
std::ostream& operator<<(std::ostream& os, const Matrix4x4& m) {for (int i = 0; i < 4; ++i) {os << "[ ";for (int j = 0; j < 4; ++j) {os << m.data[i][j] << " ";}os << "]" << std::endl;}return os;
}} // namespace linear_algebra
} // namespace math

3. 使用示例

3.1 基本運算

#include "matrix4x4.h"
#include <iostream>using namespace math::linear_algebra;int main() {// 創建矩陣Matrix4x4 m1({{{1.0, 2.0, 3.0, 4.0},{5.0, 6.0, 7.0, 8.0},{9.0, 10.0, 11.0, 12.0},{13.0, 14.0, 15.0, 16.0}}});Matrix4x4 m2({{{16.0, 15.0, 14.0, 13.0},{12.0, 11.0, 10.0, 9.0},{8.0, 7.0, 6.0, 5.0},{4.0, 3.0, 2.0, 1.0}}});// 基本運算Matrix4x4 sum = m1 + m2;      // 矩陣加法Matrix4x4 diff = m1 - m2;     // 矩陣減法Matrix4x4 prod = m1 * m2;     // 矩陣乘法Matrix4x4 scaled = m1 * 2.0;  // 標量乘法// 輸出結果std::cout << "m1:\n" << m1 << std::endl;std::cout << "m2:\n" << m2 << std::endl;std::cout << "m1 + m2:\n" << sum << std::endl;std::cout << "m1 - m2:\n" << diff << std::endl;std::cout << "m1 * m2:\n" << prod << std::endl;std::cout << "m1 * 2:\n" << scaled << std::endl;return 0;
}

3.2 3D變換

#include "matrix4x4.h"
#include <iostream>
#include <cmath>using namespace math::linear_algebra;int main() {// 創建變換矩陣Matrix4x4 rotation = Matrix4x4::rotation(M_PI / 4.0, 'z');  // 繞Z軸旋轉45度Matrix4x4 scaling = Matrix4x4::scaling(2.0, 3.0, 4.0);      // 縮放Matrix4x4 translation = Matrix4x4::translation(1.0, 2.0, 3.0); // 平移// 組合變換(注意順序:先縮放,再旋轉,最后平移)Matrix4x4 transform = translation * rotation * scaling;// 創建投影矩陣Matrix4x4 perspective = Matrix4x4::perspective(M_PI / 4.0, 16.0/9.0, 0.1, 100.0);Matrix4x4 ortho = Matrix4x4::orthographic(-1.0, 1.0, -1.0, 1.0, 0.1, 100.0);// 輸出結果std::cout << "旋轉矩陣:\n" << rotation << std::endl;std::cout << "縮放矩陣:\n" << scaling << std::endl;std::cout << "平移矩陣:\n" << translation << std::endl;std::cout << "組合變換:\n" << transform << std::endl;std::cout << "透視投影:\n" << perspective << std::endl;std::cout << "正交投影:\n" << ortho << std::endl;return 0;
}

4. 編譯和運行

4.1 編譯

使用提供的Makefile進行編譯:

make        # 編譯所有目標
make test   # 運行測試
make demo   # 運行示例
make clean  # 清理編譯文件

4.2 運行測試

./matrix4x4_test

4.3 運行示例

./matrix4x4_demo

5. 注意事項

  1. 數值精度

    • 在比較浮點數時使用適當的誤差范圍
    • 例如:std::abs(det) < 1e-10 判斷是否可逆
  2. 異常處理

    • 除以零的情況
    • 不可逆矩陣求逆的情況
    • 無效的旋轉軸
    • 投影參數的有效性檢查
  3. 性能考慮

    • 矩陣乘法的時間復雜度為O(n3)
    • 特征值計算可能需要迭代方法
    • 考慮使用SIMD指令優化計算
    • 投影矩陣的預計算
  4. 使用建議

    • 優先使用成員函數而不是全局函數
    • 保持接口的一致性
    • 提供清晰的錯誤信息
    • 注意變換矩陣的組合順序

6. 擴展閱讀

  1. 線性代數基礎

    • 矩陣運算
    • 行列式
    • 特征值和特征向量
  2. 3D變換

    • 旋轉矩陣
    • 縮放矩陣
    • 平移矩陣
    • 投影矩陣
  3. 應用領域

    • 計算機圖形學
    • 3D游戲開發
    • 計算機視覺
    • 機器人學
    • 物理模擬

    聲明

該文章為學習過程中的筆記,目的是防止自己忘記,也為了方便隨時隨地查閱。其中大部分內容收集于互聯網。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89965.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89965.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89965.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Oracle 數據庫共享池與大池調優指南

在 Oracle 數據庫的內存管理中&#xff0c;共享池&#xff08;Shared Pool&#xff09;和大池&#xff08;Large Pool&#xff09;是 SGA&#xff08;系統全局區&#xff09;中負責緩存與資源分配的核心組件。合理配置和調優這兩個池&#xff0c;能顯著提升數據庫性能 —— 尤其…

C# Lambdab表達式 Var 類

Lambdab 是用于創建一個方法的表達式Func<參數1類型, 參數2類型, 返回值類型> fnName >(參數1 參數2) {方法代碼體}Func<int, int, bool> fnName (int a, int b) > {return a > b; };//調用時和普通方法一致 Console.WriteLine(fnName(10,20)); // false…

【Python】常見模塊及其用法

文章目錄1. 什么是模塊和包&#xff1f;2. 常見的模塊及其用法2.1 time概覽2.1.1 時間獲取方法2.1.2 時間格式化與解析2.1.3 程序計時與延遲2.1.4 時間轉換2.2 random概覽2.2.1 基本隨機數2.2.2 隨機整數2.2.3 序列操作2.2.4 概率分布2.2.5 隨機種子2.2.6 狀態管理2.3 os概覽2.…

洛谷 P3478 [POI 2008] STA-Station

【題目鏈接】 洛谷 P3478 [POI 2008] STA-Station 【題目考點】 1. 樹形動規&#xff1a;換根動規 換根動規&#xff0c;又名二次掃描法&#xff0c;一般是給一顆不定根樹&#xff0c;通過兩次掃描來求解。 我們可以先任選一個根結點root&#xff0c;通過樹形動規的思想計算…

【爬蟲】03 - 爬蟲的基本數據存儲

爬蟲03 - 爬蟲的數據存儲 文章目錄爬蟲03 - 爬蟲的數據存儲一&#xff1a;CSV數據存儲1&#xff1a;基本介紹2&#xff1a;基本使用3&#xff1a;高級使用4&#xff1a;使用示例二&#xff1a;JSON數據存儲1&#xff1a;基礎json讀寫2&#xff1a;字符串和對象的轉換3&#xff…

深入分析計算機網絡數據鏈路層和網絡層面試題

計算機網絡體系結構1. 請簡述 OSI 七層模型和 TCP/IP 四層模型&#xff0c;并比較它們的異同。OSI 七層模型&#xff1a;應用層&#xff1a;直接為用戶的應用進程提供服務&#xff0c;如 HTTP&#xff08;超文本傳輸協議&#xff0c;用于 Web 瀏覽器與服務器通信&#xff09;、…

云服務器新裝的mysql8,無法通過遠程連接,然后本地pymysql也連不上

阿里云服務器&#xff0c;用apt-get新裝的mysql-server&#xff0c;竟然無法通過遠程連接到&#xff0c;竟然是這個原因。不是防火墻&#xff0c;iptables早就關了。也不是安全組&#xff0c;不是人為限制訪問的話&#xff0c;根本沒必要弄安全組 排查過程 netstat -antop|grep…

質量即服務:從測試策略到平臺運營的全鏈路作戰手冊

&#xff08;零&#xff09;為什么需要“質量即服務” 當業務方說“今晚一定要上線”&#xff0c; 當開發說“我只改了兩行代碼”&#xff0c; 當運維說“回滾窗口只有 5 分鐘”&#xff0c; 質量必須像水電一樣隨取隨用&#xff0c;而不是上線前的大壩泄洪。 這篇手冊提供一張…

Java -- 自定義異常--Wrapper類--String類

自定義異常&#xff1a;概念&#xff1a;當程序中出現了某些錯誤&#xff0c;但該錯誤信息并沒有在Throwable子類中描述處理&#xff0c;這個時候可以自己設計異常&#xff0c;用于描述該錯誤信息。步驟&#xff1a;1. 定義類&#xff1a;自定義異常類名&#xff08;程序員自己…

一文速通《線性方程組》

目錄 一、解題必記知識點 二、解題必備技巧 三、非齊次線性方程組求解 四、齊次線性方程組求解 ★五、解析題目信息&#xff0c;獲取暗含條件 一、解題必記知識點 (1) (2)基礎解系線性無關&#xff0c;基礎解系 解空間的一個基&#xff0c;基 一組線性無關的、能夠生…

【Django】DRF API版本和解析器

講解 Python3 下 Django REST Framework (DRF) API 版本控制解析器&#xff08;Parser&#xff09;一、DRF API 版本控制詳解 API 版本控制是構建健壯、可維護的 RESTful API 的關鍵&#xff0c;尤其在項目演進中需要兼容不同版本的客戶端請求。 1.1 API 版本控制的核心原理 AP…

Windows系統暫停更新工具

功能說明 暫停更新至2999年恢復系統更新徹底禁用更新&#xff08;不可逆&#xff09; 使用方法 下載解壓后雙擊運行 .bat 文件 輸入數字選擇功能&#xff1a; 輸入 1&#xff1a;暫停更新至2999年&#xff08;推薦&#xff09;輸入 2&#xff1a;恢復系統更新輸入 3&#xf…

git push新版問題解決

git 好像不能通過username:password的方式來git push了。但我的電腦依然彈出username和password的彈窗。轉戰ssh來git push。由于之前是用git clone克隆的&#xff0c;需要再轉換成ssh的url來git push。

PyCharm + AI 輔助編程

PyCharm AI&#xff1a;初學者友好的 2 個實用場景&#xff08;附操作步驟&#xff09; PyCharm 專業版&#xff08;或通過插件集成&#xff09;支持 AI 輔助編程&#xff08;如 JetBrains AI 或 GitHub Copilot&#xff09;&#xff0c;能根據代碼上下文自動生成代碼、解釋邏…

瘋狂星期四文案網第15天運營日記

網站運營第15天&#xff0c;點擊觀站&#xff1a; 瘋狂星期四 crazy-thursday.com 全網最全的瘋狂星期四文案網站 運營報告 昨日訪問量 昨天只有20來ip, 太慘了&#xff0c;感覺和最近沒有發新段子有關&#xff0c;也沒有發新的外鏈&#xff0c;不知道這周四會怎么樣 昨日搜…

如何解決pip安裝報錯ModuleNotFoundError: No module named ‘Cython’問題

【Python系列Bug修復PyCharm控制臺pip install報錯】如何解決pip安裝報錯ModuleNotFoundError: No module named ‘Cython’問題 摘要 在使用 PyCharm 控制臺或命令行執行 pip install Cython 時&#xff0c;常會遇到 ModuleNotFoundError: No module named Cython 的報錯。本…

freertos任務調度關鍵函數理解 vTaskSwitchContext

void vTaskSwitchContext(void) {//my_printf( "uxSchedulerSuspended %d\n", uxSchedulerSuspended );/* 調度器處于掛起狀態 */if (uxSchedulerSuspended ! (UBaseType_t)pdFALSE) {/*** The scheduler is currently suspended - do not allow a context* switch.…

CPU 密集型 和 I/O 密集型 任務

文章目錄**CPU 密集型任務&#xff08;CPU-bound&#xff09;**定義&#xff1a;特點&#xff1a;常見場景&#xff1a;如何優化 CPU 密集型任務&#xff1a;**I/O 密集型任務&#xff08;I/O-bound&#xff09;**定義&#xff1a;特點&#xff1a;常見場景&#xff1a;如何優化…

[2025CVPR-小目標檢測方向]基于特征信息驅動位置高斯分布估計微小目標檢測模型

核心問題 ?小目標檢測性能差&#xff1a;?? 盡管通用目標檢測器&#xff08;如 Faster R-CNN, YOLO, SSD&#xff09;在常規目標上表現出色&#xff0c;但在檢測微小目標&#xff08;如 AI-TOD 基準定義的&#xff1a;非常小目標 2-8 像素&#xff0c;小目標 8-16 像素&…

三大工廠設計模式

1.簡單工廠模式1.1需求入手從需求進行入手&#xff0c;可以更深入的理解什么是設計模式。有一個制作披薩的需求&#xff1a;需要便于擴展披薩的種類&#xff0c;便于維護。1.披薩的種類有很多&#xff1a;GreekPizz&#xff0c;CheesePizz等2.披薩的制作流程&#xff1a;prepar…