圖形變換一般是指將物體的幾何資訊經過放大、縮小、平移和旋轉等幾何變換後產生新的圖形。它總是與相關的座標繫緊密相連的。從相對運動的觀點來看,圖形變換既可以看作是圖形相對於座標系的變動,即:座標系固定不動,物體的圖形在座標系中的座標值發生變化;也可以看作是圖形不動,但是座標系相對於圖形發生了變動,從而使得物體在新的座標系下具有新的座標值。通常圖形變換隻改變物體的幾何形狀和大小,但是不改變其拓撲結構。
為了在電腦螢幕或繪圖器上輸出圖形, 通常必須在一個圖形中指定要顯示的部分或全部以及顯示裝置的輸出位置。可以在電腦螢幕上僅顯示一個地區,也可以顯示幾個地區,此時它們分別放在不同的顯示位置。在顯示或輸出圖形的過程中,可以對圖形進行平移、旋轉和縮放等幾何操作。如果圖形超出了顯示地區所指定的範圍,還必須對圖形進行裁剪。
本章主要內容包括:
觀察流程簡介;二維幾何變換視窗到視區的變換二維裁剪演算法 |
有關三維的圖形的變換和觀察流程等內容,我們將在後面的章節中介紹。
3.1 觀察流程
在電腦圖形學中,為了便於幾何造型和圖形的觀察與顯示,引入了一系列的座標系:
a 全局座標系:
通常全局座標系是一個三維笛卡兒座標系。它是一個全域座標系統,一般為右手座標系。該座標系主要用於圖形情境中的所有繪圖物件的空間定位、觀察者(視點)的位置和視線的定義等等。電腦圖形系統中所涉及的其它座標系基本上都是參照它進行定義的。
b 局部座標系:
為了幾何造型和觀察物體方便起見,獨立於全局座標系定義的二維或三維笛卡兒座標系稱為局部座標系。在局部座標系中定義的"局部"物體,通過指定局部座標系在全局座標系中的方位,利用幾何變換,就可以將"局部"定義的物體變換到全局座標系內,使之升級成為全局座標系中的物體。
c 觀察座標系:
觀察座標系通常是以視點的位置為原點,通過使用者指定的一個向上的觀察向量來定義的一個座標系,預設為左手座標系。觀察座標系主要用於從觀察者的角度對整個全局座標系內的繪圖物件進行觀察,以便簡化幾何物體在視平面(又成為成像面或投影面)的成像的數學演算。
d 視平面(成像面)座標系:
它是一個二維直角座標系統,主要用於計算物體在成像面上的投影。一般是通過指定視方向和視點到成像面之間的距離來定義成像面(投影面)。可進一步在投影面上定義一個稱之為視窗的矩形地區來實現部分成像。
e 螢幕座標系:
螢幕座標系也稱為裝置座標系,它主要用於某一特定的電腦圖形顯示裝置(如光柵顯示器)的表面的點的定義。在多數情況下,對於每一個具體的顯示裝置,都有一個單獨的裝置座標系。
在定義了成像視窗的情況下,可進一步在螢幕座標系統中定義稱為視區的有界地區,視區中的成像即為實際所觀察到的繪圖物件。換句話說,在全局座標系中要顯示的地區稱為視窗,而顯示器上相應的圖形輸出地區稱為視區(或視口)。將全局座標系中的一部分地區中的情境映射到裝置座標系的過程稱為觀察變換;將二維觀察變換簡單地稱為視窗到視區的變換,簡稱為窗視變換。它可以分為以下幾個步驟(見圖3.1):
在情境建模的過程中,常常需要定義局部座標系(或建模座標系),或對物體進行平移、旋轉和縮放等等幾何變換。為了方便設定視窗的大小和方向,我們可以在全局座標系中定義一個二維的觀察座標系,在觀察座標系中定義一個視窗(見圖3.2)。
圖3.2 全局座標系xwoyw和觀察座標系xvoyv
圖3.3 正常化的裝置座標系
另外,我們在正常化的座標系(取值範圍為0到1)下定義視區,3.3所示。可以定義多個視區。如果只定義了一個視區,則這個視區充滿整個單位正方形。通過二維裁剪和窗視變換,把視窗中的情境映射到視區中。正常化的座標系能夠保證觀察和變換獨立於輸出裝置。一旦情境變換到正常化的座標系之後,就可以通過簡單的映射把各個視區中的圖形輸出到具體裝置的繪圖區。
比例變換
比例變換是使圖形按在x和y座標軸方向分別按比例因素Sx和Sy放大或縮小的變換。它可以改變圖形的大小和形狀。
設平面上的一個點P的座標為(x, y,),經過比例變換後的座標是(x′, y′),3.3所示,其計算公式為:
其中,Sx和Sy為比例因素。上式可以用矩陣的形式表示為:
(3-2-1)
。
不同座標系的座標轉換
視窗到視區的座標變換
實際的視窗與視區的大小往往是不一樣的(3.7和3.8所示),為了在視區內正確地顯示幾何形體,必須將其從視窗變換到視區。
圖3.7 視窗
圖3.8 視區
設(xw,yw)是視窗中的任意一點,(xv,yv)是視區中對應的一點。則有如下關係:
化簡得:
(3-3-1)
其中:
(3-3-1)式可以用矩陣表示為
裁剪
裁剪
在電腦圖形顯示的過程中,往往需要確定圖形的哪些部分(包括點、線段、文字、多邊形等)落在顯示地區(即:視口或視區)之內,哪些部分落在顯示地區之外,以便只顯示位於顯示地區內的那部分圖形。裁剪的實質就是決定圖形中哪些部分位於指定的地區內。這需要進行幾何處理,以便去除落在指定地區之外的部分,保留位於指定地區以內的部分。這個過程稱為裁剪。最直觀的裁剪方法是把各種幾何圖素通過掃描轉換等技術離散成為點的集合,再逐點判斷其是否位於指定的地區內。那樣雖然簡單,但是效率太低,一般不可取。
3 線段的裁剪
對於一條給定的線段,其裁剪過程一般包括以下幾個部分:首先測試和判斷它是否完全落在裁剪區之內?如果不是,再判斷它是否完全落在裁剪區之外?然後,對於既不能確定完全落在裁剪區之內又不能確定完全落在裁剪區之外的線段,要計算它與一個或多個裁剪邊界的交點。最後,對線段的端點進行測試,對於兩個端點都落在裁剪地區內的線段就儲存起來,否則就予以去除,即裁剪之。
對於端點為(x1, y1)和(x2, y2)的線段,可以用參數方程表示:
當線段的某一個或兩個端點都位於裁剪地區之外時,通過該線段與裁剪邊界求交,可以得到參數t的值。如果交點的t值不在0和1之間,則該線段不在該裁剪邊界進入裁剪地區;否則,該線段就穿入或穿過了裁剪地區。通過去除裁剪地區以外的部分,可以實現線段的裁剪。為了減少求交計算、提高選擇和識別內部或外部線段的效率,設計有效裁剪演算法是非常重要的。
下面是我在網上找的文章,協助理解,看不懂就
算,電腦圖形學感覺有點難,
還好我高等數學,線性代數,機率,大學物理學得好,不然真是一點
都不懂了。
三維座標系
理解電腦3D圖形學中的座標系變換
要談座標系變換,那麼座標系有哪些呢?依次有:物體座標系,全局座標系,相機座標系,投影座標系以及螢幕座標系.我要討論的就是這些座標系間的轉換。
這些座標系不是憑空而來,他們都是為了完成電腦3D圖形學最最最基本的目標而出現.
電腦3D圖形學最最最基本的目標就是:將構建好的3D物體顯示在2D螢幕座標上.
初看好像就是將最初的物體座標系轉換到螢幕座標系就可以了呀,為什麼多出了全局座標系,相機座標系,投影座標 系。這是因為:在一個大世界裡有多個物體,而每個物體都有自己的座標系,如何表述這些物體間相對的關係,這個多出了全局座標系;如果只需要看到這個世界其 中一部分,這裡就多出了相機座標系;至於投影座標系那是因為直接將3D座標轉換為螢幕座標是非常複雜的(因為它們不僅維度不同,度量不同(螢幕座標一般都 是像素為單位,3D空間中我們可以現實世界的米,厘米為單位),XY的方向也不同,在2D空間時還要進行座標系變換),所以先將3D座標降維到2D座標, 然後2D座標轉換到螢幕座標。
理解3D圖形學的第一步:理解左手座標系與右手座標系
為什麼會有左手座標系與右手座標系之分?
在3D空間(沒錯!就是3D)中,所有2D座標系是等價的(就是通過一系列的仿射變換,可以互相轉換)
而3D座標系不是等價的,通過仿射變換,是無法將左手座標系轉換到右手座標系;也就是說,物體座標系用的就是左手座標系,全局座標系用的是右手 座標系,那麼物體可能就是不會是我們所希望的樣子了,可能是倒立的,也可能是背對著我們的,所以我們要區分左手座標系與右手座標系。也許在4D空間,左右 手座標系就可以互相變換了吧。
進入正題吧:
首先討論的是物體座標系->全局座標系
前面說了為了描述多個物體間相對的關係,這裡引進了全局座標系,所以全局座標系是個參考座標系。
這一步的目的將所有的物體的點都轉移到全局座標系,這裡主要涉及的是旋轉,縮放,平移等。
不過我將詳細說明為何及如何用矩陣來描述這些變換。
例:如果有兩個座標系C與C`, C`是C繞Z軸旋轉θ得到的。下面是各座標軸的變換:
如果是C座標系的點P(x, y, z),而在C`的表示就是
這時該如何建立矩陣呢? 答案就是區分你用的是行向量還是列向量.也許有人會問為什麼不區分是左手座標系還是右手座標系呢?因為C可以變換到C`,那麼他們一定是同在左手座標系或右手座標系,變換隻能在可以互相轉換的座標系之間進行。
如果你用的是行向量:由於行向量只能左乘矩陣(注意乘與乘以的區別)
所以矩陣形式應該是這樣
只有這樣,在左乘矩陣時才能得到上面P`的形式。
如果你用的是列向量: 由於列向量只能右乘矩陣(注意乘與乘以的區別)
所以矩陣形式應該是這樣
只有這樣,在右乘矩陣時才能得到上面P`的形式。
至於如何旋轉,縮放,平移我不在多說。
…………………………………覺得自己好像跑題了.還好這兩個座標系變換很簡單。
我們再討論全局座標系->相機座標系
引進相機的目的就是只需看到世界的一部分,而哪些是可以在相機裡看到的,就需要進行篩選。將物體轉換到相機座標系,這樣相機座標系進行篩選時就會簡單很多。這裡的重點是構建相機座標系。
物體座標系,全局座標系是美工在繪製時就定義好了的。而相機座標系是需要程式即時構建的。(當然這是通常情況下,如果你要建立一個世界,這個世界都是圍繞 你轉,要即時改變所有物體座標系,固定相機座標系(其實這時候相機座標系就是全局座標系),建立一個地心說的世界,我也沒辦法,你的思維也太不一樣了。)
如何構建相機座標系呢?首先我們要明確目標:我們是要構建3D座標系(好像是廢話),三個座標軸要互相垂直(也好像是廢話).
我們一般用UVN相機。例如:D3D的D3DXMatrixLookAtLH,D3DXMatrixLookAtRH,OGL的gluLookAt(右手座標系).
如何建立呢UVN相機呢? 我們就要利用叉積這個工具了:兩個不平行,不重疊的向量的叉積可以得到與這兩個向量互相垂直的向量。
如果有了相機的位置與目標的位置那麼我們可以確定一個Z軸(有人問為什麼是Z軸,因為物體的遠與近我們就習慣用Z值來表示的)。求Z軸時要注意 是左手座標系還是右手座標系,左右手座標系XY軸方向相同時,Z軸的方向相反。所以左手座標系是目標位置減去相機位置,而右手座標系則是相機位置減去目標 位置。記得normalize
這是我們要得到X與Y軸了。如何求X,Y軸呢?
一般方法是:
1、選擇一個臨時Y軸,
2、對臨時Y 與Z 軸進行叉積求得一個X軸
3、X軸再與Z軸進行叉積,得到一個Y軸。
有了XYZ就可以求出旋轉的相機矩陣了。
如何選擇一個Y軸呢?大多數情況下是(0,1,0),但是如果是相機位置E與目標位置T垂直,即(E-T=(0,+/-1,0)時),這時就不能用(0,1,0)了, 因為兩個平行向量的叉積是零向量,所以我們就要另選一個Y軸。
但是我覺得我們可以改變方法。
如果不能選Y軸,我們就選擇一個臨時X軸,這個臨時X軸就是(1,0,0)。
然後再對臨時X軸與Z軸進行叉積求得一個Y軸。
最後Y軸再與Z軸進行叉積,得到X軸。
這樣可以得到XYZ軸。
最後再根據行向量與列向量建立相機矩陣,再進行平移。
相機座標系->投影座標系.
投影的目的就是:降維.
兩種投影方式:正交投影與透視投影.
在我們TEAM中易穎已經寫了,我就不多說了,大家去看他的文章。
投影座標系->螢幕座標系
這是最簡單的。2D座標變換。也不多說。
轉載文章2:http://www.xingousi.com/computer/computergraphics.htm
電腦圖形學筆記(Part 1 ):電腦圖形學透視投影變換原理及一點和兩點透視
一、平行互分法
吳英凡所寫的《透視作圖的新方法——交點法體系》,其中談到的平行互分法,還是有道理的。
其實簡單點說,就是透視圖上的兩條“原來空間中的平行線”(在畫面上透視投影為相交於滅點),通過其中一條透視投影直線的端點畫另一條透視投影直線的平行線,必平行於畫面;這第三條線在畫面的透視投影的滅點必然在另一條透視投影線上。
二、透視投影變換學習總結
1、用多維數列表示低維空間座標,加深理解齊次座標標記法。
齊次座標標記法可以方便地運算,同時形狀不變。[x,y,z,0]表示一個無窮的點。
2、透視投影變換公式可以看成兩個矩陣的乘積,其中一個做透視變換,另外一個作正投影
保留的z'值的確切含義:指的是在完全作完透視投影變換之前,僅作透視投影之後的一條線.
它的幾何意義見李建平《電腦圖形學原理教程》第44頁。
3、左手和右手座標系的座標轉換
“視點座標系與一般的物體所在的全局座標系不同,它遵循左手法則,即左手大拇指指向Z正軸,與之垂直的四個手指指向X正軸,四指彎曲90度的方向是Y正軸。而全局座標系遵循右手法則的。”
4、視點座標系的透視變換公式很重要!!王飛著電腦圖形學書65頁
5、z'值的確切含義:指的是在完全作完透視投影變換之前,僅作透視投影之後的一條線
三、兩點透視的變換矩陣:
王飛編著《電腦圖形學基礎》的道理是:
從平面圖形的平移、旋轉、錯切開始推導,兩點透視的變換矩陣可以看成是:
物體本身有一個物體座標系——xw,yw,zw,視點作為原點又構成一個視點座標系——xe,ye,ze,物體座標系z軸朝上,y軸朝向遠處;而視點座標系y軸朝上,z軸朝向遠處。
這樣,最終的二點透視狀態可以這樣取得,首先把物體的位置的物體座標系標記法轉化為視點座標系的標記法(第一個矩陣),然後圍繞視點座標系的y軸旋轉(第二個矩陣),然後在x,y,z方向上平移(第三個矩陣),最後做透視變換(第四個矩陣),它的原文是把平移放在第二步,我在平移之前轉動,目的是保證了物體旋轉的軸在離它不遠的地方:
我使用的矩陣變換如下,原文是是把平移放在第二步:
[xw,yw,zw,1]* ***
最後所得結果是一個新的矩陣,
[xe ye ze 1]=[cos*xw-sin*yw+l zw+m 2sin*xw+2cos*yw+2n-d (sin*xw+cos*yw+n)/d]
把最後一項變成1,可得
=[(cos*xw-sin*yw+l)*d/(sin*xw+cos*yw+n (zw+m)*d/(sin*xw+cos*yw+n) (2sin*xw+2cos*yw+2n-d)*d/(sin*xw+cos*yw+n) 1 ]
即:
Xe= (cos*xw-sin*yw+l)*d/(sin*xw+cos*yw+n)
Ye=(zw+m)*d/(sin*xw+cos*yw+n)
Ze=(2sin*xw+2cos*yw+2*n-d)*d/(sin*xw+cos*yw+n)
實際上我的delphi程式裡面是這樣的:
xe:=trunc((cos(angle)*eee[ii][k].X-sin(angle)*eee[ii][k].Y+l)*d/(sin(angle)*eee[ii][k].X+cos(angle)*eee[ii][k].Y+n));
ye:=trunc((hhh[ii][k]+m)*d/(sin(angle)*eee[ii][k].X+cos(angle)*eee[ii][k].Y+n)); //透視變換
//ze可以考慮使用作為消隱
Ze:=trunc((2*sin(angle)*xw+2*cos(angle)*yw+2*n-d)*d/(sin(angle)*xw+cos(angle)*yw+n));
四、通過變換過的兩點透視的結果xe,ye,zw和*,反求原來的物體座標xw,yw
即:xe,ye,zw和已知,求出xw,yw
根據:
Xe= (cos*xw-sin*yw+l)*d/(sin*xw+cos*yw+n) (1)
Ye=(zw+m)*d/(sin*xw+cos*yw+n) (2)
Ze=(2sin*xw+2cos*yw+2n-d)*d/(sin*xw+cos*yw+n) (3)
(1)除以(2)得
Xe/Ye= (cos*xw-sin*yw+l)/ (zw+m)
(Xe*(zw+m))/Ye=cos*xw-sin*yw+l
(Xe*(zw+m))/(Ye* cos)=xw-tan*yw+l/cos
Xw=(Xe*(zw+m))/ (Ye* cos) - (ye*l)/(Ye* cos)+( sin*yw*ye)/ (Ye* cos)
Xw=(Xe*(zw+m)+ sin*yw*ye- ye*l)/ (Ye* cos) (4)
由(2)得
Ye*(sin*xw+cos*yw+n)= (zw+m)*d
Ye*(sin*xw)+ye* cos*yw+n*ye=(zw+m)*d
把(4)代入上式得
Ye* sin*(Xe*(zw+m)+ sin*yw*ye- ye*l)/ (Ye* cos)+ye* cos*yw+n*ye=(zw+m)*d
約去ye,得
sin*(Xe*(zw+m)+ sin*yw*ye- ye*l)/ cos+ye* cos*yw+n*ye=(zw+m)*d
tan*(Xe*zw+xe*m+ sin*yw*ye- ye*l) +ye* cos*yw+n*ye=(zw+m)*d
tan*Xe*zw+xe*m *tan- ye*l*tan+ sin*tan*yw*ye+ye* cos*yw+n*ye=(zw+m)*d
(sin*tan*ye+ye* cos)*yw+ tan*Xe*zw+xe*m *tan- ye*l*tan+n*ye=(zw+m)*d
最後得
Yw=[(zw+m)*d- tan*Xe*zw- xe*m *tan+ ye*l*tan- n*ye]/ (sin*tan*ye+ye* cos) (5)
而前面已經得到
Xw=(Xe*(zw+m)+ sin*yw*ye- ye*l)/ (Ye* cos) (4)
實際上相當於opengl裡面的逆變換,從滑鼠選中的螢幕位置來確定對應的三維空間中位置,opengl使用gluUnProject和gluUnProject4來計算。