由于任何线段相对于凸多边形窗口进行裁剪后,落于窗口内的线段不会多于一条,因此,对线段的裁剪,只要求出其保留部分的两个端点即可。
任意平面线段和矩形窗口的位置关系只会有以下三种:
- 完全落在窗口内
- 完全落在窗口外
- 部分在内,部分在外
步骤实现
代码实现(基于VC 6.0)
1 /* 编码裁剪算法 */ 2 int TailorCohenSutherlandCode(int left, int right, int top, 3 int bottom, CPoint p) 4 { 5 int code = 0; 6 if(p.x<left) 7 code+=1; 8 if(p.x>right) 9 code+=2; 10 if(p.y>bottom) 11 code+=4; 12 if(p.y<top) 13 code+=8; 14 return code; 15 } 16 17 bool CGDrawDC::TailorCohenSutherland(int left, int right, int top, 18 int bottom, CPoint p1, CPoint p2, CPoint *pt1, CPoint *pt2) 19 { 20 int code1,code2,code3; 21 int tmx,tmy; 22 double slope; 23 CPoint tmp; 24 25 code1 = TailorCohenSutherlandCode(left,right,top,bottom,p1); 26 code2 = TailorCohenSutherlandCode(left,right,top,bottom,p2); 27 28 if(code1==0 && code2==0){ 29 *pt1 = p1; 30 *pt2 = p2; 31 return true; 32 } 33 code3 = code1 & code2; 34 35 if(code3!=0){ 36 *pt1 = *pt2 = CPoint(-1,-1); 37 return false; 38 }else{ 39 slope = (double)(p2.y-p1.y)/(double)(p2.x-p1.x); 40 41 if((code1 & 1) || (code2 & 1)){ 42 tmx = left; 43 tmy = (tmx-p1.x)*slope+p1.y; 44 if(tmy>=top && tmy<=bottom){ 45 tmp.x=tmx; tmp.y=tmy; 46 if(code1 & 1) 47 TailorCohenSutherland(left,right,top,bottom,tmp,p2,pt1,pt2); 48 if(code2 & 1) 49 TailorCohenSutherland(left,right,top,bottom,p1,tmp,pt1,pt2); 50 return true; 51 } 52 } 53 54 if((code1 & 2) || (code2 & 2)){ 55 tmx = right; 56 tmy = (tmx-p1.x)*slope+p1.y; 57 if(tmy>=top && tmy<=bottom){ 58 tmp.x=tmx; tmp.y=tmy; 59 if(code1 & 2) 60 TailorCohenSutherland(left,right,top,bottom,tmp,p2,pt1,pt2); 61 if(code2 & 2) 62 TailorCohenSutherland(left,right,top,bottom,p1,tmp,pt1,pt2); 63 return true; 64 } 65 } 66 67 if((code1 & 4) || (code2 & 4)){ 68 tmy = bottom; 69 tmx = (tmy-p1.y)/slope+p1.x; 70 if(tmx>=left && tmx<=right){ 71 tmp.x=tmx; tmp.y=tmy; 72 if(code1 & 4) 73 TailorCohenSutherland(left,right,top,bottom,tmp,p2,pt1,pt2); 74 if(code2 & 4) 75 TailorCohenSutherland(left,right,top,bottom,p1,tmp,pt1,pt2); 76 return true; 77 } 78 } 79 80 if((code1 & 8) || (code2 & 8)){ 81 tmy = top; 82 tmx = (tmy-p1.y)/slope+p1.x; 83 if(tmx>=left && tmx<=right){ 84 tmp.x=tmx; tmp.y=tmy; 85 if(code1 & 8) 86 TailorCohenSutherland(left,right,top,bottom,tmp,p2,pt1,pt2); 87 if(code2 & 8) 88 TailorCohenSutherland(left,right,top,bottom,p1,tmp,pt1,pt2); 89 return true; 90 } 91 } 92 } 93 return false; 94 }
参考来源: 《计算机图形学实用教程(第三版)· 苏小红 编著》