計算機圖形學
計算機圖形學期末複習
第一章 緒論
- 計算機圖形學定義:計算機圖形學是研究通過計算機將資料轉換成圖形,並在專門顯示裝置上顯示的原理、方法和技術
第二章 計算機裝置及硬體系統
知識點
-
陰極射線管(CRT)
-
光柵掃描圖形顯示器:垂直回掃、水平回掃
-
液晶顯示器:
-
工作原理:利用液晶的光電顯示效應,通過施加電壓改變液晶的光學特性,從而造成對入射光的調製,使通過液晶的透射光或反射光受所加電壓的控制,達到顯示的目的。
(通過對液晶電場的控制可以實現光線的明暗變化,從而達到資訊顯示的目的)
-
-
光柵掃描圖形顯示子系統的結構(p35)
- 重要部件:幀緩衝儲存器、顯示控制器
- 幀緩衝儲存器(視訊記憶體):儲存畫素的顏色(灰度)的儲存器,可由顯示控制器直接訪問
- 顯示控制器:依據設定的顯示工作方式,讀取視訊記憶體裡的資料,並轉換成三原色並配以同步訊號給顯示器
注意事項
- 液晶顯示器的亮度沒有CRT的高
- 掃描轉換過程:畫素資訊從應用程式轉化並放入幀緩衝區的過程
第四章 圖形的表示與資料結構
- 基本元素:
- 定義:指可以用一定的幾何引數和屬性引數描述的最基本的圖形元素
- 組成:點、線、面、環、體等
- 幾何資訊與拓撲資訊:
- 幾何資訊:一般指形體在歐氏空間的位置和大小
- 拓撲資訊:形體各分量(點、線、面)的數目及相互間的連線關係(9中拓撲關係)
第五章 基本圖形生成演算法
-
直線掃描轉換:
數值微分法(DDA) 中點Bresenham演算法 Bresenham演算法 判別式 無 有,取中點,判別d 有,判別誤差e 取捨 四捨五入,有誤差 不做四捨五入 不作除法、無四捨五入 -
多邊形的掃描轉換/多邊形填充:
- 定義:從多邊形頂點表示到點陣表示
- x掃描線演算法:左閉右開的原則
- 改進的有效邊表演算法(y連貫性演算法):
-
邊緣填充演算法
-
區域填充演算法
-
反走樣:
- 走樣(圖形失真):離散量表示連續量而引起的失真
- 反走樣(圖形保真技術):用於減少或消除走樣的現象的技術
- 造成走樣的原因:直線段或曲線段的數學描述是連續的,而光柵顯示器上顯示的直線段或曲線段是由一些離散的、面積不為0的畫素點組成的
- 避免走樣的方法:
- 過取樣(後濾波):在高於顯示解析度的較高解析度下用點取樣方法計算,然後對幾個畫素的屬性進行平均,得到較低解析度下的畫素屬性
- 區域取樣(前濾波):根據圖形物件在每個畫素點上的覆蓋率來確定畫素點的亮度,這種計算覆蓋率的方法
第六章 二維變換級二維觀察
二維變換
- 基本幾何變換都是相對於座標原點和座標軸進行的
裁剪
-
直線段裁剪:編碼裁剪、中點分割裁剪、樑友棟演算法
-
多邊形裁剪:
第七章 三維變換及三維觀察
三維變換
- 注意:三維變換中,繞y軸的旋轉變換的特殊
三維觀察
(規定以逆時針旋轉方向為正向;三檢視:以Z軸正向朝上)
-
平面幾何投影:
- 透視投影:投影中心到投影面的距離有限
- 平行投影:投影中心到投影面的距離無限
- 正投影:三檢視、正軸側投影(對任意平面做投影)
- 斜投影:投影方向不垂直於投影面;投影方向和投影面成45°
投影在x0y平面
-
正軸測投影變換矩陣:
-
斜軸測投影變換矩陣:
- α=45°,β=30°或者45°
透視投影
- 投影矩陣:(中間的為透視變換矩陣)
-
主滅點:座標軸方向的平行線在投影面上形成的滅點
-
根據主滅點個數分為:一點透視、二點透視、三點透視
-
觀察座標系:
-
OpenGL中的變換
-
OpenGL視點變換函式:OpenGL視點變換函式用於確定觀察參考座標系,即確定視點的位置和觀察方向,預設情況視點位於原點,觀察方向為Z軸負向。
void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz,GLdouble upx, GLdouble upy, GLdouble upz);
-
OpenGL投影函式:
-
平行投影:
-
透視投影:
-
-
第八章 曲線與曲面
-
樣條曲線中的邊界條件:自由端、夾持端、拋物端
-
樣條曲線:
- 定義:指由多項式曲線段連線而成的曲線,在每段的邊界處滿足特定的連續條件
-
hermite插值樣條:
- 可以區域性調整,因為每個曲線段僅依賴於端點約束
- 當曲線的端點及端點的切線方向確定時,若給定不同的切線長度,將有不同形狀的Hermite曲線。
-
Bezier曲線/曲面:
- 是一個階數比控制點少一的多項式
- 只有第一個點和最後一個點在曲線上
- 不能對曲線形狀進行區域性控制,任意改變一控制點,整條曲線受影響
- Bezier曲線的性質:
- 端點:曲線總是通過起點和終點
- 一階導數:起點的切線位於前兩個控制點的連線上,終點的切線位於最後兩個的連線上
- 二階導數:曲線在起始點和終止點處的r階導數由起點或終止點和它們的r個相鄰的控制點決定
- 對稱性
- 凸包性:
- 幾何不變性:曲線形狀只與控制多邊形各頂點的相對位置有關,與座標系的選擇無關
- 變差減少性:曲線比控制多邊形更加光滑
- 控制頂點變化對曲線形狀的影響
-
B樣條曲線/曲面:
-
性質:
-
第九、十章 消隱、真實感圖形繪製
消隱
- 物體空間的消隱演算法:是將物體表面上的k個多邊形中的每一個面與其餘的k-1個面進行比較,精確地求出物體上每條稜邊或每個面的遮擋關係(多 邊形的區域排序演算法)
- 影象空間的消隱演算法:對螢幕的每一畫素進行判斷,以決定物體上哪個多邊形在該畫素點上是可見的(如深度快取演算法)
簡單光照模型
入射光=反射光+透射光+散射光+吸收光
簡單光反射模型=漫反射光+環境光+鏡面反射光
-
環境光:是光在物體和周圍環境之間多次反射的結果,即是來自周圍的環境對光的反射。環境光的特點是:它不是直接自光源,而是照射在物體上的光來自周圍各個方向,且又均勻地向各個方向反射
Ie=Ia·Ka
-
漫反射光:漫反射光是在光的照射下,物體表面發射的反射光均勻地射向各個方向
Id=Ip·Kd·cos(a)
-
鏡面反射光:鏡面反射是點光源照射在一個與物體光澤的表面(如鏡子、光亮的金屬等)有關的反射光。它的特點是光源來自一個光方向,並沿某特定方向(反射方向)離開
-
OpenGL繪製函式:
-
OpenGL消隱處理:
-
OpenGL光照與材質:
-
OpenGL紋理貼圖:
-
程式設計
編碼裁剪
//編碼定義
char clipCode(const GPoint2d &pt, const GRect2d &rc)
{
char code = 0;
if(pt.y() > rc.y1()) code |= 0x01;
else if(pt.y() < rc.y0()) code |= 0x02;
if(pt.x() > rc.x1()) code |= 0x04;
else if(pt.x() < rc.x0()) code |= 0x08;
return code;
}
//裁剪
bool gltLineClip2d(GPoint2d &pt0, GPoint2d &pt1, const GRect2d &rc)
{
char c0, c1;
while(true)
{
c0 = clipCode(pt0, rc);
c1 = clipCode(pt1, rc);
if((c0 & c1) != 0) return false;//按位與,兩點在同一個測
if(c0 == 0 && c1 == 0) return true;//兩點在視窗內
if(c0 == 0)
{
swap(pt0, pt1);
swap(c0, c1);
}
if(c0 & 0x01) // 在 Yt 之上
{
pt0.setX(pt0.x()-(pt0.y()-rc.y1())*(pt0.x()-pt1.x())/(pt0.y()-pt1.y()));
pt0.setY(rc.y1());
}
else if(c0 & 0x02) // 在 Yb 之下
{
pt0.setX(pt0.x()-(pt0.y()-rc.y0())*(pt0.x()-pt1.x())/(pt0.y()-pt1.y()));
pt0.setY(rc.y0());
}
else if(c0 & 0x04) // 在 Xr 之右
{
pt0.setY(pt0.y()-(pt0.x()-rc.x1())*(pt0.y()-pt1.y())/(pt0.x()-pt1.x()));
pt0.setX(rc.x1());
}
else if(c0 & 0x08) // 在 Xl 之左
{
pt0.setY(pt0.y()-(pt0.x()-rc.x0())*(pt0.y()-pt1.y())/(pt0.x()-pt1.x()));
pt0.setX(rc.x0());
}
}
}
Bezier曲線
//bezier的Castel推分演算法
double bezierCastel(double x[],int n,double t){
for(int r=1;r<n;r++){
for(int i=0;i<n-r;i++){
x[i] = (1-t)*x[i]+t*x[i+1];
}
}
return x[0];
}
void gltBezier2d(const GPoint2dArray &points){
if(points.count<2)
return;
double x0,y0,x1,y1;
double t,dt;
GPoint2d pt;
int n = points.count();
dt = 1.0f/(n*20);
double *x = new double[n];
double *y = new double[n];
pt = points.at(0);
x0 = pt.x();
y0 = pt.y();
for(int i = 0;i<n;i++){
pt = points.at(i);
x[i] = pt.x();
y[i] = pt.y();
}
for(t=dt;t<1;t+=dt){
x1 = bezierCastel(x,n,t);
y1 = bezierCastel(y,n,t);
gltLine2d(x0,y0,x1,y1);
x0 = x1;
y0 = y1;
}
pt = points.at(n-1);
gltLine2d(x0,y0,pt.x().pt.y());
delete []x;
delete []y;
}
B樣條曲線
//b樣條基函式
void cubicBSplineBase(int begin,const GPoint2dArray &points,double t,GPoint &pt){
float fh1 = (-t*t*t+3*t*t-3*t+1)/6;
float fh2 = (3*t*t*t-6*t*t+4)/6;
float fh3 = (-3*t*t*t+3*t*t+3*t+1)/6;
float fh4 = (t*t*t)/6;
GPoint pt0 = points.at(begin);
GPoint pt1 = points.at(begin+1);
GPoint pt2 = points.at(begin+2);
Gpoint pt3 = points.at(begin+3);
pt.setX(fh1 * pt0.x() + fh2 * pt1.x() +fh3 * pt2.x() + fh4 * pt3.x());
pt.setY(fh1 * pt0.y() + fh2 * pt1.y() +fh3 * pt2.y() + fh4 * pt3.y());
}
void gltBSpline2d(const GPoint2dArray &points){
if(points.count()<4)
return ;
double x0,y0;
double t,dt;
GPoint pt;
int n = points.count();
dt = 0.05;
for(int i=0;i<n-3;i++){
cubicBSplineBase(i,points,0,pt);
x0 = pt.x();
y0 = pt.y();
for(t=dt;t<1;t+=dt){
cubicBsplineBase(i,points,t,pt);
gltLine2d(x0,y0,pt.x(),pt.y());
x0 = pt.x();
y0 = pt.y();
}
cubicBSplineBase(i,points,t,pt);
gltLine2d(x0,y0,pt.x(),pt.y());
}
}