opengl研究3.0 多邊形區域填充
dionysoslai([email protected])2014-06-22
所謂多邊形區域填充,就是將多邊形內部區域,全部已同樣色塊填充。注意:這裡討論的多邊形是簡單多邊形(即不考慮諸如五角星這種相交多邊形)。簡單多邊形,分為凹多邊形和凸多邊形。
多邊形區域填充有以下幾種方法:
1. 逐點掃瞄方法:
原理:掃瞄多邊形區域,逐點判斷點是否在多邊形內。
難點:在於如何判斷點是否在區域內;
常用如何判斷點是否在區域內方法:射線法、面積法。
面積法原理:取乙個點,連線多邊形各個點,根據三個點形成乙個三角形原理,我們可以求得三角形面積,判斷面積的大小,就可以判斷該店是否在多邊形內了。
射線法:這個方法,是我們這裡要重點講解的乙個方法。原理:取乙個點,向左或者向右做一條射線過去,判斷射線與多邊形的交點,根據多邊形交點熟練和本身多邊形邊情況,判斷點是否在多邊形內。
首先,射線從左向右,最左邊點肯定在多邊形區域為(我們這裡假定射線方向水平向左),那麼與多邊形相交第乙個點,必然表明射線右部分在多變形內,與多邊形相交第二個點,表明射線右部分在多邊形外面。因此,通過判斷射線與多變的交點奇偶性,判斷點是否在多邊形內。
這裡,有幾種特殊情況,如下圖所示:
圖a,射線與多變形頂點相交,頂點算乙個;圖b,射線與多邊形頂點的交點,不被計算在內(注意圖a和圖b的區別->頂點縱座標大小區別);圖c和圖d,射線與多邊形一條邊重合,這條邊被忽略不計。
因此,我們可以設計如下:取點向左做一條射線,1. 對於水平邊不做考慮;2. 對於多邊形頂點與射線交點情況,如果其縱座標是所屬邊較大頂點,則計數(參考圖a),否則不計數(圖b);3.對於點在多邊形上情況,可直接判斷點在多邊形內。
偽**如下:
count ← 0;
以p為端點,作從右向左的射線l;
for 多邊形的每條邊s
do if p在邊s上
then return true;
if s不是水平的
then if s的乙個端點在l上
if 該端點是s兩端點中縱座標較大的端點
then count ← count+1
else if s和l相交
then count ← count+1;
if count mod 2 = 1
then return true;
else return false;
相應**如下:注:我是在coco2dx2.3版本內測試的,因此可能移植要改些類名。
///@brief 判斷點是否在多邊形
///@param[in] p0--要判斷點, poly--多邊形點集合, numberofpoints--多邊形點數量
///@return 2---點在多邊形內, 1---點在多邊邊上,0---點不在多邊形內
///@author dionysoslai,[email protected]
///@retval
///@post
///@version 1.0
///@data 2014-04-11
int helloworld::pointisinpolygon(const ccpoint& p0, const ccpoint* poly, const unsigned int numberofpoints)
/// 判斷邊s是否是平行線;
if (poly[i].y != poly[(i+1)%(numberofpoints)].y)
break;
} if (pointisatline(poly[(i+1)%(numberofpoints)], leftpoint, rightpoint))
break;
} /// 如果邊s沒有端點在l上,則判斷s與l是否相交
if (segmentlineisintersect(leftpoint, rightpoint, poly[i], poly[(i+1)%(numberofpoints)]))
} while (0);
} }if (1 == count%2)
else
}
這裡有個pointisatline,是用來判斷點是否在邊上函式;segmentlineisintersect,是用來判斷兩條線段是否相交函式。可參考我的另一邊博文:計算幾何文件一系列文章(目前只寫了一篇,實際上是差不多寫了常用幾何演算法,還沒寫成博文。怪樓主太懶了。)
ok,逐點掃瞄判斷方法就是差不都這樣了。
2. 掃瞄線演算法
逐點掃瞄演算法,沒有充分考慮到畫素之間的連貫性,效率低。掃瞄線演算法,就是要利用畫素之間的連貫性,提高演算法效率。
所謂連貫性:有三個概念,1.邊的連貫性,ab邊與掃瞄線1相交,也可能與掃瞄線2相交;2.掃瞄線連貫性:當前掃瞄線與多邊形邊交點順序,可能與下一條掃瞄線交點情況一致或者類似;3.區間連貫性:同一區間畫素取同一顏色屬性。
掃瞄線原理:將整個多邊形區域掃瞄問題分解到一條條掃瞄線問題,只要完成每條掃瞄線的繪製,就實現了多邊形區域填充問題。一條掃瞄線與多邊形有偶數個交點(0就不算了),按順序每2個點形成乙個區間,只要繪製這個區間即可。
難點這與掃瞄線與多邊形邊交點判斷,這個是高中問題了,通過線段一般方程ax+by+c=0,兩立方程求解。不過這種方法,要計算各種引數,比較費時,更好的方法是分成各種情況分開討論(雖然比較麻煩),可以關注我的《計算幾何演算法》系類文章。
OpenGL 多邊形偏移
include gltools.h include glshadermanager.h include else define freeglut static include endif gluint list glint spinx 0 glint spiny 0 glfloat tdist 0....
求多邊形包圍區域
求多邊形包圍區域 已知單元格中,黑色部分為封閉邊緣,如何求出綠色部分也在包圍圈之內?有了上面的概念之後,只需要選定乙個點作為起點並沿邊緣走一圈再回到起點,通過判斷向左側拐和向右拐的次數,若左拐次數大於右拐次數則為左側包圍,反之為右側包圍。在給定的包圍順序下判定了左 右 側包圍,遍可獲得包圍區域 以上...
OpenGL 多邊形的鏤空
1.凸多邊形的定義是多邊形的內角均小於180 2.多邊形可以設定鏤空效果,使用glenable gl polygon stipple 開啟鏤空模式,之後使用glpolygonstipple 設定鏤空基本圖案。void glpolygonstipple const glubyte mask mask是...