多邊形裁剪一:Sutherland-Hodgman演算法
Sutherland-Hodgman演算法
Sutherland-Hodgman演算法也叫逐邊裁剪法,該演算法是薩瑟蘭德(I.E.Sutherland)和霍德曼(Hodgman)在1974年提出的。這種演算法採用了分割處理、逐邊裁剪的方法。
一,基本思想:
一次用視窗的一條邊裁剪多邊形。
考慮視窗的一條邊以及延長線構成的裁剪線該線把平面分成兩個部分:可見一側;不可見一側。多邊形的各條邊的兩端點S、P。它們與裁剪線的位置關係只有四種
情況(1)僅輸出1個頂點P;
情況(2)輸出0個頂點;
情況(3)輸出線段SP與裁剪線的1個交點I;
情況(4)輸出線段SP與裁剪線的1個交點I和1個終點P
1、已知:多邊形頂點陣列src,頂點個數n,
定義新多邊形頂點陣列dest。
2、賦初值:用變數flag來標識:
0表示在內側,1表示在外側。
3、對多邊形的n條邊進行處理,對當前點號的考慮為:0~n-1。
for(i=0;i<n;i++)
{
if(當前第i個頂點是否在邊界內側?)
{
if(flag!=0) /*前一個點在外側嗎?*/
{
flag=0;/*從外到內的情況,將標誌置0,作為下一次迴圈的前一點標誌*/
(dest + j) =求出交點; /*將交點dest放入新多邊形*/
j++;
}
(dest + j)= (src + i); /*將當前點srci放入新多邊形*/
j++;
}
else
{
if(flag==0) /*前一個點在內側嗎?*/
{
flag=1;/*從內到外的情況,將標誌置1,作為下一次迴圈的前一點標誌*/
(dest + j) =求出交點; /*將交點dest放入新多邊形*/
j++;
}
}
s= (src + i); /*將當前點作為下次迴圈的前一點*/
}
三,演算法特點:
Sutherland-Hodgeman多邊形裁剪演算法具有一般性,被裁剪多邊形可以是任意凸多邊形或凹多邊形,裁剪視窗不侷限於矩形,可以是任意凸多邊形。
上面的演算法是多邊形相對視窗的一條邊界進行裁剪的實現,對於視窗的每一條邊界依次呼叫該演算法程式,並將前一次裁剪的結果多邊形作為下一次裁剪時的被裁剪多邊形,即可得到完整的多邊形裁剪程式。
- //點在有向線段那側
- /*
- 向量叉積法
- 為簡單計,測試點表示為P點。假設視窗邊界方向為順時針,如圖中所示,對於其中任一邊界向量,從向量起點A向終點B看過去:
- 如果被測試點P在該邊界線右邊(即內側),AB×AP的方向與X-Y平面垂直並指向螢幕裡面,即右手座標系中Z軸的負方向。
- 反過來,如果P在該邊界線的左邊(即外側),這時AB×AP的方向與X-Y平面垂直並指向螢幕外面,即右手座標系中Z軸的正方向。
- 設:點P(x,y)、點A(xA,yA)、點B(xB,yB),
- 向量AB={(xB-xA),(yB-yA)},
- 向量AP={(x-xA),(y-yA)},
- 那麼AB×AP的方向可由下式的符號來確定:
- V=(xB-xA)·(y-yA)-(x-xA)·(yB-yA) (3-14)
- 因此,當V≤0時,P在邊界線內側;
- 而V>0時,P在邊界線外側。
- */
- static int _RtInSide(RtVector vector, RtPoint point)
- {
- return (vector.ep.x - vector.sp.x) * (point.y - vector.sp.y) - (vector.ep.y - vector.sp.y) * (point.x - vector.sp.x);
- }
- //多邊形點必須是順時針方向
- int rtPrunePSH(RtPoint* src, int num, RtPoint** dest, int* total)
- {
- int i = 0, j = 0, k = -1, flag = 0;
- RtPoint start, stop;//被剪裁多邊形
- RtPoint sp, ep;//剪裁視窗
- RtPoint* temp = NULL;
- temp = (RtPoint*)malloc(sizeof(RtPoint) * 3 * (*total));
- if (temp == NULL) return -1;
- sp = *(src + num - 1);
- for ( i = 0; i < num; i++)//剪裁視窗
- {
- ep = *(src + i);
- start = *((*dest) + *total - 1);
- flag = _RtInSide(rtVector(sp, ep), start) > 0 ? 0 : 1;
- for ( j = 0; j < *total; j++)//被剪裁的多邊形
- {
- stop = *((*dest) + j);
- if (_RtInSide(rtVector(sp, ep), stop) <= 0)//當前第i個頂點是否在邊界內側
- {
- if (flag == 0)/*前一個點在外側嗎?*/
- {
- flag = 1;/*從外到內的情況,將標誌置0,作為下一次迴圈的前一點標誌*/
- k++;
- CRtPoint<double> point;
- CRtPoint<int> st(sp.x, sp.y), et(ep.x, ep.y);
- CRtLine<int> v1(st, et);
- st.SetData(start.x, start.y);
- et.SetData(stop.x, stop.y);
- CRtLine<int> v2(st, et);
- v2.Intersect(v1,point);
- (temp + k)->x = point[0];/*將交點放入新多邊形*/
- (temp + k)->y = point[1];
- }
- k++;
- *(temp + k) = stop;/*將當前點pi放入新多邊形*/
- }
- else
- {
- if (0 != flag)/*前一個點在內側嗎?*/
- {
- flag = 0;/*從內到外的情況,將標誌置1,作為下一次迴圈的前一點標誌*/
- k++;
- CRtPoint<double> point;
- CRtPoint<int> st(sp.x, sp.y), et(ep.x, ep.y);
- CRtLine<int> v1(st, et);
- st.SetData(start.x, start.y);
- et.SetData(stop.x, stop.y);
- CRtLine<int> v2(st, et);
- v2.Intersect(v1,point);
- (temp + k)->x = point[0];/*將交點放入新多邊形*/
- (temp + k)->y = point[1];
- }
- }
- start = stop;/*將當前點作為下次迴圈的前一點*/
- }
- sp = ep;
- *total = k + 1;
- memcpy(*dest, temp, sizeof(RtPoint) * (*total));
- k = -1;
- }
- return 0;
- }
相關文章
- OpenGL 學習 06 多邊形偏移 裁剪 混合 抗鋸齒
- Python 實現任意多邊形的最大內切圓演算法_任意多邊形最大內切圓演算法Python演算法
- SVG <polygon> 多邊形SVGGo
- opencv多邊形逼近OpenCV
- IDL建立泰森多邊形
- 多邊形填充-活動邊表法
- [CSS LEARN]Border與多邊形CSS
- 【JAVA】多邊形重心計算Java
- 折線(Polyline)、多邊形(Polygon)Go
- matlab繪製正多邊形Matlab
- 單一div的正多邊形變換(純CSS)CSS
- 微信小程式-測試遊戲生成六邊多邊形微信小程式遊戲
- 視覺化學習:利用向量判斷多邊形邊界視覺化
- 計算任意多邊形的面積(Android)Android
- 一個Vue媒體多段裁剪元件Vue元件
- 【IDL】 自動構建泰森多邊形(Voronoi Polygon)Go
- CAD繪圖工具中的正多邊形命令繪圖
- 複雜多邊形的三角剖分
- 如何用SPSS繪製頻率多邊形圖SPSS
- 百度地圖繪製多邊形區域地圖
- 卡特蘭數關於凸多邊形的證明
- 基於C#的多邊形衝突檢測C#
- PCL(26)cropHull任意多邊形內部點雲提取
- 如何利用CSS寫一個六邊形?CSS
- PCB 銅皮(Surface)折線多邊形擴大縮小實現(第一節)
- JS實現滑鼠點選愛心&繪製多邊形&每日一言功能JS
- OpenGL 學習 05 花托(剔除 深度測試 多邊形模式)模式
- three.js cannon.js物理引擎之ConvexPolyhedron多邊形JS
- 微信小程式裁剪圖片成圓形微信小程式
- 如何判斷一個點在地圖上?如何判斷一個點在多邊形內?地圖
- 六邊形架構架構
- 用GDI+旋轉多邊形來繪製一個時鐘摸擬小程式
- AutoCAD C# 判斷多邊形與點的位置關係C#
- JS 射線法 判斷點是否在多邊形內部JS斷點
- 高德地圖多邊形圍欄例項:javaspringmvc+mysql地圖JavaSpringMVCMySql
- 蜂巢型六邊形A星尋路演算法unity完整流程演算法Unity
- Android 圓形頭像 相簿和拍照裁剪選取Android
- 微信小程式之裁剪圖片成圓形微信小程式
- [幾何]計算不規則多邊形的面積、中心、重心