3D空間中的變換矩陣

3D 空間中的變換矩陣詳解

在 3D 計算機圖形學中,所有幾何變換都可以通過 4×4 齊次變換矩陣 來表示。以下詳細介紹各種變換矩陣及其原理。

核心變換矩陣

1. 單位矩陣(不變變換)

I=[1000010000100001] I = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} I=?1000?0100?0010?0001??

2. 平移矩陣(Translation)

將點 p=[x,y,z,1]T\mathbf{p} = [x, y, z, 1]^Tp=[x,y,z,1]T 沿向量 t=[tx,ty,tz]\mathbf{t} = [t_x, t_y, t_z]t=[tx?,ty?,tz?] 移動:

T=[100tx010ty001tz0001] T = \begin{bmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{bmatrix} T=?1000?0100?0010?tx?ty?tz?1??

變換后坐標:
p′=T?p=[x+tx,y+ty,z+tz,1]T p' = T \cdot p = [x+t_x, y+t_y, z+t_z, 1]^T p=T?p=[x+tx?,y+ty?,z+tz?,1]T

T逆矩陣:將 (tx,ty,tz)(t_x,t_y,t_z)(tx?,ty?,tz?) 取負

3. 縮放矩陣(Scaling)

沿坐標軸縮放,縮放因子 (sx,sy,sz)(s_x, s_y, s_z)(sx?,sy?,sz?)

S=[sx0000sy0000sz00001] S = \begin{bmatrix} s_x & 0 & 0 & 0 \\ 0 & s_y & 0 & 0 \\ 0 & 0 & s_z & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} S=?sx?000?0sy?00?00sz?0?0001??

特殊類型:

  • 均勻縮放sx=sy=szs_x = s_y = s_zsx?=sy?=sz?
  • 鏡像:某個分量為負(如 sx=?1s_x = -1sx?=?1
    逆矩陣:使用 (1/sx,1/sy,1/sz)(1/s_x,1/s_y,1/s_z)(1/sx?,1/sy?,1/sz?)(假設因子不為0)。

4. 旋轉矩陣(Rotation)

a) 繞坐標軸旋轉
旋轉軸矩陣
X軸Rx(θ)=[10000cos?θ?sin?θ00sin?θcos?θ00001]R_x(\theta) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta & 0 \\ 0 & \sin\theta & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}Rx?(θ)=?1000?0cosθsinθ0?0?sinθcosθ0?0001??
Y軸Ry(θ)=[cos?θ0sin?θ00100?sin?θ0cos?θ00001]R_y(\theta) = \begin{bmatrix} \cos\theta & 0 & \sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ -\sin\theta & 0 & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}Ry?(θ)=?cosθ0?sinθ0?0100?sinθ0cosθ0?0001??
Z軸Rz(θ)=[cos?θ?sin?θ00sin?θcos?θ0000100001]R_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 & 0 \\ \sin\theta & \cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}Rz?(θ)=?cosθsinθ00??sinθcosθ00?0010?0001??

旋轉方向:右手坐標系中,逆時針為正方向(從旋轉軸正向觀察)

b) 繞任意軸旋轉(Rodrigues公式)

繞單位向量 u=[ux,uy,uz]\mathbf{u} = [u_x, u_y, u_z]u=[ux?,uy?,uz?] 旋轉角度 θ\thetaθ

R(u,θ)=[cos?θ+ux2(1?cos?θ)uxuy(1?cos?θ)?uzsin?θuxuz(1?cos?θ)+uysin?θ0uyux(1?cos?θ)+uzsin?θcos?θ+uy2(1?cos?θ)uyuz(1?cos?θ)?uxsin?θ0uzux(1?cos?θ)?uysin?θuzuy(1?cos?θ)+uxsin?θcos?θ+uz2(1?cos?θ)00001] R(\mathbf{u}, \theta) = \begin{bmatrix} \cos\theta + u_x^2(1-\cos\theta) & u_xu_y(1-\cos\theta) - u_z\sin\theta & u_xu_z(1-\cos\theta) + u_y\sin\theta & 0 \\ u_yu_x(1-\cos\theta) + u_z\sin\theta & \cos\theta + u_y^2(1-\cos\theta) & u_yu_z(1-\cos\theta) - u_x\sin\theta & 0 \\ u_zu_x(1-\cos\theta) - u_y\sin\theta & u_zu_y(1-\cos\theta) + u_x\sin\theta & \cos\theta + u_z^2(1-\cos\theta) & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} R(u,θ)=?cosθ+ux2?(1?cosθ)uy?ux?(1?cosθ)+uz?sinθuz?ux?(1?cosθ)?uy?sinθ0?ux?uy?(1?cosθ)?uz?sinθcosθ+uy2?(1?cosθ)uz?uy?(1?cosθ)+ux?sinθ0?ux?uz?(1?cosθ)+uy?sinθuy?uz?(1?cosθ)?ux?sinθcosθ+uz2?(1?cosθ)0?0001??

5. 組合變換矩陣

變換矩陣可以通過乘法組合。注意矩陣乘法的順序非常重要(不滿足交換律)。通常,變換按以下順序應用:縮放 -> 旋轉 -> 平移,即:
M=T?R?S M = T \cdot R \cdot S M=T?R?S
但是,如果以不同的順序應用,結果會不同。

例如,先繞Y軸旋轉90度,再沿X軸平移3個單位,與先平移后旋轉的結果不同:
??先旋轉后平移??:點會先旋轉,然后沿世界坐標系的X軸平移。
??先平移后旋轉??:點先在世界坐標系中沿X軸平移,然后旋轉(此時點的位置已經改變,旋轉后位置不同)。

注意順序

  1. 縮放 (S)
  2. 旋轉 ?
  3. 平移 (T)

這是因為矩陣乘法是 右乘結合p′=T?(R?(S?p)) \mathbf{p}' = T \cdot (R \cdot (S \cdot \mathbf{p})) p=T?(R?(S?p))

特殊變換類型

1. 剪切矩陣(Shear)

H=[1hxyhxz0hyx1hyz0hzxhzy100001] H = \begin{bmatrix} 1 & h_{xy} & h_{xz} & 0 \\ h_{yx} & 1 & h_{yz} & 0 \\ h_{zx} & h_{zy} & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} H=?1hyx?hzx?0?hxy?1hzy?0?hxz?hyz?10?0001??

2. 正交投影矩陣

向XY平面投影:
Portho=[1000010000000001] P_{\text{ortho}} = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} Portho?=?1000?0100?0000?0001??

變換矩陣在編程中的實現

使用GLM(OpenGL Mathematics)庫示例(兩種寫法)

  1. GLM函數疊加運算
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>// 初始化矩陣
glm::mat4 model = glm::mat4(1.0f); // 單位矩陣// 平移:沿X軸移動1.5單位
model = glm::translate(model, glm::vec3(1.5f, 0.0f, 0.0f));// 旋轉:繞Z軸旋轉90度
model = glm::rotate(model, glm::radians(90.0f), glm::vec3(0.0f, 0.0f, 1.0f));// 縮放:Y軸放大2倍
model = glm::scale(model, glm::vec3(1.0f, 2.0f, 1.0f));

變換順序很重要:矩陣乘法從右到左應用變換,所以上面代碼的順序實際上是先縮放,再旋轉,最后平移。
在組合變換時,考慮使用逆序:先進行的變換在矩陣乘法中放在右邊(后乘),后進行的變換放在左邊(先乘)

2. 計算好各個變換矩陣后再相乘

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>int main() {// 單位矩陣glm::mat4 identity = glm::mat4(1.0f);// 平移變換:沿X軸移動2個單位glm::mat4 translation = glm::translate(glm::mat4(1.0), glm::vec3(2.0f, 0.0f, 0.0f));// 縮放變換:Y軸擴大3倍glm::mat4 scaling = glm::scale(glm::mat4(1.0), glm::vec3(1.0f, 3.0f, 1.0f));// 旋轉變換:繞Z軸旋轉45度glm::mat4 rotation = glm::rotate(glm::mat4(1.0), glm::radians(45.0f), glm::vec3(0.0f, 0.0f, 1.0f));// 繞任意軸旋轉:繞(1,1,0)旋轉30度glm::vec3 axis = glm::normalize(glm::vec3(1.0f, 1.0f, 0.0f));glm::mat4 customRotation = glm::rotate(glm::mat4(1.0), glm::radians(30.0f), axis);// 組合變換:先縮放,再旋轉,最后平移glm::mat4 composite = translation * rotation * scaling;// 應用變換到點glm::vec4 point(1.0f, 1.0f, 0.0f, 1.0f);glm::vec4 transformedPoint = composite * point;return 0;
}

