计算机图形学学习笔记(上)
第一章 導論
概念
計算機圖形學是一門研究如何利用計算機表示,生成,處理和顯示的圖形的學科。 代表著計算機工業的發展水平。
**圖形:**計算機圖形學的研究對象。
應用領域:
計算機游戲,計算機輔助設計(CAD or CAM),計算機藝術,虛擬現實,計算機輔助教學
圖形的分類:
圖形的表示方法
時,用形狀參數和屬性參數描述圖形的一種方法
示圖形的一種方法,描述的圖形常稱為圖像
相關學科
圖像顯示器的發展及工作原理
陰極射線管(CRT)
- 主要是由電子槍,聚焦系統,加速系統,偏轉系統,蔭罩板,熒光屏組成。
- 由于熒光粉具有余暉特性,電子束停止熒光屏后,熒光屏的亮度并不是立即消失,而是按指數規律衰減,圖像會逐漸變暗。
- 為了得到亮度穩定的圖像,需要不斷地刷新屏幕。當屏幕刷新頻率>=60HZ時,人的肉眼就不會感到圖像的閃爍。采用的屏幕刷新頻率為80HZ。
- 最小刷新頻率 = 1/余輝時間
光柵掃描器
光柵掃描器是一個畫點設備。,可以看成一個點陣單元發射器,并可控制每個點陣單元的顏色,這些點陣單元被稱為像素。
為了能在屏幕上顯示整個圖形,電子束需要從屏幕的左下角開始,沿著水平方向從左到右勻速掃描,到達第一行的屏幕右端之后電子束立即回到屏幕左端下一行的起點位置,再開始向右端掃描…一直到屏幕的右下角,顯示出一幀圖像。
存儲用于刷新的圖像信息。儲存像素點的顏色值。、
液晶顯示器
采用了液晶控制透光度技術來生成圖形的顯示器。
CRT顯示器具有價格低,亮度高,視角寬,使用壽命高的優點。而LCD顯示器則有體積小,重量輕,圖像無閃爍,輻射低的優點。缺點是視角稍窄,使用壽命短。
第二章 MFC繪圖基礎
繪圖工具類
- CGdiObject類:GDI繪圖工具的基類,一般不能直接使用。
- CBitmap:封裝了一個GDI位圖,提供位圖操作的接口。
- CBrush類:封裝了GDI畫刷,可以選作設備上下文的當前畫刷。畫刷用于填充圖形內部。
- CFont:封裝了GDI字體,可以選作設備上下文中的當前字體。
- CPallette:封裝了GDI調色板,提供應用程序和顯示器之間的顏色接口。
- CPen:封裝了GDI畫筆,可以選作設備上下文的當前畫筆。畫筆是用于繪制圖形邊界線
映射模式
返回值:原映射模式,用宏定義值來表示
參數:cx窗口x范圍的邏輯坐標,cy窗口y范圍的邏輯坐標;size 是窗口的SIZE或CSIZE對象。
返回值:原窗口范圍內的CSIZE對象。
3. 設置視區范圍函數
參數:cx視區x范圍的邏輯坐標,cy視區y范圍的邏輯坐標;size 是視區的SIZE或CSIZE對象。
返回值:原窗視區范圍內的CSIZE對象。
參數:x,y是窗口新原點坐標;point是窗口新原點的POINT結構或者CPoint對象。
返回值:原窗口原點的CPoint對象。
5. 設置視區原點函數
參數:x,y是視區新原點坐標;point是視區新原點的POINT結構或者CPoint對象。
返回值:原視區原點的CPoint對象。
注意點:窗口可以理解為一種邏輯坐標下的句型區域,而視區是設備坐標系下的矩形區域。根據窗口和視區的大小可以確定x方向和y方向的比例因子。
設置x軸正向向右,y軸正向向上,客戶區中心為中心原點。
pDC->setWindowExt(rect.Width(),rect.Height()); pDC->setViewportExt(rect.Width(),-rect.Height()); pDC->setViewportOrg(rect.Width()/2,rect.Height()/2);把一個100200的窗口中的圖形顯示到200px200px的視區中
窗口映射到視區中,y方向的比例為1(不變),x方向的比例為2 (放大2倍)。
一個邏輯單位在y方向映射為一個像素,x方向都映射為2個像素
保持X軸正向向右不變,當Y軸正向向下時 SetViewportOrg(x, y);與
SetWindowOrg(-x, -y);等價
當Y軸正向向上時 SetViewportOrg(x, y);與SetWindowOrg(-x, y);等價
使用GDI對象
Cpen NewPen,*OldPen; NewPen.CreatePen(PS_SOLID,1,RGB(0,0,255));//創建藍色畫筆 OldPen=pDC->SelectObject(&NewPen);//選入對象 ... pDC->SelectObject(OldPen);//保存原畫筆 NewPen.DeleteObject();第三章 基本圖形的掃描變換
直線的掃描變換
中點Bresenham算法原理
設當前屏幕上最逼近直線的像素點為Pi(xi,yi),下一個像素點Pi+1(xi+1,yi+1)相較于前一個像素點的坐標每次在主位移方向上+or-1,另一個方向上是否+or-1取決于中點偏差判別式的值。
若直線斜率絕對值<=1,直線在x方向上變化快,以x為主位移方向。否則,以y為主位移方向。
構造中點誤差項
從Pi(xi,yi)點出發選擇下一像素時,需將Pu和Pd的中點M(xi+1,yi+0.5)代入隱函數方程,構造中點誤差項di。
di = F(xi+1,yi+0.5) = yi+0.5-k(xi+1)-b
當di < 0時,中點M在直線的下方,Pu點離直線距離更近,下一像素點應選取Pu,即y向上走一步;di = 0時,選取兩點均可。否則,選取Pd點,y方向上不移動。
因此
遞推公式
直線的起點坐標為P0(x0,y0),x為主位移方向,因此第一個中點是M(x0+1,y0+0.5),相應的di的初始值為
算法實現
void Bresenham(int x0,int y0,int x1,int y1){int dx = x1-x0,dy = y1-y0;int x = x0,y = y0;double k = 1.0*dy/dx;double d;//繪制斜率k為0<=k<=1的直線 if(k >= 0 && k <= 1.0){//設置直線段的顏色 COLORREF clr = RGB(255,0,0); d = 0.5-k;//不包括中點 for(x = x0;x < x1;x++){pDC->SetPixel(Round(x),Round(y),clr);if(d < 0){y++;d += 1-k;}else{d-=k;}}} }園的掃描變換
算法原理
本算法是考慮45°的圓弧及第一象限x在[-,R/sqrt(2)]的1/8圓弧、
構造中點誤差判別式
遞推公式
(1)當di <0時,下一中點的坐標為:M(xi+2,yi-0.5)。所以下一步中點偏差判別式為:
(2)di >= 0時,下一中點的坐標為:M(xi+2,yi-1.5)。所以下一步的中點誤差判別式為:
中點偏差判別式的初始值
算法實現
//畫中點的Bresenham算法 void CTestView::MBCircle(double R,CDC *pDC){double d;d = 1.25-R;int x = 0,y = R;for(x = 0; x <= y;x++){//調用八分法畫圓子函數 CirclePoint(x,y,pDC);if(d < 0){d += 2*x+3; }else{d += 2*(x-y)+5;y--;}} }void CTestView::CirclePoint(int x,int y,CDC *pDC){//圓心坐標CP2 pc = CP2((p0.x+p1.x)/2.0,(p0.y+p1.y)/2.0);//定義圓的邊界顏色COLORREF clr = RGB(0,0,255);pDC->SetPixelV(Round(x+pc.x),Round(y+pc.y),clr);pDC->SetPixelV(Round(y+pc.x),Round(x+pc.y),clr);pDC->SetPixelV(Round(y+pc.x),Round(-x+pc.y),clr);pDC->SetPixelV(Round(x+pc.x),Round(-y+pc.y),clr);pDC->SetPixelV(Round(-x+pc.x),Round(-y+pc.y),clr);pDC->SetPixelV(Round(-y+pc.x),Round(-x+pc.y),clr);pDC->SetPixelV(Round(-y+pc.x),Round(x+pc.y),clr);pDC->SetPixelV(Round(-x+pc.x),Round(y+pc.y),clr); }橢圓的掃描變換
算法原理
構造上半部分I的中點偏差判別式
上半部分I的遞推公式
中點偏差判別式的初值
下半部分II的中點偏差判別式
下半部分II區域遞推公式
中點偏差判別式的初值:
算法實現
void CTestView::MBEllipse(CDC *pDC){int x,y,a,b;double d1,d2;x = 0,y = b;d1 = b*b+a*a*(-b+0.25);EllipsePoint(x,y,pDC);//橢圓前半段 while(b*b*(x+1)<a*a*(y-0.5)){if(d1 < 0){d1+=b*b*(2*x+3);}else{d1+=b*b*(2*x+3)+a*a*(-2*y+2);y--;}x++;EllipsePoint(x,y,pDC);}//橢圓后半段d2 = b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;while(y > 0){if(d2 <0){d2+=b*b*(2*x+2)+a*a*(-2*y+3);x++;}else{d2 += a*a*(-2*y+3);}y--;EllipsePoint(x,y,pDC);} } //四分法畫橢圓子函數 void CTestView::EllipsePoint(double x,double y,CDC *pDC){//橢圓中心坐標CP2 pc = CP2((p0.x+p1.x)/2.0,(p0.y+p1.y)/2.0);//定義橢圓的顏色COLORREF clr = RGB(0,0,255);pDC->SetPixelV(Round(x+pc.x),Round(y+pc.y),clr);pDC->SetPixelV(Round(-x+pc.x),Round(y+pc.y),clr);pDC->SetPixelV(Round(x+pc.x),Round(-y+pc.y),clr);pDC->SetPixelV(Round(-x+pc.x),Round(-y+pc.y),clr); }反走樣技術
- 走樣:由離散量表示連續量而引起的失真稱為走樣
- 反走樣:用于減輕走樣現象的技術。
第四章:多邊形填充
多邊形的掃描轉換
多邊形的表示
(1)頂點表示法
- 是用多邊形的頂點序列來描述
- 優點:特點是直觀,占內存少,易于進行幾何變換
- 缺點:沒有明確指出哪些像素在多邊形內,所以不能直接進行填充,需要對多邊形進行掃描轉換。
(2)點陣表示法
- 是用多邊形覆蓋的像素點集來描述。內部像素具有一種顏色,邊界像素和外部像素具有另外的顏色。
- 優點:是便于直接確定實面積圖形覆蓋的像素點,是多邊形填充所需要的表示形式。
- 缺少了多邊形頂點的幾何信息。
(3)多邊形的掃描變換
將多邊形的描述從頂點表示法變換到點陣表示法的過程,叫做多邊形的掃描轉換。即從多邊形的頂點信息出發,求出多邊形內部的各個像素點信息。
多邊形的填充
一般原理:
在掃描線從多邊形頂點的最小值ymin到多邊形頂點的最大值ymax移動過程中,重復上述工作,就可以完成多邊形的填充。
區域填充
- 對于用點陣表示的多邊形,內部像素具有一種顏色,邊界像素和外部像素具有另外的顏色,可以使用區域填充法。
- 區域是指一組相鄰而又具有相同屬性的像素,可以理解為多邊形的內部。
- 種子填充算法是從給定的種子位置開始,按填充顏色點亮種子的相鄰像素知道顏色不同的邊界像素為止。種子填充算法主要有4鄰接點算法和8鄰接點算法。
有效邊標填充算法
填充原理
按照掃描線從小到大的移動順序,計算當前掃描線與多邊形各邊的交點,然后按照交點用指定的顏色點亮區間內的所有像素,完成填充工作。
填充步驟
邊界像素處理原則:下閉上開,左閉右開
有效邊和有效邊表
多邊形內部與當前掃描線相交的邊稱為有效邊。
- 某條有效邊和不同掃描線的交點y坐標變化:yi+1 = yi + 1;
- 設有效邊的斜率為k。假定有效邊與當前掃描線yi的交點為(xi,yi),則有效邊與下一條掃描線yi+1的交點為(xi+1,yi+1)。
- 其中yi+1 = yi + 1;xi+1 = xi + 1/k = xi + dx/dy;
把有效邊按照與掃描線交點x坐標遞增的順序放入一個鏈表中,稱為有效邊表,有效邊表的結點如下所示:
有效邊的數據結構定義如下:
//有效邊類 class AET{public:AET();virtual ~AET();double x;int ymax;double k;AET *next; };邊表
有效邊表給出了掃描線和有效邊交點坐標的計算方法,但是沒有給出新邊出現的位置坐標,為了確定在哪條掃描線上插入了新邊,就需要構造一個邊表,用以存放掃描線上多邊形各條邊出現的信息。
邊表的表示方法:
- 把待填充的多邊形的各邊放入ET(邊表)
- 邊表為一個縱向掃描線鏈表。
- 鏈表的每個結點稱為桶,對應和多邊形相交的每一條掃描線。
桶的數據結構定義如下:
class Bucket{public:Bucket();virtual ~Bucket();//掃描線 int ScanLine();//桶上的邊表指針Bucket *next; };將每一邊放入與該邊最小y坐標相對應的桶中。
算法流程
- [a] 取出ET中當前掃描線y所對應的存儲桶中所有的邊,并插入有效邊表AET中,AET中的各邊按照Xmin值(當Xmin相等時,按照1/k遞增方向排序)。
- [b] 將AET中滿足y = Ymax的邊刪去。(下閉上開)
- [c] 將AET中的邊兩兩一次配對,即1,2邊為一對,3,4邊為一對,一次類推。當前掃描線y與每一條邊的交點正好是(x,y),填充每對交點之間的部分。(左閉右開)
- [d] 將AET剩下的每一條邊的x都變為x + 1/k。
- [e] 將當前的掃描線的坐標值y累加1。即y = y + 1。重復以上步驟。
邊緣填充算法
原理:求出多邊形的每條邊與掃描線的交點,然后將交點右側的所有像素顏色全部取為反色。按任意順序處理完多邊形所有邊后,就完成了多邊形填充任務。
區域填充算法
原理:用點陣表示的多邊形區域,如果其內部像素具有同一種顏色,而邊界像素具有另一種像素,可以使用種子填充算法進行填充。種子填充算法是從區域內任意一個種子像素開始,由內向外將填充色擴充到整個多邊形區域。
四連通域
從多邊形區域內任意一個種子像素點出發,通過訪問其左上右下這4個鄰接點可以遍歷區域內所有像素。
八連通域
從多邊形區域內任意一個種子像素點出發,通過訪問其左,左上,上,右上,右,右下,下,左下這8個鄰接點可以遍歷區域內所有像素點。
種子填充算法原理
先將種子像素入棧。種子像素為棧底像素,如果棧不為空,執行如下三步:
掃描線種子填充算法
先將種子像素入棧,種子像素為棧底像素,如果棧不為空,執行如下4步:
總結
以上是生活随笔為你收集整理的计算机图形学学习笔记(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 方差_python+方差_
- 下一篇: java int 运算符,java中各