[圖形學] Chp8.7.2 梁友棟-Barsky線段裁剪算法


  這節簡單介紹了梁友棟-Barsky裁剪算法的原理,只有結論並沒有過程,看過http://blog.csdn.net/daisy__ben/article/details/51941608這篇文章后,大概有了新的認識。

"

假設點P1P2W1W2的橫坐標分別是x1,x2,w1,w2,線段P1P2與藍色裁剪窗口W1W2(藍色的線之間)的存在公共部分(可見部分)的充要條件是:

max(min(x1,x2), min(w1,w2))≤ min(max(x1,x2), max(w1,w2))
即所謂左端點中大者<=右端點中的小者
"
 
  線段上的點滿足y=x1+u(x2-x1) = x1 + u*△x。 其中0<=u<=1。
  u1決定了線段在裁剪區域內的左側點,u2決定了在裁剪區域內右側的點。左點yl = x1 + u1 * △x,右點yr = x1 + u2 * △x,且必須滿足0 <= u1 <= u2 <= 1.
  這時,求解u1和u2是梁友棟-Barsky線段裁剪算法的目的,
 
 
 
 
 
 
 
(8.18)(8.19)
 
 
  對於書中的公式(8.18),求等式,即為線段與4個邊界的交點u值。
 
"
r不等於0的時候,對於上面四個不等式,當rk < 0時 ,u >= qk/rk,當rk>0時 u <= qk/rk,則點P才能位於裁剪窗口之內。同理,假如P已經落在了裁剪窗口之內,u一定大於等於所有rk<0對應的uk的最大值,而小於等於所有rk>0時對應的uk最小值。
"
  代碼中因此就有了函數GLint clipTest(GLfloat p, GLfloat q, GLfloat * u1, GLfloat * u2)。當p<0時,要獲得對應的u,如果這個u>u2,則舍棄;如果u<u2並且u>u1,則u1=u。若p>0時,如果這個u<u1則舍棄;如果u<u2,則u2=u。 傳入的p,q分別由公式(8.19)確定。由此計算最多4次來獲得u1和u2.
 
 1 #include <GLUT/GLUT.h>
 2 #include <iostream>
 3 #include "lineliangbarsk.h"
 4 #include "linebres.h"
 5 
 6 GLint clipTest (GLfloat p, GLfloat q, GLfloat * u1, GLfloat * u2)
 7 {
 8     GLfloat r;
 9     GLint returnValue = true;
10     
11     if(p < 0.0)
12     {
13         r = q / p;
14         if(r > *u2)
15         {
16             returnValue = false;
17         }
18         else
19         {
20             if(r > *u1)
21             {
22                 *u1 = r;
23             }
24         }
25     }
26     else
27     {
28         if(p > 0.0)
29         {
30             r = q / p;
31             if(r < *u1)
32             {
33                 returnValue = false;
34             }
35             else
36             {
37                 if(r < *u2)
38                 {
39                     *u2 = r;
40                 }
41             }
42         }
43         else
44         {
45             if(q < 0.0)
46             {
47                 returnValue = false;
48             }
49         }
50     }
51     return returnValue;
52 }
53 
54 void lineClipLiangBarsk(wcPt2D winMin, wcPt2D winMax, wcPt2D p1, wcPt2D p2)
55 {
56     GLfloat u1 = 0.0, u2 = 1.0, dx = p2.getx() - p1.getx(), dy;
57     
58     if(clipTest(-dx, p1.getx() - winMin.getx(), &u1, &u2))
59     {
60         if(clipTest(dx, winMax.getx() - p1.getx(), &u1, &u2))
61         {
62             dy = p2.gety() - p1.gety();
63             if(clipTest(-dy, p1.gety() - winMin.gety(), &u1, &u2))
64             {
65                 if(clipTest(dy, winMax.gety() - p1.gety(), &u1, &u2))
66                 {
67                     if(u2 < 1.0)
68                     {
69                         p2.setCoords(p1.getx() + u2 * dx, p1.gety() + u2 * dy);
70                     }
71                     if(u1 > 0.0)
72                     {
73                         p1.setCoords(p1.getx() + u1 * dx, p1.gety() + u1 * dy);
74                     }
75                     lineBres(round(p1.getx()), round(p1.gety()), round(p2.getx()), round(p2.gety()));
76                     std::cout << "liangbarsk : " << u1 << "," << u2 << std::endl;
77                     std::cout << "liangbarsk : " << p1.getx() << "," << p1.gety() << "," << p2.getx() << "," << p2.gety() << std::endl;
78                 }
79             }
80         }
81     }
82 }
View Code

https://github.com/p0e0o0p0l0e0/Computer_Graphics.git

c05938b3e669c1a04f86a54a69b5e2bb3066bd4e

參考:http://blog.csdn.net/daisy__ben/article/details/51941608

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM