多边形之间的交差并补....

  以前接触二维图形的操作比较多,多边形之间的交差并补是一个难点,算法也颇为复杂,幸好有一些现成的源代码文件,比如这个gpc.c和gpc.h。

  首先先将gpc.c和gpc.h加入到工程,我用的是mfc vc6.0(好古老)...需要将gpc.c改成gpc.cpp,然后添加到工程,似乎出现过一些问题,具体忘了,蛮简单最后配置成功,就可以用gpc的算法了。

  整个文件不算难,很容易看懂,这里简单贴一下我写的代码,这个代码是一个多边形在另一多边形内部面积超过80%的时候,进行一系列操作。因此要求出两个多边形的交集。

  首先我们先看一下求多边形面积的代码。

double CMap3DEditorDoc::det(gpc_vertex p0, gpc_vertex p1, gpc_vertex p2)  
{  
    return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);  
}  

double CMap3DEditorDoc::ploygon_area(int n,gpc_vertex p[])    
{  
    double s=0.0f;  
    int i=1;  
    for(;i < n-1;i++)  
        s += det(p[0],p[i],p[i+1]);  
    return 0.5*fabs(s);  
} 
View Code

  其中gpc_vertex在gpc.h中有解释,其实就是二维坐标点。如下

typedef struct                      /* Polygon vertex structure          */
{
  double              x;            /* Vertex x component                */
  double              y;            /* vertex y component                */
} gpc_vertex;

  再看看gpc_polygon这个比较重要的数据类型。

typedef struct                      /* Polygon set structure             */
{
  int                 num_contours; /* Number of contours in polygon     */
  int                *hole;         /* Hole / external contour flags     */
  gpc_vertex_list    *contour;      /* Contour array pointer             */
} gpc_polygon;
  num_contours指这个多边形有几个多边形组成,hole指的是洞,就是在多边形挖洞,就像铜钱里的孔,比如铜钱可能有两个边界,一个是外部的圆,一个是方形的洞,如果只是一个闭合多边形,那么num_contours == 1,hole == 0就好了。gpc_vertex_list是每个多边形的点,定义如下:
typedef struct                      /* Vertex list structure             */
{
  int                 num_vertices; /* Number of vertices in list        */
  gpc_vertex         *vertex;       /* Vertex array pointer              */
} gpc_vertex_list;

  即点数和点坐标,这个就不做解释了。

  运用gpc,首先你要将你的多边形数据转化成gpc_polygon这个类型,然后运用其函数就能得到结果。下面是我的代码:

double CMap3DEditorDoc::CalIntersectRegion(CSMAPFace *pSubject_Face, CSMAPFace *pClip_Face)
{
    if(!pSubject_Face || !pClip_Face) return 0;

    gpc_polygon *psubject_polygon = new gpc_polygon;//第一个多边形数据
    gpc_polygon *pclip_polygon = new gpc_polygon;//第二个多边形数据
    gpc_polygon *presult_polygon = new gpc_polygon; //交集多边形数据

    psubject_polygon->num_contours = pclip_polygon->num_contours = presult_polygon->num_contours = 1;
    psubject_polygon->hole = pclip_polygon->hole = presult_polygon->hole = 0;//初始化

    FaceToPolygon(pSubject_Face, psubject_polygon);//转化第一个多边形数据成gpc_polygon
    FaceToPolygon(pClip_Face, pclip_polygon);//转化第二个数据

    gpc_polygon_clip(GPC_INT, psubject_polygon, pclip_polygon, presult_polygon);//运用交差并补函数,GPC_INT指进行交运算
    if(!presult_polygon->num_contours) return 0;

    double area = ploygon_area(presult_polygon->contour->num_vertices, presult_polygon->contour->vertex);
    
    psubject_polygon=pclip_polygon=presult_polygon=NULL;
    delete presult_polygon;
    delete pclip_polygon;
    delete presult_polygon;

    return area;


}
CSMAPFace是自己的数据类型。整个函数很简单就能得到相交的多边形和面积。
下面是gpc文件下载:
http://pan.baidu.com/share/link?shareid=2182627207&uk=3020745002
http://pan.baidu.com/share/link?shareid=2184046649&uk=3020745002

竟然不能添加附件.....

posted on 2013-09-30 10:56  梦魇nightmare  阅读(1566)  评论(0)    收藏  举报