手動實現矩陣類

class Matrix4f {
public:float m[4][4];Matrix4f() { /* 初始化為單位矩陣 */ }static Matrix4f translate(float tx, float ty, float tz) {Matrix4f m;m.m[0][3] = tx;m.m[1][3] = ty;m.m[2][3] = tz;return m;}static Matrix4f scale(float sx, float sy, float sz) {Matrix4f m;m.m[0][0] = sx;m.m[1][1] = sy;m.m[2][2] = sz;return m;}static Matrix4f rotateX(float angle) {float rad = angle * M_PI/180.0;float c = cos(rad);float s = sin(rad);Matrix4f m;m.m[1][1] = c; m.m[1][2] = -s;m.m[2][1] = s; m.m[2][2] = c;return m;}Matrix4f operator*(const Matrix4f& right) const {// 矩陣乘法實現}Vec4f operator*(const Vec4f& v) const {// 矩陣向量乘法}
};

變換矩陣的性質與應用

  1. 齊次坐標

    • 3D點:[x, y, z, 1]?
    • 3D向量:[x, y, z, 0]?(防止被平移)
  2. 逆變換

    • 平移逆矩陣:$ T^{-1}(t_x, t_y, t_z) = T(-t_x, -t_y, -t_z) $
    • 縮放逆矩陣:$ S^{-1}(s_x, s_y, s_z) = S(1/s_x, 1/s_y, 1/s_z) $
    • 旋轉逆矩陣:$ R^{-1} = R^T $(正交矩陣)
  3. 組合變換求逆
    組合變換的逆矩陣可以通過矩陣求逆得到。如果變換矩陣是正交的(純旋轉,不含縮放或錯切),則轉置就是逆矩陣。如果包含平移和縮放,則需要計算逆矩陣:

    (T?R?S)?1=S?1?R?1?T?1 (T \cdot R \cdot S)^{-1} = S^{-1} \cdot R^{-1} \cdot T^{-1} (T?R?S)?1=S?1?R?1?T?1
    其中:
    T ?1 :將平移向量取負。
    R ?1:旋轉矩陣的轉置(因為旋轉矩陣正交)。
    S ?1:縮放因子的倒數(假設非零)。

  4. 在變換鏈中的位置

    局部坐標 → 模型矩陣 → 世界坐標↓
    世界坐標 → 視圖矩陣 → 觀察坐標↓
    觀察坐標 → 投影矩陣 → 裁剪坐標
    

可視化理解變換順序

考慮一個點 P(0,1,0) 的變換過程:

原始位置: 0,1,0
縮放: 2倍Y軸
結果: 0,2,0
旋轉: 繞Z軸90度
結果: -2,0,0
平移: X軸移動3單位
最終位置: 1,0,0
錯誤順序
先平移: 3,1,0
后旋轉: -1,3,0
結果不符

正確的矩陣乘法順序:
Pfinal=[1003010000100001]?平移×[0?100100000100001]?旋轉×[1000020000100001]?縮放×[0101] P_{\text{final}} = \underset{\text{平移}}{\underbrace{ \begin{bmatrix} 1 & 0 & 0 & 3 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} }} \times \underset{\text{旋轉}}{\underbrace{ \begin{bmatrix} 0 & -1 & 0 & 0 \\ 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} }} \times \underset{\text{縮放}}{\underbrace{ \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 2 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} }} \times \begin{bmatrix} 0 \\ 1 \\ 0 \\ 1 \end{bmatrix} Pfinal?=平移?1000?0100?0010?3001????×旋轉?0100??1000?0010?0001????×縮放?1000?0200?0010?0001????×?0101??

這些矩陣構成了 3D 圖形學的基礎,在 OpenGL、DirectX、Vulkan 等圖形 API 以及 Unity、Unreal 等游戲引擎中廣泛使用。掌握它們對于理解 3D 渲染管線至關重要。

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

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

相關文章

長連接(Long Connection)詳解

一、長連接基本概念長連接&#xff08;也稱為持久連接&#xff09;是指在一個TCP連接上可以連續發送多個HTTP請求/響應&#xff0c;而不是每次通信都建立新的連接。這是HTTP/1.1的默認行為&#xff0c;通過Connection: keep-alive頭部實現。二、工作原理1. 傳統短連接流程客戶端…

【匯總】接口自動化測試 + 持續集成(文末視頻演示)

技術棧&#xff1a;java testng httpclient allure fastjson jsonpath poi/yaml log4j 有建議請聯系wx&#xff1a;ren168632201 java接口自動化系列(01)&#xff1a;自動化測試框架設計(入門版) java接口自動化系列(02)&#xff1a;測試數據文件設計(excel/yam) java接…

科研快報 |無人機+AI:廣東防控基孔熱背后的技術革命

Prism Path 科 研 快 報 CS跨學科頂尖期刊論文資訊 -NO.2025001- 人工智能在登革熱預防、控制與管理中的作用&#xff1a;一項技術性敘述綜述 The role of artificial intelligence for dengue prevention, control, and management: A technical narrative review 期刊…

常見的中間件漏洞

建議&#xff1a;啟動下一個環境時&#xff0c;將上一個環境關閉&#xff0c;防止端口沖突和運行卡頓1.TomcatTomcat put方法任意文件寫入漏洞Apache Tomcat 7.0.0 - 7.0.79 Apache Tomcat 8.5.19環境&#xff1a;cd vulhub-master/tomcat/CVE-2017-12615 docker-compose up -d…

7寸工業模組 XA070Y2-L01芯顯科技詳細參數資料

芯顯7寸工業液晶屏 XA070Y2-L01 技術規格單 基礎信息 項目 參數 制造商 芯顯 型號 XA070Y2-L01 顯示技術 a-Si TN TFT-LCD 應用場景 車載中控 / 工業HMI 屏幕尺寸 7.0英寸 機械結構 特性 指標 顯示區域 152.4 91.44 mm 整機尺寸 165 104.09 9.1 mm 公差范圍 0.5 mm 表面處理…

機器學習基礎-numpy

一、相關知識點二、例子&#xff1a;import matplotlib.pyplot as plt import numpy as npplt.rcParams[font.sans-serif] [KaiTi] # 使用黑體 plt.rcParams[axes.unicode_minus] False # 解決負號顯示問題math np.random.randint(low60,high100,size50) english np.rand…

Cockpit管理服務器

Cockpit 是一個開源工具&#xff0c;通過Web Console管理Linux服務器。部署 Cockpit[rootserver ~ 11:05:26]# yum -y install cockpit?[rootserver ~ 11:30:26]# systemctl enable cockpit.socket --nowCreated symlink from /etc/systemd/system/sockets.target.wants/cockp…

處理訂單過期但支付成功的系統設計:平衡用戶體驗與業務規則

設計一個處理訂單過期但用戶支付成功的場景&#xff0c;需要平衡用戶體驗、系統一致性和業務規則。以下是一個系統化的設計方案&#xff0c;涵蓋關鍵流程、異常處理和用戶溝通&#xff1a;1. 場景分析 背景&#xff1a;用戶在下單后&#xff0c;訂單因超時而被標記為“過期”&a…

AI學習筆記三十三:基于Opencv的單目標跟蹤

若該文為原創文章&#xff0c;轉載請注明原文出處。一、功能介紹主要是想實現跟蹤視頻中的一個特定目標。使用了OpenCV庫來實現視頻中特定目標的跟蹤。需要提供視頻文件路徑以及目標在第一幀中的位置坐標&#xff08;x, y, width, height&#xff09;&#xff0c;程序會自動跟蹤…

第二篇:Three.js核心三要素:場景、相機、渲染器

第二篇&#xff1a;Three.js核心三要素&#xff1a;場景、相機、渲染器 引言 在Three.js的世界里&#xff0c;場景(Scene)、相機(Camera)和渲染器(Renderer)構成了最基礎的"鐵三角"。它們如同導演、攝像機和放映機&#xff0c;共同決定了3D內容的呈現方式。本篇將深入…

RagFlow本地源碼部署(非Docker)

參考官方文檔做個總結 1. 提前安裝好uv pipx install uv pre-commit2. 下載源碼&#xff1a; git clone https://github.com/infiniflow/ragflow.git cd ragflow/ uv sync --python 3.10 --all-extras # install RAGFlow dependent python modules uv run download_deps.py …

[免費]基于Python的招聘職位信息推薦系統(獵聘網數據分析與可視化)(Django+requests庫)【論文+源碼+SQL腳本】

大家好&#xff0c;我是python222_小鋒老師&#xff0c;看到一個不錯的基于Python的招聘職位信息推薦系統(獵聘網數據分析與可視化)(Djangorequests庫)&#xff0c;分享下哈。 項目視頻演示 【免費】基于Python的招聘職位信息推薦系統(獵聘網數據分析與可視化)(Django爬蟲) P…

國產化PDF處理控件Spire.PDF教程:Java 提取 PDF 圖片,高質量提取與圖片過濾技巧

在處理包含圖片的 PDF 文件時&#xff0c;例如掃描文檔、產品手冊或宣傳資料&#xff0c;我們經常需要將其中的圖像提取出來&#xff0c;用于保存、識別或再加工。E-iceblue旗下Spire系列產品&#xff0c;是文檔處理領域的佼佼者&#xff0c;支持國產化信創。本文將介紹如何使用…

Cesium 快速入門(七)材質詳解

Cesium 快速入門&#xff08;七&#xff09;材質詳解 看過的知識不等于學會。唯有用心總結、系統記錄&#xff0c;并通過溫故知新反復實踐&#xff0c;才能真正掌握一二 作為一名摸爬滾打三年的前端開發&#xff0c;開源社區給了我飯碗&#xff0c;我也將所學的知識體系回饋給大…

C++:結構體(Structure)

目錄 第一性原理出發&#xff1a;我們要解決什么問題&#xff1f; 定義結構體&#xff08;Defining Structures&#xff09; 問題&#xff1a;名字太長怎么辦&#xff1f; 如何定義結構體變量&#xff1f; 結構體的大小&#xff08;Size of Structures&#xff09; 初始化…

化學結構式解讀指南:從基礎認知到InDraw智能識別

中文名稱&#xff1a;3-[2-(二甲基氨基)乙基]-1H-吲哚英文名稱&#xff1a;3-[2-(dimethylamino)ethyl]-1H-indole分子式: C12H16N2分子量: 188.2740這是什么結構式&#xff1f;怎么繪制呢&#xff1f;可以用InDraw里的AI圖像識別這個結構式&#xff0c;也可以手動繪圖&#xf…

如何使用一臺電腦adb調試多個Android設備

目錄 一、臨時斷開其中一個設備連接 二、指定調試設備 總結 當我們使用Android調試工具調試多個設備&#xff0c;例如一開始使用adb連接了一臺Android真機進行調試&#xff0c;此時又在Android studio中打開了一個模擬機&#xff0c;此時我們在adb命令窗口中使用adb命令的…

ChatGPT的下一站:從“答案引擎”到“思維教練”

摘要&#xff1a;我們正處在一個“萬物皆可ChatGPT”的時代&#xff0c;但當它淪為最高效的“代碼搬運工”和“作業速成器”時&#xff0c;我們得到的究竟是效率的提升還是思維的退化&#xff1f;本文深入探討一個引人深思的概念——“導師模式”的AI。它不再直接提供答案&…

SpringBoot集成Flyway

SpringBoot集成Flyway_springboot flyway-CSDN博客 Flyway 本質上是一個開源的數據庫遷移工具&#xff0c;它能夠以自動化、可重復且可靠的方式管理數據庫的變更。無論是小型項目還是大型企業級應用&#xff0c;Flyway 都能助力開發者輕松應對數據庫架構的演進。它支持多種數據…

【實時Linux實戰系列】實時圖像處理應用開發

在當今快速發展的技術領域&#xff0c;實時圖像處理應用在眾多領域發揮著至關重要的作用。從自動駕駛汽車、工業自動化檢測到醫療影像診斷&#xff0c;實時圖像處理技術的應用場景無處不在。通過在實時Linux系統中開發圖像處理應用&#xff0c;開發者能夠充分利用Linux的穩定性…