【问题标题】:Using CGAL to partition a non-simple polygon使用 CGAL 划分非简单多边形
【发布时间】:2025-11-27 13:15:01
【问题描述】:

假设我有一个非简单多边形, CGAL 如何帮助我将其划分为一组简单的多边形?

例如,给出一个由二维点序列表示的多边形:

(1, 1) (1, -1) (-1, 1) (-1, -1) 

我希望获得两个多边形;

(1, 1) (1, -1) (0, 0)

(0, 0) (-1, 1) (-1, -1) 

CGAL 可行吗?

【问题讨论】:

    标签: cgal


    【解决方案1】:

    您需要的两个多边形不构成原始船体。如果您只想使用 (0,0) 作为顶点之一将原始集合分解为三角形,您可以这样做:

    #include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
    #include <CGAL/Constrained_Delaunay_triangulation_2.h>
    #include <CGAL/Delaunay_mesh_vertex_base_2.h>
    #include <CGAL/Delaunay_mesh_face_base_2.h>
    #include <vector>    
    
    typedef CGAL::Exact_predicates_inexact_constructions_kernel     K;
    typedef K::Point_2                                              Point_2;
    typedef CGAL::Delaunay_mesh_vertex_base_2<K>                    Vb;
    typedef CGAL::Delaunay_mesh_face_base_2<K>                      Fb;
    typedef CGAL::Triangulation_data_structure_2<Vb, Fb>            Tds;
    typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds>      CDT;
    typedef CDT::Vertex_handle                                      Vertex_handle;
    typedef CDT::Face_iterator                                      Face_iterator;    
    
    int main(int argc, char* argv[])
    {
        // Create a vector of the points
        //
        std::vector<Point_2> points2D ;
        points2D.push_back(Point_2(  1,  1));
        points2D.push_back(Point_2(  1, -1));
        points2D.push_back(Point_2( -1,  1));
        points2D.push_back(Point_2( -1, -1));
        points2D.push_back(Point_2( 0, 0));
    
        size_t numTestPoints = points2D.size();
    
        // Create a constrained delaunay triangulation and add the points
        //
        CDT cdt;
        std::vector<Vertex_handle> vhs;
        for (unsigned int i=0; i<numTestPoints; ++i){
            vhs.push_back(cdt.insert(points2D[i]));
        }
    
        int i=0;
        for (Face_iterator fit = cdt.faces_begin()  ; fit != cdt.faces_end(); ++fit) {
            printf("Face %d is (%f,%f) -- (%f,%f) -- (%f,%f) \n",i++,
                   fit->vertex(0)->point().x(),fit->vertex(0)->point().y(),
                   fit->vertex(1)->point().x(),fit->vertex(1)->point().y(),
                   fit->vertex(2)->point().x(),fit->vertex(2)->point().y() );
    
        }
    
        return 0 ;
    }
    

    应该给你这样的输出:

    Face 0 is (0.000000,0.000000) -- (1.000000,-1.000000) -- (1.000000,1.000000) 
    Face 1 is (0.000000,0.000000) -- (1.000000,1.000000) -- (-1.000000,1.000000) 
    Face 2 is (-1.000000,-1.000000) -- (0.000000,0.000000) -- (-1.000000,1.000000) 
    Face 3 is (-1.000000,-1.000000) -- (1.000000,-1.000000) -- (0.000000,0.000000) 
    

    【讨论】: