青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

小四的海市蜃樓
Never surrender to complexity
posts - 21,comments - 59,trackbacks - 0
多年之前在WPS做算法研究的時候寫的常用計算幾何算法

  1 #ifndef __GLOBAL_H__
  2 #define __GLOBAL_H__
  3 
  4 #include <vector>
  5 #include <iterator>
  6 #include <math.h>
  7 
  8 #define MIN_VALUE        1E-5
  9 #define MIN_DISTANCE    0.001f
 10 #define MIN_AREA        0.000001f
 11 #define PI                3.14159265358979f
 12 #define min(a, b)  (((a) < (b)) ? (a) : (b)) 
 13 #define max(a, b)  (((a) > (b)) ? (a) : (b)) 
 14 
 15 struct POINT2D
 16 {
 17     float x, y;
 18     bool operator == (const POINT2D& pt)
 19     {
 20         return(sqrt((x-pt.x)*(x-pt.x)+(y-pt.y)*(y-pt.y))<MIN_DISTANCE); 
 21     }
 22 };
 23 
 24 struct POINT3D
 25 {
 26     float x, y, z;
 27     bool operator == (const POINT3D& pt)
 28     {
 29         return(sqrt((x-pt.x)*(x-pt.x)+(y-pt.y)*(y-pt.y)+(z-pt.z)*(z-pt.z))<MIN_DISTANCE); 
 30     }
 31 }; 
 32 
 33 struct LINESEG
 34 { 
 35     POINT2D s; 
 36     POINT2D e; 
 37     LINESEG()
 38     {
 39 
 40     }
 41     LINESEG(POINT2D a, POINT2D b) 
 42     { 
 43         s = a; 
 44         e = b;
 45     } 
 46 };
 47 
 48 struct LINE           // 直線的解析方程 a*x+b*y+c=0  為統一表示,約定 a >= 0 
 49 
 50     float a; 
 51     float b; 
 52     float c; 
 53     LINE(float d1 = 1, float d2 = -1, float d3 = 0) 
 54     { 
 55         a = d1; 
 56         b = d2; 
 57         c = d3;
 58     } 
 59 }; 
 60 
 61 template <typename T>
 62 struct POLYGON
 63 {
 64     int type;            //-1未知, 0凹多邊形, 1凸多邊形, 3順時針, 4逆時針
 65     std::vector<T> data;
 66     T& operator = (const T& polygon)
 67     {
 68         type = polygon.type;
 69         data.clear();
 70         std::copy(polygon.data.begin(), polygon.data.end(), std::back_inserter(data));
 71         return *this;
 72     }
 73 };
 74 
 75 typedef POLYGON<POINT2D> POLYGON2D;
 76 typedef POLYGON<POINT3D> POLYGON3D;
 77 
 78 struct SUBPATH
 79 {
 80     //type為0表示只有一個簡單多邊形,1表示環形多邊形
 81     //環形多邊形約定,第一個多邊形是外多邊形,順時針,后面的是內多邊形,逆時針
 82     //并且都是簡單多邊形,彼此之間不相交
 83     int type;          
 84     float z;
 85     std::vector<POLYGON2D> polygons;    
 86     SUBPATH()
 87     {
 88         z = 0.0f;
 89     }
 90     SUBPATH& operator = (const SUBPATH& polypath)
 91     {
 92         type = polypath.type;
 93         polygons.clear();
 94         std::copy(polypath.polygons.begin(), polypath.polygons.end(), std::back_inserter(polygons));
 95         return *this;
 96     }
 97 };
 98 
 99 typedef std::vector<SUBPATH> POLYPATH;
100 
101 enum beveltype
102 {
103     circle = 0,        //
104     angle,            //角度
105     coolSlant,        //冷色斜面
106     cross,            //十字形
107     artDeco,        //藝術裝飾
108     relaxedInset,    //松散遷入
109     convex,            //凸起
110     divot,            //草皮
111     slope,            //斜面
112     hardEdge,        //硬邊緣
113     riblet,            //棱紋
114     softRound,        //柔圓
115 };
116 
117 struct DRECT 
118 {
119     float    left;
120     float    top;
121     float    right;
122     float    bottom;
123     float    height;
124     float    width;
125 };
126 
127 
128 
129 #endif // __GLOBAL_H__
130 


  1 // -------------------------------------------------------------------------
  2 //    文件名        :    geometry.h
  3 //    創建者        :    dingjie
  4 //    創建時間    :    2007-5-29 
  5 //    功能描述    :    計算幾何常用算法
  6 //
  7 // -------------------------------------------------------------------------
  8 #ifndef __GEOMETRY_H__
  9 #define __GEOMETRY_H__
 10 
 11 #include <vector>
 12 #include <iterator>
 13 #include <math.h>
 14 #include <vector>
 15 #include <assert.h>
 16 #include "Global.h"
 17 
 18 #define MAGNETIC_DIST    0.003f
 19 
 20 // -------------------------------------------------------------------------
 21 //    r=multiply(p0, p1, p2),得到(p2-p0)*(p1-p0)的叉積 ,根據叉積判斷拐點走向
 22 //    r>0: p2在矢量p0p1的順時針方向; 
 23 //    r=0:p0p1p2三點共線; 
 24 //    r<0: p2在矢量p0p1的逆時針方向 
 25 // -------------------------------------------------------------------------
 26 inline float Multiply(const POINT2D& p0,const POINT2D& p1,const POINT2D& p2) 
 27 { 
 28     return((p2.x-p0.x)*(p1.y-p0.y)-(p1.x-p0.x)*(p2.y-p0.y)); 
 29 } 
 30 // -------------------------------------------------------------------------
 31 //    兩點歐式距離
 32 // -------------------------------------------------------------------------
 33 inline float Dist(const POINT2D& p1,const POINT2D& p2)              
 34 { 
 35     return(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y))); 
 36 } 
 37 
 38 // -------------------------------------------------------------------------
 39 //    求p0到經p1p2確定的直線的距離
 40 // -------------------------------------------------------------------------
 41 inline float PtToLineDist(const POINT2D& p0, const POINT2D& p1, const POINT2D& p2)
 42 {
 43     return fabs(Multiply(p0, p1, p2))/Dist(p1, p2); 
 44 }
 45 // -------------------------------------------------------------------------
 46 //    判斷兩條線段是否有交點
 47 // -------------------------------------------------------------------------
 48 inline BOOL LineSegIntersect(const LINESEG& ls1, const LINESEG& ls2)
 49 {
 50     return((max(ls1.s.x, ls1.e.x)>=min(ls2.s.x, ls2.e.x))&&                 //排斥測試 
 51         (max(ls2.s.x, ls2.e.x)>=min(ls1.s.x, ls1.e.x))&& 
 52         (max(ls1.s.y, ls1.e.y)>=min(ls2.s.y, ls2.e.y))&& 
 53         (max(ls2.s.y, ls2.e.y)>=min(ls1.s.y, ls1.e.y))&& 
 54         (Multiply(ls2.s, ls1.e, ls1.s)*Multiply(ls1.e, ls2.e, ls1.s)>=0)&&  //跨立測試
 55         (Multiply(ls1.s, ls2.e, ls2.s)*Multiply(ls2.e, ls1.e, ls2.s)>=0)); 
 56 }
 57 
 58 inline BOOL LineSegIntersect(const POINT2D& pt1, const POINT2D& pt2, 
 59                              const POINT2D& pt3, const POINT2D& pt4)
 60 {
 61     return((max(pt1.x, pt2.x)>=min(pt3.x, pt4.x))&&                 //排斥測試 
 62         (max(pt3.x, pt4.x)>=min(pt1.x, pt2.x))&& 
 63         (max(pt1.y, pt2.y)>=min(pt3.y, pt4.y))&& 
 64         (max(pt3.y, pt4.y)>=min(pt1.y, pt2.y))&& 
 65         (Multiply(pt3, pt2, pt1)*Multiply(pt2, pt4, pt1)>=0)&&  //跨立測試
 66         (Multiply(pt1, pt4, pt3)*Multiply(pt4, pt2, pt3)>=0)); 
 67 }
 68 
 69 // -------------------------------------------------------------------------
 70 //    如果返回值大于0,則p0在p1->p2左邊(逆時針),如果小于0在右邊,否則共線
 71 // -------------------------------------------------------------------------
 72 inline float LeftOrRight(const POINT2D& p0, const POINT2D& p1, const POINT2D& p2)   
 73 {   
 74     return Multiply(p1, p0, p2);  
 75 }   
 76 
 77 // -------------------------------------------------------------------------
 78 // 根據已知兩點坐標,求過這兩點的直線解析方程: a*x+b*y+c = 0  (a >= 0)  
 79 // -------------------------------------------------------------------------
 80 inline LINE GetLine(const POINT2D& p1, const POINT2D& p2) 
 81 { 
 82     LINE tl; 
 83     int sign = 1; 
 84     tl.a = p2.y - p1.y; 
 85     if( tl.a < 0) 
 86     { 
 87         sign = -1; 
 88         tl.a = sign * tl.a; 
 89     } 
 90     tl.b = sign * (p1.x - p2.x); 
 91     tl.c = sign * (p1.y * p2.x - p1.x * p2.y); 
 92     return tl; 
 93 } 
 94 
 95 // -------------------------------------------------------------------------
 96 // 如果兩條直線 l1, l2相交,返回TRUE,且返回交點p
 97 // -------------------------------------------------------------------------
 98 inline BOOL GetLineIntersect(const LINE& l1, const LINE& l2, POINT2D& p)  
 99 { 
100     float d = l1.a * l2.b - l2.a * l1.b; 
101     if (fabs(d) < MIN_VALUE)  // 不相交
102     {
103         return FALSE;
104     }
105     p.x = (l2.c * l1.b - l1.c * l2.b) / d; 
106     p.y = (l2.a * l1.c - l1.a * l2.c) / d; 
107     return TRUE;
108 } 
109 // -------------------------------------------------------------------------
110 // 計算距離線段sp->ep距離為distance的平行線,正值的時候
111 // 取線段右邊的,也就是多邊形內的,負值的時候相反。
112 // -------------------------------------------------------------------------
113 inline LINE GetParallelLine(const POINT2D& sp, const POINT2D& ep, float distance, BOOL& bSucceeded)
114 {
115     bSucceeded = TRUE;
116     LINE line1 = GetLine(sp, ep);
117     LINE line(line1.a, line1.b, 0);
118     if ((fabs(line.a) <= MIN_VALUE) && (fabs(line.b) <= MIN_VALUE))
119     {
120         bSucceeded = FALSE;
121         return line;
122     }
123     
124     //設line1方程為ax+by+c=0,則平行線方程為ax+by+m=0
125     //距離d=fabs(m-c)/sqrt(a*a+b*b) 
126     float m1, m2;
127     float f = distance * sqrt(line1.a * line1.a + line1.b * line1.b);
128     m1 = line1.c + f;
129     m2 = line1.c - f;
130     
131     line.c = (ep.y - sp.y < 0) ? m1 : m2;
132 
133     return line;
134 }
135 // -------------------------------------------------------------------------
136 // r=dotmultiply(p1,p2,op0),得到矢量(p1-p0)和(p2-p0)的點積,如果兩個矢量都
137 // 非零矢量r<0:兩矢量夾角為銳角;r=0:兩矢量夾角為直角;r>0:兩矢量夾角為鈍角 
138 // -------------------------------------------------------------------------
139 inline float DotMultiply(const POINT2D& p1, const POINT2D& p2, const POINT2D& p0) 
140 { 
141     return ((p1.x - p0.x) * (p2.x - p0.x) + (p1.y - p0.y) * (p2.y - p0.y)); 
142 } 
143 // -------------------------------------------------------------------------
144 // 點和線段的位置關系
145 // -------------------------------------------------------------------------
146 inline float Relation(const POINT2D& p, const LINESEG& l) 
147 { 
148     LINESEG tl(l.s, p); 
149     return DotMultiply(tl.e, l.e, l.s) / (Dist(l.s, l.e) * Dist(l.s, l.e)); 
150 } 
151 // -------------------------------------------------------------------------
152 // 求點p到線段l所在直線的垂足 P 
153 // -------------------------------------------------------------------------
154 inline POINT2D Perpendicular(const POINT2D& p, const LINESEG& l) 
155 { 
156     float r = Relation(p, l); 
157     POINT2D tp; 
158     tp.x = l.s.x + r * (l.e.x - l.s.x); 
159     tp.y = l.s.y + r * (l.e.y - l.s.y); 
160     return tp; 
161 } 
162 // -------------------------------------------------------------------------
163 // 求點p到線段l的最短距離,并返回線段上距該點最近的點np 
164 // 注意:np是線段l上到點p最近的點,不一定是垂足 
165 // -------------------------------------------------------------------------
166 inline float PtToLinesegDist(const POINT2D& p, const LINESEG& l, POINT2D &np) 
167 { 
168     float r = Relation(p, l); 
169     if(r < 0) 
170     { 
171         np = l.s; 
172         return Dist(p, l.s); 
173     } 
174     else if(r > 1) 
175     { 
176         np = l.e; 
177         return Dist(p, l.e); 
178     } 
179     np = Perpendicular(p, l); 
180     return Dist(p, np); 
181 } 
182 // -------------------------------------------------------------------------
183 // sp在平行線上的垂足,距離sp為distance的點
184 // -------------------------------------------------------------------------
185 inline POINT2D GetRightPt(const POINT2D& sp, const POINT2D& ep, float distance)
186 {
187     POINT2D pt;
188     BOOL b;
189     LINE line = GetParallelLine(sp, ep, distance, b);
190     assert(b);
191     LINE ppline(line.b, -line.a, line.a*sp.y-line.b*sp.x);//過sp點的垂線
192     b = GetLineIntersect(line, ppline, pt);
193     assert(b);
194     return pt;
195 }
196 // -------------------------------------------------------------------------
197 // 返回頂角在o點,起始邊為os,終止邊為oe的夾角
198 // (非U角,單位:弧度)  
199 // -------------------------------------------------------------------------
200 inline float GetAngle(const POINT2D& o, const POINT2D& s, const POINT2D& e) 
201 { 
202     float cosfi, fi, norm; 
203     float dsx = s.x - o.x; 
204     float dsy = s.y - o.y; 
205     float dex = e.x - o.x; 
206     float dey = e.y - o.y; 
207     
208     cosfi = dsx * dex + dsy * dey; 
209     norm = (dsx * dsx + dsy * dsy) * (dex * dex + dey * dey); 
210     cosfi /= sqrt(norm); 
211     
212     if (cosfi >=  1.0 ) return 0; 
213     if (cosfi <= -1.0 ) return PI; 
214     
215     fi = acos(cosfi); 
216     return fabs(fi);
217 }
218 // -------------------------------------------------------------------------
219 // 計算pt1繞pt2逆時針旋轉alpha弧度以后的點
220 // -------------------------------------------------------------------------
221 inline POINT2D PtRotate(const POINT2D& pt1, const POINT2D& pt2, float alpha)
222 {
223     float cosine = cos(alpha);
224     float sine = sin(alpha);
225     POINT2D pt = {(pt1.x-pt2.x)*cosine-(pt1.y-pt2.y)*sine+pt2.x, 
226         (pt1.x-pt2.x)*sine+(pt1.y-pt2.y)*cosine+pt2.y};
227     return pt;
228 }
229 // -------------------------------------------------------------------------
230 // 計算多邊形面積(帶符號);輸入頂點按順時針排列時,
231 // 返回正值;否則返回負值
232 // -------------------------------------------------------------------------
233 inline float PolygonArea(const POLYGON2D& polygon) 
234 { 
235     int nCount = polygon.data.size();
236     if (nCount < 3) 
237         return 0.0f; 
238     float s = polygon.data[0].y * (polygon.data[1].x - polygon.data[nCount-1].x); 
239     for (int i = 1; i < nCount; i++) 
240     {
241         s += polygon.data[i].y * (polygon.data[(i+1)%nCount].x - polygon.data[(i-1)].x); 
242     }
243     return s / 2; 
244 } 
245 // -------------------------------------------------------------------------
246 // 測試多邊形頂點序列按時針方向
247 // -------------------------------------------------------------------------
248 inline BOOL AntiClockwise(const POLYGON2D& polygon) 
249 { 
250     return (PolygonArea(polygon) < 0); 
251 } 
252 // -------------------------------------------------------------------------
253 // 多邊形是否自交叉
254 // -------------------------------------------------------------------------
255 inline BOOL SelfIntersect(const POLYGON2D& polygon, DRECT& rect, int& a, int& b)
256 {
257     rect.left = rect.bottom = 1E5f;
258     rect.right = rect.top = 1E-5f;
259     const std::vector<POINT2D>& pts = polygon.data;
260     int nCount = pts.size();
261 
262     for (int i = 0; i < nCount; i ++)
263     {
264         rect.left = min(rect.left, pts[i].x);
265         rect.bottom = min(rect.bottom, pts[i].y);
266         rect.right = max(rect.right, pts[i].x);
267         rect.top = max(rect.top, pts[i].y);
268         for (int j = i+2; j < nCount; j ++)
269         {
270             if ((0==i)&&((j+1)%nCount==0))
271                 continue;
272             if (LineSegIntersect(pts[i], pts[(i+1)%nCount], pts[j], pts[(j+1)%nCount]))
273             {
274                 a = i;
275                 b = j;
276                 return TRUE;
277             }
278         }
279     }    
280     return FALSE;
281 }
282 
283 inline BOOL SelfIntersect(const POLYGON2D& polygon)
284 {
285     const std::vector<POINT2D>& pts = polygon.data;
286     if (pts.size()<=3)
287         return FALSE;
288     int nCount = pts.size();
289 
290     for (int i = 0; i < nCount-1; i ++)
291     {
292         for (int j = i+2; j < nCount; j ++)
293         {
294             if ((j+1)%nCount==i)
295                 continue;
296             if (LineSegIntersect(pts[i], pts[(i+1)%nCount], pts[j], pts[(j+1)%nCount]))
297                 return TRUE;
298         }
299     }    
300     return FALSE;
301 }
302 
303 // -------------------------------------------------------------------------
304 // 根據頂點序列計算邊距為distance的緩沖頂點的坐標  
305 // -------------------------------------------------------------------------
306 inline BOOL GetBufPoints(std::vector<POINT2D>& bufpts, const std::vector<POINT2D>& pts, float distance)
307 {
308     if (fabs(distance)<MIN_VALUE)
309     {
310         bufpts = pts;
311         return TRUE;
312     }    
313     
314     int nCount = pts.size();
315     bufpts.resize(nCount);
316     
317     for (int i = 0; i < nCount; i ++)
318     {    
319         int nPrev = (i+nCount-1)%nCount;
320         int nNext = (i+1)%nCount;
321         BOOL succeed;
322         LINE line1 = GetParallelLine(pts[nPrev], pts[i], distance, succeed);
323         assert(succeed);
324         LINE line2 = GetParallelLine(pts[i], pts[nNext], distance, succeed);
325         assert(succeed);
326         if (!succeed)
327             return FALSE;
328         BOOL b = GetLineIntersect(line1, line2, bufpts[i]);
329         //assert(b);
330         if (!b)
331         {
332             bufpts[i] = GetRightPt(pts[i], pts[nNext], distance);
333         }
334     }
335     return TRUE;
336 }
337 // -------------------------------------------------------------------------
338 // 設置多邊形凹凸性
339 // -------------------------------------------------------------------------
340 inline void SetPolyProt(POLYGON2D& polygon)
341 {
342     const std::vector<POINT2D>& pts = polygon.data;
343     int nCount = pts.size();
344     if (nCount<4) 
345     {
346         polygon.type = 1;
347         return;
348     }
349     
350     float a,b;   
351     a = LeftOrRight(pts[0], pts[1], pts[2]);   
352     for(int i = 0; i < nCount;  i ++)
353     {   
354         int nNext = (i+1)%nCount;
355         int nNextNext = (nNext+1)%nCount;
356         b = LeftOrRight(pts[i], pts[nNext], pts[nNextNext]);   
357         if(a * b < 0)
358         {
359             polygon.type = 0;
360             return;
361         }
362     }      
363     polygon.type = 1;
364 }
365 // -------------------------------------------------------------------------
366 // 計算當前多邊形即pPoints,第一個有頂點合并的等距線的距離
367 // bInside為True,取多邊形內方向,反之取多邊形外方向
368 // -------------------------------------------------------------------------
369 inline float GetMinJoinWidth(const std::vector<POINT2D>& pPoints, BOOL bInside, int& idx)
370 {
371     int nCount = pPoints.size();
372     float minwidth = 1E10;  
373     std::vector<POINT2D> bufpts;
374     GetBufPoints(bufpts, pPoints, 1);
375     for (int i = 0; i < nCount; i ++)
376     {
377         int nNext = (i+1)%nCount;
378         LINE line1 = GetLine(bufpts[i], pPoints[i]);
379         LINE line2 = GetLine(bufpts[nNext], pPoints[nNext]);
380         POINT2D ispt;
381         BOOL bIntersect = GetLineIntersect(line1, line2, ispt);
382         if(!bIntersect)
383             continue;
384 
385         float f = LeftOrRight(ispt, pPoints[i], pPoints[nNext]);
386 
387         if (bInside)
388         {
389             if (f > 0)  continue;   //多邊形內方向
390         }
391         else
392         {
393             if (f < 0)  continue;   //多邊形外方向
394         }
395 
396         //求此點到直線距離
397         float d = PtToLineDist(ispt, pPoints[i], pPoints[nNext]);
398 
399         if (d < minwidth)
400         {
401             minwidth = d;
402             idx = i;
403         }
404     }
405     
406     return minwidth;
407 }
408 // -------------------------------------------------------------------------
409 // 根據四個控制點計算一條bezier曲線,hits為點數
410 // -------------------------------------------------------------------------
411 inline void GetBezier(std::vector<POINT2D>& bezier, const POINT2D cp[4], int hits)
412 {
413     assert(hits>1);
414     
415     bezier.resize(hits);
416     int i = 0;
417     float X,Y;
418     float x[4];
419     float y[4];
420     
421     for(i = 0; i < 4; i ++)
422     {
423         x[i] = cp[i].x;
424         y[i] = cp[i].y;
425     }
426     
427     float a0,a1,a2,a3,b0,b1,b2,b3,t,t2,t3,dt;
428     a0 = x[0];
429     a1 = -3 * x[0] + 3 * x[1];
430     a2 = 3 * x[0] - 6 * x[1] + 3 * x[2];
431     a3 = -x[0] + 3 * x[1] - 3 * x[2] + x[3];
432     b0 = y[0];
433     b1 = -3 * y[0] + 3 * y[1];
434     b2 = 3 * y[0] - 6 * y[1] + 3 * y[2];
435     b3 = -y[0] + 3 * y[1] - 3 * y[2] + y[3];
436     dt = 1.0f / (hits-1);    
437     
438     for (i = 0; i < (hits-1); i ++)
439     {
440         t = i * dt;
441         t2 = t * t;
442         t3 = t * t2;
443         X = (a0 + a1 * t + a2 * t2 + a3 * t3);
444         Y = (b0 + b1 * t + b2 * t2 + b3 * t3);
445         bezier[i].x = X;
446         bezier[i].y = Y;
447     };
448     bezier[hits-1].x = cp[3].x;
449     bezier[hits-1].y = cp[3].y;
450     return;    
451 }
452 // -------------------------------------------------------------------------
453 // 合并vector里距離超近的相鄰點,只保留其中一個,另一個刪除
454 // -------------------------------------------------------------------------
455 inline BOOL ClipPolygon(std::vector<POINT2D>& pts)
456 {
457     //刪除距離近的相鄰頂點
458     int nPtCnt = pts.size();
459     BOOL bCliped = TRUE;
460     while (bCliped)
461     {
462         bCliped = FALSE;
463         int nCount = pts.size();
464         int nCurr = nCount - 1;
465         for (int i = nCount - 1; i >= 0 ; i --)
466         {
467             if (pts.size()<=2)
468             {
469                 return (nPtCnt > pts.size());
470             }
471             int nPrev = (nCurr+pts.size()-1)%pts.size();
472             float d = Dist(pts[nCurr], pts[nPrev]);
473             if (d <= MAGNETIC_DIST)
474             {
475                 pts.erase(pts.begin() + nCurr);
476                 bCliped = TRUE;
477             }
478             else
479             {
480                 int nNext = (nCurr+1)%pts.size();
481                 float d = PtToLineDist(pts[nNext], pts[nCurr], pts[nPrev]);
482                 if(d <= MAGNETIC_DIST) // 接近平行 
483                 {
484                     pts.erase(pts.begin() + nCurr);
485                     bCliped = TRUE;
486                 }            
487             }
488             nCurr --;
489             if (nCurr == -1)
490                 nCurr = pts.size() - 1;
491         }
492     }
493     return (nPtCnt > pts.size());
494 }
495 
496 //判斷點p是否在線段l上
497 inline int OnLineseg(const LINESEG l, const POINT2D p)
498 {
499     return( (Multiply(l.e,p,l.s)==0)&&
500         (((p.x-l.s.x)*(p.x-l.e.x)<0 )||( (p.y-l.s.y)*(p.y-l.e.y)<0)));
501 }
502 //射線法判斷點q與多邊形polygon的位置關系,要求polygon為簡單多邊形,(頂點按逆時針排列?)   
503 //如果點在多邊形內:    返回2   
504 //如果點在多邊形邊上:    返回1   
505 //如果點在多邊形外:    返回0    
506 inline int PtInPolygon(const POLYGON2D& polygon,const POINT2D& point)
507 {
508     int nCount = polygon.data.size();
509     const std::vector<POINT2D>& data = polygon.data;
510     int i,c=0;   
511     LINESEG line,edge;   
512     line.s = line.e = point;   
513     line.s.x = 1e10;   
514     for(i = 0; i < nCount; i++)   
515     {   
516         edge.s = data[i];   
517         edge.e = data[(i+1)%nCount];   
518         if(OnLineseg(edge,point))   
519             return 1;                //如果點在邊上,返回1 
520         if (edge.s.y==edge.e.y)        //平行線,跳過
521             continue;
522         
523         if(min(edge.s.y, edge.e.y)!=point.y && LineSegIntersect(line,edge))   
524             c++;    
525     }   
526     if(c%2 == 1)  
527         return 2;  
528     else  
529         return 0; 
530 }
531 //反轉多邊形
532 inline void Reverse(POLYGON2D& polygons)
533 {
534     POLYGON2D tmp = polygons;
535     polygons.data.clear();
536     std::copy(tmp.data.rbegin(), tmp.data.rend(), std::back_inserter(polygons.data));
537 }
538 
539 #endif    //__GEOMETRY_H__

