三维变换矩阵深度理解之变换矩阵分解

发布于:2025-03-02 ⋅ 阅读:(89) ⋅ 点赞:(0)

概述

三维变换矩阵在几何核心库、渲染引擎、游戏开发等多个方面都有广泛的应用。在实际应用中,我们有时候需要单独使用三维变化的平移、旋转或缩放解决业务问题。本文将详细讲解将三维变换矩阵拆分为平移、旋转、缩放的分解算法,同时也作为对前一篇文章的理解加强。

了解了原理,一定会发现这个看似麻烦的问题解决起来非常简单。作者的写作目标就是把复杂抽象的数学问题和实际工作相结合,通俗易懂的介绍给大家

如果没有读过前一篇文章的建议先读一下,链接如下

       一文彻底弄懂三维变换矩阵

本文以后用“上篇文章”代替该文章。

用平移、旋转、缩放表示原矩阵

假设我们要分解的三维变化矩阵如下

M = [ a 00 a 01 a 02 a 03 a 10 a 11 a 12 a 13 a 20 a 21 a 22 a 23 0 0 0 1 ]        ( 公式 1 ) M=\begin{bmatrix} a_{00} & a_{01} & a_{02} & a_{03} \\ a_{10} & a_{11} & a_{12} & a_{13} \\ a_{20} & a_{21} & a_{22} & a_{23} \\ 0 & 0 & 0 & 1 \end{bmatrix} \space \space \space \space \space \space (公式1) M= a00a10a200a01a11a210a02a12a220a03a13a231       (公式1)

利用上篇文章介绍的公式

P ′ = ( P x ⋅ s x ⋅ e 0 ,    P y ⋅ s y ⋅ e 1 ,    P z ⋅ s z ⋅ e 2 ) + P T P^{'}=(P_x \cdot s_x \cdot e0,\space\space P_y \cdot s_y \cdot e1,\space\space P_z \cdot s_z\cdot e2) + P_T P=(Pxsxe0,  Pysye1,  Pzsze2)+PT

我们可以将M表示成如下形式

M = [ s x ⋅ e 0 s y ⋅ e 1 s z ⋅ e 2 P T 0 0 0 1 ]        ( 公式 2 ) M=\begin{bmatrix} s_x \cdot e0 & s_y \cdot e1 & s_z \cdot e2 & P_T \\ 0 & 0 & 0 & 1 \end{bmatrix} \space \space \space \space \space \space (公式2) M=[sxe00sye10sze20PT1]      (公式2)

计算平移向量

平移向量是最好计算的,对比公式1和公式2可知,平移向量

P T = [ a 03 a 13 a 23 ] P_T = \begin{bmatrix} a_{03} \\ a_{13} \\ a_{23} \end{bmatrix} PT= a03a13a23

计算缩放向量的绝对值

根据上篇文章,我们知道旋转矩阵的e0、e1和e2是单位向量,基于这个特性,我们可以计算缩放系数的绝对值

∣ s x ∣ = ∣ s x ∣ ⋅ ∣ e 0 ∣ = ∣ s x ⋅ e 0 ∣ = a 00 2 + a 10 2 + a 20 2 ∣ s y ∣ = ∣ s y ∣ ⋅ ∣ e 1 ∣ = ∣ s y ⋅ e 1 ∣ = a 01 2 + a 11 2 + a 21 2 ∣ s z ∣ = ∣ s z ∣ ⋅ ∣ e 2 ∣ = ∣ s z ⋅ e 2 ∣ = a 02 2 + a 12 2 + a 22 2 |s_x| = |s_x|\cdot|e0|=|s_x \cdot e0| = \sqrt{a_{00}^2+a_{10}^2+a_{20}^2} \\[4px] |s_y| = |s_y|\cdot|e1|=|s_y \cdot e1| = \sqrt{a_{01}^2+a_{11}^2+a_{21}^2} \\[4px] |s_z| = |s_z|\cdot|e2|=|s_z \cdot e2| = \sqrt{a_{02}^2+a_{12}^2+a_{22}^2} sx=sxe0∣=sxe0∣=a002+a102+a202 sy=sye1∣=sye1∣=a012+a112+a212 sz=sze2∣=sze2∣=a022+a122+a222

计算旋转矩阵和缩放系数的符号

理论上,这个问题存在多组解,例如做一个旋转,和镜像两次之后做旋转,能得到同样的变换结果。实际应用中,我们一般情况下只需找到一组结果即可(其他结果,可以参考同样的方法找到)。

我们先假设不存在镜像,也就是假设三个维度的缩放系数都为正,即

s x = a 00 2 + a 10 2 + a 20 2 s y = a 01 2 + a 11 2 + a 21 2 s z = a 02 2 + a 12 2 + a 22 2 s_x = \sqrt{a_{00}^2+a_{10}^2+a_{20}^2} \\[4px] s_y = \sqrt{a_{01}^2+a_{11}^2+a_{21}^2} \\[4px] s_z = \sqrt{a_{02}^2+a_{12}^2+a_{22}^2} sx=a002+a102+a202 sy=a012+a112+a212 sz=a022+a122+a222

那么

e 0 = [ a 00 s x a 10 s x a 20 s x ] e 1 = [ a 01 s y a 11 s y a 21 s y ] e 2 = [ a 02 s z a 12 s z a 22 s z ] e0=\begin{bmatrix} \dfrac{a_{00}}{s_x} \\[16px] \dfrac{a_{10}}{s_x} \\[16px] \dfrac{a_{20}}{s_x} \end{bmatrix} \\[16px] e1=\begin{bmatrix} \dfrac{a_{01}}{s_y} \\[16px] \dfrac{a_{11}}{s_y} \\[16px] \dfrac{a_{21}}{s_y} \end{bmatrix} \\[16px] e2=\begin{bmatrix} \dfrac{a_{02}}{s_z} \\[16px] \dfrac{a_{12}}{s_z} \\[16px] \dfrac{a_{22}}{s_z} \end{bmatrix} \\[16px] e0= sxa00sxa10sxa20 e1= sya01sya11sya21 e2= sza02sza12sza22

根据上篇文章的讲解,我们知道e0、e1和e2是正交坐标系的三个轴,根据坐标系轴的正交特性可知,如果

( e 0 × e 1 ) ⋅ e 2 < 0 (e0 × e1) \cdot e2 < 0 (e0×e1)e2<0

说明有一个坐标轴需要反向,即存在镜像。

假设将x轴反向,则

s x = − s x e 0 = − e 0 s_x = -s_x \\[2px] e0 = -e0 sx=sxe0=e0

到这里,我们就得到了缩放系数

[ s x s y s z ] \begin{bmatrix} s_x \\ s_y \\ s_z \end{bmatrix} sxsysz

旋转矩阵

[ e 0 e 1 e 2 ] \begin{bmatrix} e0 & e1 & e2 \end{bmatrix} [e0e1e2]

还是那句话,真正理解了原理,真的很简单。祝大家打好基础,技术突飞猛进。


网站公告

今日签到

点亮在社区的每一天
去签到