• <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>
            小四的海市蜃樓
            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 小四 閱讀(4728) 評論(0)  編輯 收藏 引用 所屬分類: 圖形圖像與計算幾何
            久久精品国产一区二区三区日韩| 免费观看久久精彩视频| 久久国产精品免费一区二区三区 | 91精品国产乱码久久久久久 | 久久99亚洲综合精品首页| 精品久久久久久国产| 国产99精品久久| 色综合久久天天综合| 青青草国产精品久久| 超级碰久久免费公开视频| 亚洲第一永久AV网站久久精品男人的天堂AV| 久久嫩草影院免费看夜色| 久久精品国产网红主播| 中文字幕亚洲综合久久菠萝蜜| 国产精品99久久久久久人| 久久国产一区二区| 青草国产精品久久久久久| 久久777国产线看观看精品| 国产精品美女久久久m| 狠狠色丁香久久婷婷综合_中| 久久综合狠狠色综合伊人| 国产福利电影一区二区三区久久老子无码午夜伦不 | 99久久精品无码一区二区毛片 | 性做久久久久久免费观看| 要久久爱在线免费观看| 亚洲精品乱码久久久久久久久久久久| 久久中文娱乐网| 人妻精品久久久久中文字幕| 99精品久久久久久久婷婷| 无码8090精品久久一区| av色综合久久天堂av色综合在 | 亚州日韩精品专区久久久| 青青草原精品99久久精品66| 国产精品成人无码久久久久久 | 久久精品九九亚洲精品| 国产成人无码精品久久久久免费 | 久久人人爽人人爽人人片AV不| 久久se精品一区精品二区国产| 一级女性全黄久久生活片免费 | 久久免费国产精品一区二区| 亚洲国产成人久久综合野外|