C++
posted on 2012-12-05 23:07 小四 閱讀(4763) 評論(0)  編輯 收藏 引用 所屬分類: 圖形圖像與計算幾何
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            尤物yw午夜国产精品视频| 欧美精品在线观看| 伊人成人在线| 欧美成人在线影院| 欧美啪啪成人vr| 亚洲综合精品自拍| 久久精品国产99国产精品| 亚洲精品极品| 欧美日韩一区二区三区视频| 亚洲欧美电影在线观看| 欧美主播一区二区三区| 亚洲国产视频一区二区| 一本色道久久综合狠狠躁的推荐| 欧美色区777第一页| 久久精品网址| 欧美国产日韩精品| 性欧美videos另类喷潮| 久久性天堂网| 午夜精品久久久久久99热| 久久久精品五月天| 亚洲一区二区三区精品在线| 欧美亚洲视频在线看网址| 亚洲日本视频| 午夜精品久久久久久久99热浪潮| 亚洲成人在线视频播放| 一本久久a久久精品亚洲| 国自产拍偷拍福利精品免费一| 亚洲国产精品免费| 国产一区二区三区在线观看精品| 亚洲国产高清视频| 国内精品一区二区三区| 夜夜嗨av一区二区三区中文字幕 | 欧美顶级艳妇交换群宴| 国产精品porn| 亚洲青色在线| 亚洲电影视频在线| 欧美一区二区三区免费观看| 夜夜嗨av一区二区三区| 久久亚洲精品视频| 久久九九全国免费精品观看| 欧美日韩国产首页在线观看| 久久综合久久综合久久| 国产日产欧美a一级在线| 亚洲精品免费观看| 亚洲精品乱码久久久久久蜜桃91| 欧美在线视频观看| 欧美在线不卡| 国产精品午夜久久| 亚洲午夜精品视频| 亚洲香蕉伊综合在人在线视看| 蜜臀a∨国产成人精品| 久久免费少妇高潮久久精品99| 国产精品成人在线| 一区二区三区日韩欧美精品| 99re8这里有精品热视频免费 | 亚洲视频一区二区在线观看 | 亚洲国产另类久久久精品极度| 亚洲欧美精品| 欧美激情精品久久久久久变态 | 亚洲人成在线免费观看| 久久这里只有精品视频首页| 久久视频一区二区| 红桃视频国产精品| 久久裸体视频| 欧美黑人在线观看| 亚洲精品乱码久久久久久日本蜜臀 | 亚洲一区二区三区四区五区午夜| 亚洲一区影院| 国产精品久久久久一区二区三区| 亚洲天堂网在线观看| 欧美一区影院| 精品av久久久久电影| 久久综合九色九九| 亚洲人成在线影院| 亚洲综合日韩| 国产综合亚洲精品一区二| 久久人人爽国产| 亚洲国产精品视频一区| 一区二区三区高清| 国产精品萝li| 久久久国产精彩视频美女艺术照福利| 久久婷婷国产综合国色天香| 亚洲国产一区二区精品专区| 欧美精品色综合| 亚洲欧美日韩区| 免费永久网站黄欧美| 夜夜嗨av一区二区三区四区| 欧美性色综合| 久久久亚洲午夜电影| 亚洲欧洲精品一区二区精品久久久| 亚洲视频精品| 国产一区二区三区在线播放免费观看 | 亚洲福利视频三区| 亚洲宅男天堂在线观看无病毒| 国产精品一二三| 美女视频黄免费的久久| 99精品欧美一区| 另类国产ts人妖高潮视频| 亚洲网站在线看| 精品999在线观看| 国产精品进线69影院| 久久综合999| 亚洲综合日本| 亚洲人成在线观看网站高清| 久久久精品视频成人| 一区二区三区欧美在线| 国语自产精品视频在线看抢先版结局 | 亚洲国产成人高清精品| 午夜精品久久久久久久久久久久| 亚洲第一二三四五区| 国产精品青草综合久久久久99| 看片网站欧美日韩| 香港久久久电影| 亚洲免费观看视频| 亚洲第一二三四五区| 久久精品国产96久久久香蕉| 久久精品99国产精品日本| 中日韩高清电影网| 91久久国产综合久久| 老司机久久99久久精品播放免费 | 欧美一区二区在线免费观看| 夜夜嗨av一区二区三区网站四季av| 国产综合香蕉五月婷在线| 国产精品日韩欧美| 欧美天天在线| 欧美日韩免费观看一区=区三区| 久久综合图片| 久久久精品日韩欧美| 香蕉久久夜色精品国产| 亚洲视频网在线直播| av成人免费在线观看| 日韩视频不卡中文| 亚洲精品在线免费| 亚洲人久久久| 亚洲人成网站精品片在线观看| 欧美二区在线观看| 欧美国产高潮xxxx1819| 农村妇女精品| 欧美国产精品v| 欧美激情国产日韩精品一区18| 欧美不卡在线视频| 欧美国产先锋| 最新热久久免费视频| 亚洲精品国产精品国自产在线 | 亚洲激情成人在线| 91久久精品日日躁夜夜躁欧美 | 制服丝袜亚洲播放| 亚洲一区国产一区| 校园春色综合网| 久久久国产午夜精品| 麻豆精品在线视频| 欧美高清视频在线播放| 欧美日韩午夜视频在线观看| 欧美午夜激情视频| 国产亚洲精品久| 在线看欧美视频| 夜夜嗨av色一区二区不卡| 亚洲欧美经典视频| 久久精品视频在线免费观看| 免费在线亚洲欧美| 亚洲美女av网站| 亚洲女优在线| 麻豆国产精品777777在线| 欧美日韩国产二区| 国产亚洲激情在线| 亚洲国内自拍| 亚洲欧美国产一区二区三区| 久久久777| 亚洲美女一区| 久久精品视频在线| 欧美揉bbbbb揉bbbbb| 国产自产在线视频一区| 一区二区电影免费观看| 久久精品一区二区| 亚洲三级视频| 久久er精品视频| 欧美日韩午夜激情| 好男人免费精品视频| 亚洲午夜精品在线| 免费成人毛片| 亚洲在线视频免费观看| 欧美+日本+国产+在线a∨观看| 欧美日韩国产欧| 亚洲成人资源| 欧美在线在线| 亚洲国产高清aⅴ视频| 中文一区二区| 欧美11—12娇小xxxx| 亚洲视频免费在线| 欧美国产先锋| 一区二区视频欧美| 欧美一区1区三区3区公司| 亚洲国产日韩在线一区模特| 欧美一区二区在线免费观看| 欧美日韩一区二区三区四区在线观看 | 这里只有精品丝袜| 亚洲二区免费| 久久久久一区二区三区| 国产精品亚洲成人| 亚洲视频在线观看一区|