回顧Games101圖形學(一)幾何變換中一些公式的推導


回顧Games101 chapter 1 - 6

前言

本文只寫回顧后重新加深認識的知識

透視除法的意義

經過MVP矩陣之后,將模型空間下某點的坐標,轉換成了裁剪空間下的坐標,此時因為裁剪空間的范圍是\(x∈[-W/2,W/2]\)\(y∈[-H/2,H/2]\),所以經過以下兩個變換,其中除以pz就是透視除法

透視矯正意義和做法:https://stackoverflow.com/questions/24441631/how-exactly-does-opengl-do-perspectively-correct-linear-interpolation
一:

\[-1≤2·\frac{\left( \frac{p_x}{p_z}·near \right)}{w}≤1 \\ -1≤2·\frac{\left( \frac{p_y}{p_z}·near \right)}{h}≤1 \]

二:

\[\left[ \begin{matrix} x& y& z& w\\ \end{matrix} \right] \left[ \begin{matrix} 1& 0& 0& 0\\ 0& 1& 0& 0\\ 0& 0& 1& 0\\ \varDelta x& \varDelta y& \varDelta z& 1\\ \end{matrix} \right] =\left[ \begin{matrix} x+\varDelta x*w& y+\varDelta y*w& z+\varDelta z*w& w\\ \end{matrix} \right] \]

只有當W=1,這個三維坐標轉換是等價的,才能保證位移的量是正確的,W=0時,則沒有位移

只有當W=1時,三維坐標點轉換成四維齊次坐標點才是等價的

坐標系變換和矩陣推導

坐標系變換理解不直觀,傾向於101中閆老師所說的理解坐標系的轉換通過矩陣進行的線性變換,將A坐標系下的點P,乘上矩陣得出B坐標系下的點P',以下是拋開常見的變換(如透視投影變換、正交投影變換等)如何得出變換矩陣M,通過矩陣變換(下文着重說明)

已知坐標系A和坐標系B

\[坐標系B的x,y,z軸在坐標系A下可表示為(u_{\mathrm{x}},u_{\mathrm{y}},v_{\mathrm{z}},0) \]

\[\left( \mathrm{v}_{\mathrm{x}},\mathrm{v}_{\mathrm{y}},\mathrm{v}_{\mathrm{z}},0 \right) \text{,}\left( \mathrm{w}_{\mathrm{x}},\mathrm{w}_{\mathrm{y}},\mathrm{w}_{\mathrm{z}},0 \right) \text{,坐標系B的原點在坐標系A下表示為(Q}_{\mathrm{x}},\mathrm{Q}_{\mathrm{y}},\mathrm{Q}_{\mathrm{z}},1\text{)} \]

img

則將坐標系B中一點P從坐標系B變換到坐標系A的變換矩陣為:(注意此處的例子是將源坐標系A變換到目標坐標系B下)

\[\mathrm{M}=\left[ \begin{matrix} u_{\mathrm{x}}& u_{\mathrm{y}}& u_{\mathrm{z}}& 0\\ v_{\mathrm{x}}& v_{\mathrm{y}}& v_{\mathrm{z}}& 0\\ w_{\mathrm{x}}& w_{\mathrm{y}}& w_{\mathrm{z}}& 0\\ Q_{\mathrm{x}}& Q_{\mathrm{y}}& Q_{\mathrm{z}}& 1\\ \end{matrix} \right] \]

如之前所說,變換過程中點p在空間中的絕對位置沒有發生改變,只是參考坐標系發生了改變,從B坐標系變到A坐標系。(縮放,旋轉,平移變換只有在同一坐標系下才有意義)

矩陣變換是基於基向量組的結果

  • 矩陣變換之於同一個坐標系,可以理解為坐標系不變,點的位置改變
  • 矩陣變換之於不同坐標系,可以理解為點的絕對位置不變,坐標系改變

\[\left[ \begin{array}{c} x^{'}\\ y^{'}\\ \end{array} \right] =B\left[ \begin{array}{c} x\\ y\\ \end{array} \right] \Rightarrow \left[ \begin{array}{c} x\\ y\\ \end{array} \right] =B^{-1}\left[ \begin{array}{c} x^{'}\\ y^{'}\\ \end{array} \right] \text{,}B=\left[ \begin{matrix} \overrightarrow{b_1}& \overrightarrow{b_2}\\ \end{matrix} \right] \text{,且}\overrightarrow{b_1}\text{,}\overrightarrow{b_2}\text{是坐標系}B\text{的基向量} \]

其中,矩陣B的各個列向量分別對應B坐標系的各個基向量,\( \left[ \begin{array}{c} x\\ y\\ \end{array} \right] \)是向量\( \overrightarrow{OP} \)或者說點P在B坐標系的表示,\( \left[ \begin{array}{c} x^{'}\\ y^{'}\\ \end{array} \right] \)則是向量\( \overrightarrow{OP} \)或者點P在A坐標系中的表示

這里寫圖片描述

以圖中的兩個向量\( \overrightarrow{b_1} \)\( \overrightarrow{b_2} \)為基確定一個坐標系B,顯然在B坐標系中\( \overrightarrow{b_{1B}}=\left[ \begin{array}{c} 1\\ 0\\ \end{array} \right] \)\( \overrightarrow{b_{2B}}=\left[ \begin{array}{c} 0\\ 1\\ \end{array} \right] \),接下來,將\( \overrightarrow{b_1} \)\( \overrightarrow{b_2} \)定位到A坐標系中,得到\( \overrightarrow{b_{1A}}=\left[ \begin{array}{c} 2\\ 1\\ \end{array} \right] \)\( \overrightarrow{b_{2A}}=\left[ \begin{array}{c} -1\\ 1\\ \end{array} \right] \)

\( \because \overrightarrow{OP}=2\overrightarrow{b_1}+2\overrightarrow{b_2} \)

\( \therefore \overrightarrow{OP}\)在B坐標系中的表示為\( \left[ \begin{array}{c} 2\\ 2\\ \end{array} \right] \),現在,將\( \overrightarrow{OP} \)用A坐標系描敘:
\( \overrightarrow{OP}=2\overrightarrow{b_1}+2\overrightarrow{b_2}=2\overrightarrow{b_{1A}}+2\overrightarrow{b_{2A}}=\left[ \begin{matrix} \overrightarrow{b_{1A}}& \overrightarrow{b_{2A}}\\ \end{matrix} \right] \left[ \begin{array}{c} 2\\ 2\\ \end{array} \right] =\left[ \begin{array}{c} 2\\ 4\\ \end{array} \right] \\ \)
現在,令矩陣B=\( \left[ \begin{matrix} \overrightarrow{b_{1A}}& \overrightarrow{b_{2A}}\\ \end{matrix} \right] \),P點是用B坐標系表示的任意一點\((x,y)\)
於是\( \overrightarrow{OP} \)在A坐標系中的表示\( \left[ \begin{array}{c} ^{x^{'}}\\ y^{'}\\ \end{array} \right] =B\left[ \begin{array}{c} x\\ y\\ \end{array} \right] \),顯然,B是可逆的,於是就有了之前的結論
那么在這個例子當中,當我們需要知道某點在轉換坐標系后的新坐標時,通過該例子也可以加深印象,比如在B坐標系下有點\(Q(3,4)\),即\(\overrightarrow{OQ}=(3,4)\),跟據剛才的例子可以看出它轉換在A坐標系下的點

\[\overrightarrow{OQ}=2\overrightarrow{b_1}+2\overrightarrow{b_2}=2\overrightarrow{b_{1A}}+2\overrightarrow{b_{2A}}=\left[ \begin{matrix} \overrightarrow{b_{1A}}& \overrightarrow{b_{2A}}\\ \end{matrix} \right] \left[ \begin{array}{c} 3\\ 4\\ \end{array} \right] =\left[ \begin{matrix} 2& -1\\ 1& 1\\ \end{matrix} \right] \left[ \begin{array}{c} 5\\ 4\\ \end{array} \right] =\left[ \begin{array}{c} 6\\ 9\\ \end{array} \right] \]

即轉換到A坐標系下的點\(Q^{'}\)的坐標為\(Q^{'}(6,9)\)

雖然這里的討論是基於二維的,但是,結論可以擴展到任意維度

闡述結論:

將B坐標系的基向量定位到A坐標系,然后將定位之后的基向量作為矩陣B的列向量,用矩陣B對B坐標系中的點P的坐標進行矩陣變換,將得到點P在A坐標系中的坐標。這個過程,就是從坐標系 B到坐標系A的一個追溯過程

View/Camera Transformation

先將相機移到原點,然后進行分別對坐標軸進行旋轉,用矩陣表示則是\(M_{view}=R_{view}T_{view}\)

  • 將相機移回原點

\[T_{view}=\left[ \begin{matrix} 1& 0& 0& -x_e\\ 0& 1& 0& -y_e\\ 0& 0& 1& -z_e\\ 0& 0& 0& 1\\ \end{matrix} \right] \]

  • \(Rotate\,\,g\,\,to\,\,-Z, t\,\,to\,\,Y, \left( g×t \right) \,\,To\,\,X\)
    g是相機看的方向(lookAt),t是相機向上的方向(Up),也就是相機的-Z軸和Y軸,兩個向量叉積就是另一個坐標軸

\[R_{view}^{-1}=\left[ \begin{matrix} x_{\widehat{g}×\widehat{t}}& x_t& x_{-g}& 0\\ y_{\widehat{g}×\widehat{t}}& y_t& y_{-g}& 0\\ z_{\widehat{g}×\widehat{t}}& z_t& z_{-g}& 0\\ 0& 0& 0& 1\\ \end{matrix} \right] \]

旋轉矩陣是正交矩陣,所以旋轉矩陣的逆就是旋轉矩陣的轉置

\[R_{view}^{}=\left[ \begin{matrix} x_{\widehat{g}×\widehat{t}}& y_{\widehat{g}×\widehat{t}}& z_{\widehat{g}×\widehat{t}}& 0\\ x_t& y_t& y_t& 0\\ x_{-g}& y_{-g}& z_{-g}& 0\\ 0& 0& 0& 1\\ \end{matrix} \right] \]

正交投影矩陣

無論是正交投影還是透視投影,都是要將x、y、z移到-1到1的范圍內,先將中心點移到原點,然后縮放

\[M_{ortho}=\left( \begin{matrix} \frac{2}{r-l}& 0& 0& 0\\ 0& \frac{2}{t-b}& 0& 0\\ 0& 0& \frac{2}{n-f}& 0\\ 0& 0& 0& 1\\ \end{matrix} \right) \left( \begin{matrix} 1& 0& 0& -\frac{r+l}{2}\\ 0& 1& 0& -\frac{t+b}{2}\\ 0& 0& 1& -\frac{n+f}{2}\\ 0& 0& 0& 1\\ \end{matrix} \right) \]

透視投影矩陣推導

首先先將frustum 轉變為cuboid(n -> n,f -> f)(\(M_{persp->ortho}\))
然后再做正交投影

整個投影變換包括兩部分

  • v = P(矩陣)*p
  • \(v=\frac{v}{v_w}=\frac{v}{pz}\)透視除法


以上大概推出等式這一步,接下來用公式展示更為直觀

\[\left( \begin{matrix} m00& m01& m02& m03\\ m10& m11& m12& m13\\ m20& m21& m22& m23\\ m30& m31& m32& m33\\ \end{matrix} \right) \left( \begin{array}{c} x\\ y\\ z\\ 1\\ \end{array} \right) =\left( \begin{array}{c} \frac{x}{z*aspect*\tan \left( \frac{fov}{2} \right)}\\ \frac{y}{z*tan\left( \frac{fov}{2} \right)}\\ z^{‘’}\\ 1\\ \end{array} \right) \]

\[m00*x+m01*y+m02*z+m03=\frac{x}{z*aspect*\tan \left( \frac{fov}{2} \right)} \]

將右邊的四維列向量表示的坐標每一項乘以z,所以有

\[\left( \begin{matrix} m00& m01& m02& m03\\ m10& m11& m12& m13\\ m20& m21& m22& m23\\ m30& m31& m32& m33\\ \end{matrix} \right) *\left( \begin{array}{c} x\\ y\\ z\\ 1\\ \end{array} \right) =\left( \begin{array}{c} \frac{x}{aspect*\tan \left( \frac{fov}{2} \right)}\\ \frac{y}{\tan \left( \frac{fov}{2} \right)}\\ z*z^{{'}{'}}\\ z\\ \end{array} \right) \]

所以求得矩陣為

\[\left( \begin{matrix} \frac{1}{aspect*\tan \left( \frac{fov}{2} \right)}& 0& 0& 0\\ 0& \frac{1}{\tan \left( \frac{fov}{2} \right)}& 0& 0\\ 0& 0& m22& m23\\ 0& 0& 1& 0\\ \end{matrix} \right) \]

\[m22*z+m23 =\,\,z*z^{{'}{'}} \\ \Rightarrow m22+\frac{m23}{z}=z^{{'}{'}} \]

因為z=zNear時,z''=-1;z=zFar時,z''=1所以有以下等式

\[m22+\frac{m23}{zNear}=-1 \\ m22+\frac{m23}{zFar}=1 \]

聯立求得:

\[m22=\frac{-zFar-zNear}{zNear-zFar} \\ m23=\frac{2*zFar*zNear}{zNear-zFar} \]

最后求得投影矩陣為

\[\left( \begin{matrix} \frac{1}{aspect*\tan \left( \frac{fov}{2} \right)}& 0& 0& 0\\ 0& \frac{1}{\tan \left( \frac{fov}{2} \right)}& 0& 0\\ 0& 0& \frac{-zFar-zNear}{zNear-zFar}& \frac{2*zNear*zFar}{zNear-zFar}\\ 0& 0& 1& 0\\ \end{matrix} \right) \]

將這樣得矩陣乘以視錐體內的一個頂點坐標,得到一個新的向量,再將這個向量的每個分量除以第四個分量(此步驟也被稱為透視除法)(w),這樣就可以得到頂點映射到規則立方觀察體后的新的坐標

注意:z坐標的映射方式的獲得,最后我們是為了方便矩陣乘法的操作方向求得了z坐標與cvv中的z坐標的映射方式:

\[m22+\frac{m23}{z}=z^{{'}{'}} \]

此時的映射並不是線性的,當z越大時,z的變化對z''的擾動越小

Canonical Cube to Screen

  • Irrelevant to z
  • Transform in xy plane : [-1, 1] to [0, width] × [0, height]
  • Viewport transform matrix:

視口矩陣

\[M_{viewport}=\left[ \begin{matrix} \frac{width}{2}& 0& 0& \frac{width}{2}\\ 0& \frac{height}{2}& 0& \frac{height}{2}\\ 0& 0& 1& 0\\ 0& 0& 0& 1\\ \end{matrix} \right] \]

深度z的計算

前言
3D光柵化發生在圖元被變換到Screen space之后,因為這里的Screen space與2D的Screen Space完全一致,所以2D的光柵化算法在這里依然適用。

然而由於圖元經過了投影變換,且投影變換為非線性變換,所以不能用簡單的線性插值獲取fragment的屬性

投影變換不會保持相對距離不變性
如上圖所示,view space中的線段v0v1上兩點$ p0\left( p0_x,p0_y,p0_z,1 \right) $,$ p1\left( p1_x,p1_y,p1_z,1 \right) $在near plane上的投影為點$ s0\left( s0_x,s0_y \right) $,$ s1\left( s1_x,s1_y \right) $。$ p0 $,$p1$中間一點$v(v_x,v_y,v_z,1)$在near plane上的投影為點$q(q_x,q_y)$。從圖中可以看出點v到p0,p1的距離比值與點q到s0,s1的距離比值完全不同,投影變換不保持距離不變。

為了執行z-buffer算法,需要通過點q獲取到v的深度值(z)
\(v\)的深度值可以通過如下方法插值得到:

\[v_z=\frac{1}{\frac{c}{p1_z}+\frac{\left( 1-c \right)}{p0_z}} \]

以下是推導的過程:

手寫版:

文字版:
由於點\(q\)為點\(v\)在near plane上的投影,因此點\(q\)與點\(v\)的關系為:

  • \(q_x=\frac{v_x·near}{v_z}\)
    \(v\)位於\(p0p1\)之間,則
  • \(v_z=p0_{z}+t·(p1_z-p0_z)=\frac{v_x·near}{q_x}\)
    由點\(v\)\(p0\)\(p1\)之間,點\(q\)\(s0\)\(s1\)之間則有
  • \(v_x=p0_{x}·(1-t)+p1_{x}·t=p0_{x}+t·(p1_{x}-p0_{x})\)
  • \(q_x=s0_{x}·(1-c)+s1_{x}·c=s0_{x}+c·(s1_{x}-s0_{x})\)
    代入式(1)可得
    \(v_z=\frac{v_x·near}{q_x}=\frac{(p0_x+t·(p1_x-p0_x))·near}{s0_x+c·(s1_x-s0_x)}\)式(2)
    又s0和s1分別為p0和p1在near plane上的投影,則:
  • \(s0_x=\frac{p0_x·near}{p1_z}\)
  • \(s1_x=\frac{p1_x·near}{p1_z}\)
    代入式(2)可得:

\[v_z=\frac{\left( \frac{p0_x·s0_x}{near}+t·\left( \frac{p1_x·s1_x}{near}-\frac{p0_x·s0_x}{near} \right) \right) ·near}{s0_x+c·\left( s1_x-s0_x \right)} \]

\[v_z=\frac{\left( \frac{p0_x·s0_x}{near}+t·\left( \frac{p1_x·s1_x}{near}-\frac{p0_x·s0_x}{near} \right) \right) ·near}{s0_x+c·\left( s1_x-s0_x \right)} \\ v_z=\frac{\left( p0_x·s0_x+t·\left( p1_x·s1_x-p0_x·s0_x \right) \right)}{s0_x+c·\left( s1_x-s0_x \right)} \\ p0_z+t·\left( p1_z-p0_z \right) =\frac{\left( p0_x·s0_x+t·\left( p1_x·s1_x-p0_x·s0_x \right) \right)}{s0_x+c·\left( s1_x-s0_x \right)} \\ \left( p0_z+t·\left( p1_z-p0_z \right) \right) ·\left( s0_x+c·\left( s1_x-s0_x \right) \right) =p0_x·s0_x+t·\left( p1_x·s1_x-p0_x·s0_x \right) \\ p0_z·s0_x+p0_z·c·\left( s1_x-s0_x \right) +t·\left( p1_z-p0_z \right) ·s0_x+t·c·\left( p1_z-p0_z \right) ·\left( s1_x-s0_x \right) =p0_x·s0_x+t·\left( p1_x·s1_x-p0_x·s0_x \right) \]

化簡得:

\[t·\left( p1_z-c·\left( p1_z-p0_z \right) \right) =c·p0_z \]

則:

\[t=\frac{c·p0_z}{c·p0_z+(1-c)·p1_z} \]

代入式(1)可得

\[v_z=p0_z+t·(p1_z-p0_z) \]

\[v_z=p0_z+\frac{c·p0_z}{c·p0_z+(1-c)·p1_z}·(p1_z-p0_z) \]

\[v_z=\frac{1}{\frac{c}{p1_z}+\frac{(1-c)}{p0_z}} \]

若View Space中三角形\(v0v1v2\),變換到Screen Space后為三角形\(s0s1s2\)\(v0v1v2\)內一點v在Screen Space的投影點\(s0s1s2\)內的點\(q\),對三角形\(s0s1s2\)內的點(fragment)\(q\),可以通過如下方法取得fragment\(q\)在View Space中對應的深度值:

\[q.z=v.z=\frac{1}{\frac{\lambda0}{v0.z}+\frac{\lambda1}{v1.z}+\frac{\lambda2}{v2.z}} \]

\(\lambda0,\lambda1,\lambda2\)為點p在三角形\(s0s1s2\)內的重心坐標
引入結論:
對Screen Space三角形\(s0,s1,s2\)內一點\(p\)的任意屬性插值的公式為:

\[Atribute\left( p \right) =z·\left( \frac{\lambda 0·Atribute\left( v0 \right)}{z0}+\frac{\lambda 1·Atribute\left( v1 \right)}{z1}+\frac{\lambda 2·Atribute\left( v2 \right)}{z2} \right) \]

\(\lambda0,\lambda1,\lambda2\)為點\(p\)的重心坐標,\(z0,z1,z2,z\)分別為\(s0,s1,s2,p\)在view space中對應點的深度值,可以用這個方法插值得到\(p\)在NDC Space內對應點的深度值
此處貼一下Games101作業框架中關於深度的計算,與上述公式對應\(z = z_interpolated*w_reciprocal\)

    auto[alpha, beta, gamma] = computeBarycentric2D(x, y, t.v);
    float w_reciprocal = 1.0 / (alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
    float z_interpolated =
    alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
    z_interpolated *= w_reciprocal;

    if (depth_buf[get_index(x, y)] > z_interpolated) {
        depth_buf[get_index(x, y)] = z_interpolated;
        Eigen::Vector3f point;
        point << static_cast<float>(x), static_cast<float>(y), z_interpolated;
        set_pixel(point, t.getColor());
    }

羅德里格斯旋轉公式

指定任意軸k旋轉\( \alpha \)角得出旋轉矩陣
字寫得不好,在爬了...
手寫版:

文字版:
首先先將\(\overrightarrow{k}\)處理成單位向量,這點很重要,關乎着下一步等式是否成立,有些博文寫這里不需要處理單位向量,這是錯的

\[\overrightarrow{v}·\overrightarrow{k}=|\overrightarrow{v}|·|\overrightarrow{k}|·\cos <\overrightarrow{v}\text{,}\overrightarrow{k}>=|\overrightarrow{v}|·\cos <\overrightarrow{v}\text{,}\overrightarrow{k}> \]

可得

\[\overrightarrow{v_{||}}=|\overrightarrow{v}|·\cos <\overrightarrow{v},\overrightarrow{k}>·\overrightarrow{k} \\ \overrightarrow{v}=\overrightarrow{v_{\bot}}+\overrightarrow{v_{||}} \\ \overrightarrow{v_{\bot}}=\overrightarrow{v}-\overrightarrow{v_{||}}=\overrightarrow{v}-\left( \overrightarrow{v}·\overrightarrow{k} \right) \overrightarrow{k} \]

\(\overrightarrow{k}\)做旋轉時,向下做垂線,可看作底部經過了類似半圓的旋轉
要求得\(\overrightarrow{v_{rot}}=\overrightarrow{v_{||}}+\overrightarrow{v_{rot\bot}}\),將\(\overrightarrow{v_{rot\bot}}\)作正交分解有\( \overrightarrow{v_{rot\bot}}=\overrightarrow{a}+\overrightarrow{b} \),易得\( |\overrightarrow{w}|=|\overrightarrow{v_{\bot}}| \),則有\( \overrightarrow{w}=\overrightarrow{k}×\overrightarrow{v_{\bot}}=\overrightarrow{k}×\left[ \overrightarrow{v}-\overrightarrow{v_{||}} \right] =\overrightarrow{k}×\overrightarrow{v}-\overrightarrow{k}×\overrightarrow{v_{||}}=\overrightarrow{k}×\overrightarrow{v}-0=\overrightarrow{k}×\overrightarrow{v} \)
接下來求\( \overrightarrow{a} \)\( \overrightarrow{b} \)

\[|\overrightarrow{a}|=|\overrightarrow{v_{rot\bot}}|·\cos \left( \theta -90 \right) =|\overrightarrow{v_{rot\bot}}|·\sin \left( \theta \right) \\ \overrightarrow{a}=\frac{\overrightarrow{w}}{|\overrightarrow{w}|}·|\overrightarrow{a}|=\frac{\overrightarrow{w}}{|\overrightarrow{v_{rot\bot}}|}·|\overrightarrow{v_{rot\bot}}|·\sin \left( \theta \right) =\overrightarrow{w}·\sin \left( \theta \right) \]

\[|\overrightarrow{b}|=|\overrightarrow{v_{rot\bot}}|·\cos \left( 180-\theta \right) =|\overrightarrow{v_{rot\bot}}|·\cos \left( \theta \right) \\ \overrightarrow{b}=\frac{\overrightarrow{v_{\bot}}}{|\overrightarrow{v_{\bot}}|}·|\overrightarrow{b}|=\frac{\overrightarrow{v_{\bot}}}{|\overrightarrow{v_{\bot}}|}·|\overrightarrow{v_{rot\bot}}|·\cos \left( \theta \right) =\overrightarrow{v_{\bot}}·\cos \left( \theta \right) \,\, \text{注意}|\overrightarrow{v_{\bot}}|=|\overrightarrow{v_{rot\bot}}| \]

\[\overrightarrow{v_{rot\bot}}=\overrightarrow{a}+\overrightarrow{b}=\overrightarrow{w}·\sin \left( \theta \right) +\overrightarrow{v_{\bot}}·\cos \left( \theta \right) =\sin \left( \theta \right) ·\left( \overrightarrow{k}×\overrightarrow{v} \right) +\cos \left( \theta \right) \left( \overrightarrow{v}-\left( \overrightarrow{v}·\overrightarrow{k} \right) \overrightarrow{k} \right) \\ \overrightarrow{v_{rot}}=\overrightarrow{v_{||}}+\overrightarrow{v_{rot\bot}}=\left( \overrightarrow{v}·\overrightarrow{k} \right) \overrightarrow{k}+\sin \left( \theta \right) ·\left( \overrightarrow{k}×\overrightarrow{v} \right) +\cos \left( \theta \right) \left( \overrightarrow{v}-\left( \overrightarrow{v}·\overrightarrow{k} \right) \overrightarrow{k} \right) \\ =\cos \left( \theta \right) \overrightarrow{v}+\left( 1-\cos \left( \theta \right) \left( \overrightarrow{v}·\overrightarrow{k} \right) \overrightarrow{k} \right) +\sin \left( \theta \right) ·\left( \overrightarrow{k}×\overrightarrow{v} \right) \]

\( \overrightarrow{k} \)\( \overrightarrow{v} \)分別寫為列向量

\[\overrightarrow{k}=\left( \begin{array}{c} k_x\\ k_y\\ k_z\\ \end{array} \right) \]

\[\overrightarrow{v}=\left( \begin{array}{c} v_x\\ v_y\\ v_z\\ \end{array} \right) \]

\( \overrightarrow{v_{rot}}=R·\overrightarrow{v} \)
兩個式子

\[\left( \overrightarrow{v}·\overrightarrow{k} \right) \overrightarrow{k}=\overrightarrow{k}\left( \overrightarrow{v}·\overrightarrow{k} \right) =\overrightarrow{k}\left( \overrightarrow{k^T}·\overrightarrow{v} \right) \]

\[\overrightarrow{k}×\overrightarrow{v}=\left[ \begin{array}{c} k_yv_z-k_zv_y\\ k_zv_x-k_xv_z\\ k_xv_y-k_yv_x\\ \end{array} \right] =\left[ \begin{matrix} 0& -k_z& k_y\\ k_z& 0& -k_x\\ -k_y& k_x& 0\\ \end{matrix} \right] \left[ \begin{array}{c} v_x\\ v_y\\ v_z\\ \end{array} \right] \]

結合以上兩個式子可得,其中\(I\)為3×3的單位矩陣

\[R=I\cos \left( \theta \right) +\left( 1-\cos \left( \theta \right) \right) \left( \begin{array}{c} k_x\\ k_y\\ k_z\\ \end{array} \right) \left( \begin{matrix} k_x& k_y& k_z\\ \end{matrix} \right) +\sin \left( \theta \right) \left( \begin{matrix} 0& -k_z& k_y\\ k_z& 0& -k_x\\ -k_y& k_x& 0\\ \end{matrix} \right) \,\, \]

以下是比較通用的表示方式

\[R\left( n,\alpha \right) =\cos \left( \alpha \right) I+\left( 1-\cos \left( \alpha \right) \right) nn^T+\sin \left( \alpha \right) \left( \begin{matrix} 0& -n_z& n_y\\ n_z& 0& -n_x\\ -n_y& n_x& 0\\ \end{matrix} \right) \]

部分引用的博文

https://blog.csdn.net/unclerunning/article/details/70948696#齊次坐標系與平移

https://zhuanlan.zhihu.com/p/45757899


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM