利用矩陣進(jìn)行坐標(biāo)系轉(zhuǎn)換

原文鏈接

首先review一下矩陣的基礎(chǔ)知識(shí):

m×n 矩陣是排列在 m 行和 n 列中的一系列數(shù)。下圖顯示幾個(gè)矩陣。

可以通過(guò)將單個(gè)元素相加來(lái)加合兩個(gè)尺寸相同的矩陣。下圖顯示了兩個(gè)矩陣相加的示例。

m×n 矩陣可與一個(gè) n×p 矩陣相乘,結(jié)果為一個(gè) m×p 矩陣。第一個(gè)矩陣的列數(shù)必須與第二個(gè)矩陣的行數(shù)相同。例如,一個(gè) 4×2 矩陣與一個(gè) 2×3 矩陣相乘,產(chǎn)生一個(gè) 4×3 矩陣。

矩陣的行列的平面點(diǎn)可視為矢量。例如,(2, 5) 是具有兩個(gè)組件的矢量,(3, 7, 1) 是具有三個(gè)組件的矢量。兩個(gè)矢量的點(diǎn)積定義如下:

(a, b) ? (c, d) = ac + bd
(a, b, c) ? (d, e, f) = ad + be + cf

例如,(2, 3) 和 (5, 4) 的點(diǎn)積是 (2)(5) + (3)(4) = 22。(2, 5, 1) 和 (4, 3, 1) 的點(diǎn)積是 (2)(4) + (5)(3) + (1)(1) = 24。請(qǐng)注意,兩個(gè)矢量的點(diǎn)積是數(shù)字,而不是另一個(gè)矢量。另外請(qǐng)注意,只有當(dāng)兩個(gè)矢量的組件數(shù)相同時(shí),才能計(jì)算點(diǎn)積。

將 A(i, j) 作為矩陣 A 中第 i 行、第 j 列的項(xiàng)。例如,A(3, 2)是矩陣 A 中第 3 行、第 2 列的項(xiàng)。假定 A、B 和 C 是矩陣,且 AB = C,則 C 的項(xiàng)計(jì)算如下:

C(i, j) =(A 的第 i 行)?(B 的第 j 列)


下圖顯示了矩陣相乘的幾個(gè)示例。

以第二個(gè)等式為例,假設(shè)等式兩邊的矩陣分別是a、b、c,1 * 3的矩陣和3 * 2的矩陣相乘,得到的結(jié)果為1 * 2的矩陣。
其中c[0][0] = a[0][0] * b[0][0]+a[0][1] * b[1][0]+a[0][2] * b[2][0],c[0][1]=a[0][0] * b[0][1]+a[0][1] * b[1][1]+a[0][2] * b[2][1]。

矩陣的加法、乘法,可以用來(lái)做坐標(biāo)轉(zhuǎn)換。我們通常使用3 * 3(如果不需要旋轉(zhuǎn),則2*2的矩陣即可)的矩陣來(lái)做平面上的各種坐標(biāo)轉(zhuǎn)換,包括x/y軸的平移、旋轉(zhuǎn)?,F(xiàn)在來(lái)看一個(gè)簡(jiǎn)單的坐標(biāo)系轉(zhuǎn)換的例子:假設(shè)我們的客戶(hù)區(qū)分辨率是100 * 100,要在客戶(hù)區(qū)中心點(diǎn)畫(huà)一個(gè)點(diǎn),這個(gè)點(diǎn)的坐標(biāo)是(x, y)?,F(xiàn)在如果我們調(diào)整了客戶(hù)區(qū)分辨率為400 * 300,此時(shí)如果還需要保持這個(gè)點(diǎn)的相對(duì)位置不變,計(jì)算他的坐標(biāo)應(yīng)該是(x * 400 / 100, y * 300 / 100)。這個(gè)計(jì)算過(guò)程很簡(jiǎn)單,那么用矩陣操作應(yīng)該如何來(lái)實(shí)現(xiàn)呢?

我們將這個(gè)點(diǎn)視為一個(gè)1 * 2的矩陣,將其乘以一個(gè)2 * 2的矩陣,得出的仍然是一個(gè)1 * 2的矩陣,就是新的坐標(biāo)了。由于屏幕分辨率在x、y軸分別擴(kuò)大為原來(lái)的4倍和3倍,那么我們只要將點(diǎn)的x、y軸坐標(biāo)都擴(kuò)大到原來(lái)的4、3倍即可。公式如下:

等式左邊的第二個(gè)矩陣,就是用來(lái)實(shí)現(xiàn)坐標(biāo)轉(zhuǎn)換的矩陣。其中b[0][0]就是x軸的擴(kuò)大倍數(shù),b[1][1]就是在y軸上的擴(kuò)大倍數(shù)。這里面b[0][1]和b[1][0]永遠(yuǎn)是0。坐標(biāo)系的這種轉(zhuǎn)換,叫做線(xiàn)性變換。

OK??赐赀@個(gè)例子,是不是覺(jué)得用矩陣比直接計(jì)算還麻煩?嗯,對(duì)于這種簡(jiǎn)單的情況是這樣的。不過(guò)別急,繼續(xù)看坐標(biāo)系旋轉(zhuǎn)的情況,如果現(xiàn)在要求這個(gè)客戶(hù)區(qū)逆時(shí)針旋轉(zhuǎn)30度,要保持這個(gè)點(diǎn)的相對(duì)位置不變,他的新坐標(biāo)應(yīng)該是多少呢?

普通的計(jì)算的公式就不陳述了,這就是個(gè)初中幾何題目。我們直接來(lái)看怎樣通過(guò)矩陣操作實(shí)現(xiàn)。首先看公式:在二維空間中,旋轉(zhuǎn)可以用一個(gè)單一的角 θ 定義。作為約定,正角表示逆時(shí)針旋轉(zhuǎn)。關(guān)于原點(diǎn)逆時(shí)針旋轉(zhuǎn) θ 的矩陣是:

也就是說(shuō),逆時(shí)針旋轉(zhuǎn)30度的新坐標(biāo)就是:

當(dāng)然,除此之外,坐標(biāo)系還有平移,但是這個(gè)就簡(jiǎn)單了,只是一個(gè)簡(jiǎn)單的矩陣加法。比如(x, y)向右平移一個(gè)單位,用矩陣就是[x, y] + [1, 0]就是是(x + 1, y)。

下圖顯示了應(yīng)用于點(diǎn) (2, 1) 的幾個(gè)變換:

前圖中顯示的所有變換都是線(xiàn)性變換。某些其他變換(如平移)不是線(xiàn)性的,不能表示為與 2×2 矩陣相乘的形式。假定您要從點(diǎn) (2, 1) 開(kāi)始,將其旋轉(zhuǎn) 90 度,在 x 方向?qū)⑵淦揭?3 個(gè)單位,在 y 方向?qū)⑵淦揭?4 個(gè)單位??赏ㄟ^(guò)先使用矩陣乘法再使用矩陣加法來(lái)完成此操作。

后面跟一平移(與 1×2 矩陣相加)的線(xiàn)性變換(與 2×2 矩陣相乘)稱(chēng)為仿射變換,如上圖所示。放射變換(先乘后加)可以通過(guò)乘以一個(gè)3*3的矩陣來(lái)實(shí)現(xiàn),若要使其起作用,平面上的點(diǎn)必須存儲(chǔ)于具有虛擬第三坐標(biāo)的 1×3 矩陣中。通常的方法是使所有的第三坐標(biāo)等于 1。例如,矩陣 [2 1 1] 代表點(diǎn) (2, 1)。下圖演示了表示為與單個(gè) 3×3 矩陣相乘的仿射變換(旋轉(zhuǎn) 90 度;在 x 方向上平移 3 個(gè)單位,在 y 方向上平移 4 個(gè)單位):

在前面的示例中,點(diǎn) (2, 1) 映射到了點(diǎn) (2, 6)。請(qǐng)注意,3×3 矩陣的第三列包含數(shù)字 0,0,1。對(duì)于仿射變換的 3×3 矩陣而言,情況將總是如此。重要的數(shù)字是列 1 和列 2 中的 6 個(gè)數(shù)字。矩陣左上角的 2×2 部分表示變換的線(xiàn)性部分,第 3 行中的前兩項(xiàng)表示平移。

在使用3 * 3的矩陣做仿射變換時(shí)候,表示點(diǎn)的矩陣變成了一個(gè)1 * 3矩陣,這個(gè)矩陣中的最后一個(gè)值(a[0][2])必須設(shè)置成1。對(duì)于3 * 3矩陣b,其最后一列的值是多少是沒(méi)有關(guān)系的,因?yàn)樗麄儾粫?huì)影響結(jié)果中的前兩列。不過(guò)如上,經(jīng)常將他們?cè)O(shè)置為0,0,1。這一列對(duì)于坐標(biāo)轉(zhuǎn)換的結(jié)果并沒(méi)有任何影響,但是他們是必須的,因?yàn)榫仃囅喑吮仨殱M(mǎn)足開(kāi)篇所講的“相乘的兩個(gè)矩陣第一個(gè)矩陣的列數(shù)必須與第二個(gè)矩陣的行數(shù)相同”。


矩陣類(lèi)“Matrix”

在.Net Framework中,又一個(gè)矩陣類(lèi)“Matrix”。其內(nèi)置了點(diǎn)坐標(biāo)轉(zhuǎn)換(TransformPoints)、平移(Translate)、縮放(Scale)、旋轉(zhuǎn)(Rotate)方法。下面的示例創(chuàng)建了復(fù)合變換(先旋轉(zhuǎn) 30 度,再在 y 方向上縮放 2 倍,然后在 x 方向平移 5 個(gè)單位)的矩陣:

Matrix myMatrix = newMatrix(); 
myMatrix.Rotate(30); 
myMatrix.Scale(1, 2, MatrixOrder.Append); 
myMatrix.Translate(5, 0, MatrixOrder.Append); 

除了Matrix類(lèi)以外,.Net Framework中也有其他用于坐標(biāo)系轉(zhuǎn)換的類(lèi),比如System.Drawing.Graphics。具體用法請(qǐng)查閱相關(guān)文檔。

以上只是利用矩陣進(jìn)行平面坐標(biāo)系轉(zhuǎn)換的方法。如果是三位坐標(biāo)系,也是可以利用矩陣來(lái)操作的,但Matrix類(lèi)不行,因?yàn)槠浔旧淼亩ㄎ痪褪恰胺庋b表示幾何變換的 3 x 3 仿射矩陣”。


附上幾個(gè)三維空間的旋轉(zhuǎn)公式:

上面是分別繞單個(gè)軸旋轉(zhuǎn)的公式。復(fù)雜的旋轉(zhuǎn)可以通過(guò)這三個(gè)公式組合而成,任何 3 維旋轉(zhuǎn)矩陣都可以用這三個(gè)角 θx, θy, 和 θz 來(lái)刻畫(huà),并且可以表示為 roll, pitch 和 yaw 矩陣的乘積。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容