光柵圖形學算法
直線段的掃描轉換算法
主要有三個算法:1)數值微分法,2)中點畫線法,3)Bresenham算法
數值微分法(DDA)
引進圖形學中一個很重要的思想—增量思想。
當前步的y值等於前一步的 值加上斜率 ,這樣就把原來一個乘法和加法變成了一個加法。
改進方法:1)改進效率,2)直線方程類型方面進行改。
中點畫線法
每次在最大位移方向上走一步,而另一個方向是走步還是不走步要取決於中點誤差項的判斷。
如下面這張圖中,,每次在 方向上加1, 方向上加1或不變需要判斷。
改進方法:用增量思想改寫,使算法成爲整數加法的運算。
Bresenham算法
1)通過各行、各列像素中心構造一組虛擬網格線;
2)按照直線起點到終點的順序,計算直線與各垂直網格線的交點;
3)根據誤差項的符號確定該列象素中與此交點最近的像素;
4)把這個算法的效率也搞到整數加法。
Bresenham算法很像DDA算法(加斜率),但應用範圍廣泛。
總結
DDA:每步做一個加法。
中點畫線法:每步做一個整數加法。
Bresenham算法:更一般的算法,兼顧效率和適用性。
多邊形的掃描轉換
光柵圖形的一個基本問題是把多邊形的頂點表示轉換爲點陣表示。這種轉換稱爲多邊形的掃描轉換。
X-掃描線算法:按掃描線順序,計算掃描線與多邊形的相交區間,再用要求的顏色顯示這些區間的像素,即完成填充工作。關鍵問題是求交。
改進的多邊形掃描轉換算法思想:1)掃描線,2)增量
既考慮掃描線是連貫的,也要考慮到多邊形的連貫性。
新的數據結構:活性邊表(AET)
活性邊表的數據結構如下:
新邊表(NET),用來存放多邊形的邊的信息:
每做一次新的掃描線時,對已有的邊進行處理:
1.是否被去除掉;
2.如果不被去除,第二就要對它的數據進行更新;
3.看有沒有新的邊進來,插入排序。
上述做法避免了求交運算。
邊緣填充算法:
思想:按任意順序處理多邊形的每條邊。
步驟:
1)對每條邊求出該邊與掃描線的交點;
2)每一條掃描線上交點右方的所有像素取補;
問題:邊緣填充算法簡單,但對於複雜圖,每個像素可能被訪問多次。
解決:減少邊緣填充法訪問像素的次數,採用柵欄填充算法。
柵欄填充算法:
柵欄:一條過多邊形頂點且與掃描線垂直的直線。
做法:把多邊形分爲兩半,將交點與柵欄之間的像素取補
邊界標誌算法:
做法:對多邊形邊界所經過的象素打上標誌,將其圍住區域上色。
優勢:
1)不必建立維護邊表以及對它進行排序;
2)適合硬件實現;
3)執行速度比有序邊表算法快1到2個數量級。
區域填充算法
概念:將種子點擴展到整個區域內的過程,概念上和BFS非常相像。
表示方法:內點表示,邊界表示
連通分爲4向連通和8向連通
反走樣算法
走樣:
1)鋸齒形;
2)圖形中包含微小的物體,微小物體四捨五入被捨棄;
3)動畫中時隱時現,閃爍。
解決反採樣的方法:
1)採用分辨率更高的顯示設備,但以4倍的存儲和轉換時間爲代價;
2)採用某種形式的模糊,這裏面又分爲了非加權區域採樣方法和加權區域採樣方法。
非加權區域採樣方法
按面積給像素賦值,有以下缺點:
a.亮度與面積成正比,而與位置無關(面積可能一樣,相交部分更接近中心應該越亮);
b.直線上相鄰像素會有較大的灰度差;
加權區域採樣方法
根據相交區域與像素中心的距離來決定其權重。
可採用離散計算方法:
裁剪算法
屏幕顯示只是圖形的一部分,確定哪些落在顯示區之內,哪些落在顯示區之外,選擇的過程就成爲裁剪。
點的裁剪
比較簡單,直接進行比較邊界。
直線裁剪
直線裁剪有三種:1)Cohen-Sutherland算法,2)中點分割算法,3)Liang-Barsky裁剪算法
Cohen-Sutherland算法:每條線的端點都以4位二進制碼進行編碼,然後進行二進制的或、與運算,根據結果進行不同的操作。比較適合大部分線段完全可見/大部分線段完全不可見。
中點分割算法:通過二分逼近確定直線段與窗口的交點。
Liang-Barsky裁剪算法:
a.用參數方程表示一條直線:
b.把被裁減的直線段看成是一條有方向的線段,把窗口的四條邊分成兩類,入邊和出邊。
c.然後求取直線的參數方程與邊界直線的交點 值:。
Cohen-Sutherland算法和Liang-Barsky裁剪算法只能適用於矩形窗口。
多邊形的裁剪
Sutherland-Hodgeman多邊形裁剪算法:將多邊形邊界作爲一個整體,每次用窗口的一條邊對要裁剪的多邊形和中間結果多邊形進行裁剪,分而治之。
利用Sutherland-Hodgeman裁剪算法對凸多邊形進行裁剪可以獲得正確的裁剪結果,但是對凹多邊形會產生多餘的線段,如下圖:
文字裁剪
文字裁剪有三種:1)串精度裁剪,2)字符精度裁剪,3)筆劃/像素精度裁剪
串精度裁剪:當字符串中的所有字符都在裁剪窗口內時,就全部保留它,否則捨棄整個字符串。
字符精度裁剪:在進行裁剪時,任何與窗口有重疊或落在窗口邊界以外的字符都被裁剪掉。
筆劃/像素精度裁剪:將筆劃分解成直線段對窗口作裁剪。
三種不同的方式如下圖: