二維cohen sutherland線裁剪演算法

2021-09-01 23:27:59 字數 2951 閱讀 4329

演算法**於計算機圖形學(第三版)

對於每條線段,針對其兩端點,都賦與「區域碼」的四位二進位製碼,每一位用來標識端點相對於相應裁剪矩形邊界的裡面還是外面。可以按任意的次序引用視窗邊界,下圖給出了從右到左編號,從1至4的順序。

在上圖中,位1表示裁剪視窗的左邊界,位2表示右邊界,位3表示下邊界,位4表示上邊界。任何碼位的值為1表示端點在相應視窗的左邊界的外面。類似的,碼位為0表示在內部或者邊界上。

每一裁剪視窗邊界將二維空間劃分成內部的兩個半空間。四個視窗邊界一起生成了九個區域,如下圖所示

四個視窗邊界一起生成了九個區域,上圖列出了這些區域的二維二進碼。

區域碼的位值通過將端點的座標值(x, y)與裁剪視窗邊界相比較而確定。如果x1 計算端點座標與裁剪邊界的差。

2 用各差值計算的符號位來設定區域碼中相應的值。

根據區域碼,可將線段分為三種情況:

1 兩個端點的區域碼均為0000的,完全在視窗界內。可用邏輯或判斷是否為0000,若為真,則完全位於區域之內。

2 兩個端點的端點的區域碼中,有一對相同位置為1的則完全落在裁剪區域之外。可用邏輯與判斷是否為0000,若為真,則完全位於裁剪區域之外。

3 其他情況需要進一步判斷與邊界是否有相交。

對於不能判斷為完全在視窗外或者視窗內的線段,需要測試其與視窗邊界的交點。這些線段可能穿過或不穿過視窗內部,需要多次求交運算,求交次數依賴於選擇裁剪邊界的次序。每次處理一條裁剪視窗邊界後,裁掉其中一部分後,餘下部分對照視窗的其餘邊界進行檢查,該過程一直進行到線段完全被裁剪掉或餘下的線段部分完全在裁剪視窗內。在後面的討論中,我們假定視窗邊界的處理次序是:左,右,下,上。要檢查一線段是否與某裁剪邊界相交,我們可以檢查其兩端點區域碼的相應位。如果其中乙個是1而另乙個是0,則相交。

下圖給出了兩條不能馬上判斷出完全在視窗內或視窗外的線段。p1和p2的線段區域碼是0100和1001。因此,p1在左邊界之內而p2在左邊界之外,接著我們計算交點位置p2'並裁掉p2到p2'的部分。餘下的線段部分位於右邊界的內部,因此我們接下來檢查下邊界。端點p1在下裁剪邊界之下面p2'在其上,因此求出在該邊界上的交點p1'。我們清除從p1到p1'的部分,再處理視窗的上邊界。在其上我們確定交點位置p2''。最後一步是裁掉上邊界之上的部分,並儲存從p1'到p2''的內部段。對於第二條線段,可以發現p3在左邊界的外部而p4在左邊界的內部。因此我們計算交點p3',並清除p3到p3'的段。通過對端點p3'和p4區域碼的測試,我們發現餘下的線段部分在裁剪視窗之下將其清除。

使用這一方法裁剪線段時,很可能要計算與所有四條裁剪邊界的交點,這依賴於線段端點如何處理以及按什麼 樣的邊界次序。為了減少求交計算,需要對該演算法進行改進。

線段與裁剪邊界的交點計算可以使用斜率截距式的直線方程。對於端點座標為(x0, y0)和(xend, yend)的直線段,與垂直邊界交點的y座標 可以由下列等式計算得到:

y = y0 + m(x-x0)

其中x值置為xwmin,線段的斜率根據m = (yend-y0)/(xend-x0)進行計算。同樣我們要尋找與水平邊界相交的交點,其x座標可以按下列等式進行計算:

x = x0 + (y-y0)/m 其中,y設為ywmin或ywmax。

原始碼實現:

class wcpt2d

const glint winleftbitcode = 0x01;

const glint winrightbitcode = 0x02;

const glint winbottombitcode = 0x04;

const glint wintopbitcode = 0x08;

inline glint inside(glint code)

inline glint reject(glint code1, glint code2)

inline glint accept(glint code1, glint code2)

glubyte encode(wcpt2d pt, wcpt2d winmin, wcpt2d winmax)

glubyte code = 0x00;

if(pt.x < winmin.x)

code = code|winleftbitcode;

if(pt.x > winmax.x)

code = code|winrightbitcode;

if(pt.y < winmin.y)

code = code|winbottombitcode;

if(pt.y > winmax.y)

code = code|wintopbitcode;

return code;

wcpt2d tmp;

tmp = *p1;

*p1 = *p2;

*p2 = tmp;

void swapcodes(glubyte *c1, glubyte *c2)

glubyte tmp;

tmp = *c1;

*c1 = *c2;

*c2 = tmp;

void lineclipcohsuth(wcpt2d winmin, wcpt2d winmax, wcpt2d p1, wcpt2d p2)

glubyte code1, code2;

glint done = false, plotline = false;

glfloat m;

while(!done)else if(reject(code1, code2))

done = true;

else else if(code1 & winrightbitcode)else if(code1 & winbottombitcode)else if(code1 & wintopbitcode){

if(p2.x != p1.x)

p1.x += (winmax.y - p1.y)/m;

p1.y = winmax.y;

if(plotline)

linebres(round(p1.x), round(p1.y), round(p2.x), round(p2.y));

二維陣列與二維指標

1.二維陣列的儲存是線性的,可以通過一維指標的方式訪問。如一下 int map 5 5 int mapd map 0 0 則 map i j mapd i 5 j 而利用二維陣列線性儲存的特性,可以將二維陣列當作一維指標方便的在函式之間傳遞 如 將乙個二維陣列賦值給乙個動態二維陣列,引數設定為一維指...

二維指標和二維陣列

二維指標和二維陣列有三種形式 1,type ptr 2,type ptr或者type prt 3,type prt 三種形式意思相近,也有區別。首先三種形式都能表示二維的資料結構。1,type ptr 表示乙個指向指標的指標 但是在一開始宣告的時候 type ptr ptr到底指向幾個指標是不知道的...

二維陣列與二維指標

一.指標與二維陣列 以martix 3 4 為例 1.二維陣列的本質 int martix 3 4 int martix 3 4 int 4 martix 3 令int 4 為type,type martix 3 為含有三個元素的陣列,每乙個元素型別為int 4 int 4 是乙個擁有4個int型別...