The Computational Geometry Algorithms Library(CGAL)是一个开源的计算几何算法软件库。CGAL是用原生C++语言开发的,通过SWIG绑定,目前可以对Python和JAVA有一定程度的支持。 CGAL项目从1996年开始开发,到目前已经超过25年历史了,内容模块涵盖算术基础、数据类型、多项式求解器、2/3D线性几何基础、多边形算法、多边形布尔运算、特征曲线的布尔运算等, 具有较高的鲁棒性和效率。
安装前假设大家已经安装Visual Studio 2019以及MS vc++ 16.0。 参考官网Getting Start教程
第一步:下载安装Boost库,我安装的版本是1.74;第二步:下载安装CGAL-5.1-Setup.exe 官网剩下的步骤还有设置环境变量、系统变量之类的,这些都是为了用cmake生成项目,并用make编译做准备的,由于我使用cmake生成项目 并不是很成功,因此建议大家可以忽略掉这两个步骤。CGAL是一个只有头文件(header only)的库,它的所有代码实现都放在了.h文件中,因此使用前只需要把header include进去就可以了,不需要去找它的符号文件(.lib / .o)。顺便提一下,header only的库,跨平台使用时会比较方便,但是由于没有预编译的符号文件,因此每次生成项目时都需要把GCAL本身的内容重新编译,时间会比较长。
步骤一:打开Visual Studio,新建一个C++控制台项目;
步骤二:通过Visual Studio配置管理器把解决方案和项目平台修改为x64;
步骤三:添加boost库以及CGAL库的引用,主要关注的是几个配置项:
配置属性---->C/C++ ---->常规------> 附加包含目录,设置为C:\local\boost_1_74_0;C:\dev\CGAL-5.1\include;C:\dev\CGAL-5.1\auxiliary\gmp\include;%(AdditionalIncludeDirectories) 配置属性---->链接器 ---->常规------> 附加库目录,设置为C:\dev\CGAL-5.1\auxiliary\gmp\lib;C:\local\boost_1_74_0\lib64-msvc-14.2;%(AdditionalLibraryDirectories) 配置属性---->链接器 ---->输入------> 附加依赖项,设置为libgmp-10.lib;libmpfr-4.lib;%(AdditionalDependencies)在main.cpp写入demo代码:
// Constructing an arrangement of various conic arcs. #include <CGAL/config.h> #ifndef CGAL_USE_CORE #include <iostream> int main() { std::cout << "Sorry, this example needs CORE ..." << std::endl; return 0; } #else #include <CGAL/Cartesian.h> #include <CGAL/CORE_algebraic_number_traits.h> #include <CGAL/Arr_conic_traits_2.h> #include <CGAL/Arrangement_2.h> typedef CGAL::CORE_algebraic_number_traits Nt_traits; typedef Nt_traits::Rational Rational; typedef Nt_traits::Algebraic Algebraic; typedef CGAL::Cartesian<Rational> Rat_kernel; typedef Rat_kernel::Point_2 Rat_point_2; typedef Rat_kernel::Segment_2 Rat_segment_2; typedef Rat_kernel::Circle_2 Rat_circle_2; typedef CGAL::Cartesian<Algebraic> Alg_kernel; typedef CGAL::Arr_conic_traits_2<Rat_kernel, Alg_kernel, Nt_traits> Traits_2; typedef Traits_2::Point_2 Point_2; typedef Traits_2::Curve_2 Conic_arc_2; typedef CGAL::Arrangement_2<Traits_2> Arrangement_2; void print_neighboring_vertices(Arrangement_2::Vertex_const_handle v) { if (v->is_isolated()) { std::cout << "The vertex (" << v->point() << ") is isolated" << std::endl; return; } Arrangement_2::Halfedge_around_vertex_const_circulator first, curr; first = curr = v->incident_halfedges(); std::cout << "The neighbors of the vertex (" << v->point() << ") are:"; do { // Note that the current halfedge is directed from u to v: Arrangement_2::Vertex_const_handle u = curr->source(); std::cout << " (" << u->point() << ")"; } while (++curr != first); std::cout << std::endl; } int main() { Arrangement_2 arr; // Insert a hyperbolic arc, supported by the hyperbola y = 1/x // (or: xy - 1 = 0) with the endpoints (1/5, 4) and (2, 1/2). // Note that the arc is counterclockwise oriented. Point_2 ps1(Rational(1, 4), 4); Point_2 pt1(2, Rational(1, 2)); Conic_arc_2 c1(0, 0, 1, 0, 0, -1, CGAL::COUNTERCLOCKWISE, ps1, pt1); insert(arr, c1); // Insert a full ellipse, which is (x/4)^2 + (y/2)^2 = 0 rotated by // phi=36.87 degree (such that sin(phi) = 0.6, cos(phi) = 0.8), // yielding: 58x^2 + 72y^2 - 48xy - 360 = 0. Conic_arc_2 c2(58, 72, -48, 0, 0, -360); insert(arr, c2); // Insert the segment (1, 1) -- (0, -3). Rat_point_2 ps3(1, 1); Rat_point_2 pt3(0, -3); Conic_arc_2 c3(Rat_segment_2(ps3, pt3)); insert(arr, c3); // Insert a circular arc supported by the circle x^2 + y^2 = 5^2, // with (-3, 4) and (4, 3) as its endpoints. We want the arc to be // clockwise oriented, so it passes through (0, 5) as well. Rat_point_2 ps4(-3, 4); Rat_point_2 pm4(0, 5); Rat_point_2 pt4(4, 3); Conic_arc_2 c4(ps4, pm4, pt4); CGAL_assertion(c4.is_valid()); insert(arr, c4); // Insert a full unit circle that is centered at (0, 4). Rat_circle_2 circ5(Rat_point_2(0, 4), 1); Conic_arc_2 c5(circ5); insert(arr, c5); // Insert a parabolic arc that is supported by a parabola y = -x^2 // (or: x^2 + y = 0) and whose endpoints are (-sqrt(3), -3) ~ (-1.73, -3) // and (sqrt(2), -2) ~ (1.41, -2). Notice that since the x-coordinates // of the endpoints cannot be accurately represented, we specify them // as the intersections of the parabola with the lines y = -3 and y = -2. // Note that the arc is clockwise oriented. Conic_arc_2 c6 = Conic_arc_2(1, 0, 0, 0, 1, 0, // The parabola. CGAL::CLOCKWISE, Point_2(-1.73, -3), // Approximation of the source. 0, 0, 0, 0, 1, 3, // The line: y = -3. Point_2(1.41, -2), // Approximation of the target. 0, 0, 0, 0, 1, 2); // The line: y = -2. CGAL_assertion(c6.is_valid()); insert(arr, c6); // Insert the right half of the circle centered at (4, 2.5) whose radius // is 1/2 (therefore its squared radius is 1/4). Rat_circle_2 circ7(Rat_point_2(4, Rational(5, 2)), Rational(1, 4)); Point_2 ps7(4, 3); Point_2 pt7(4, 2); Conic_arc_2 c7(circ7, CGAL::CLOCKWISE, ps7, pt7); insert(arr, c7); // Print out the size of the resulting arrangement. std::cout << "The arrangement size:" << std::endl << " V = " << arr.number_of_vertices() << ", E = " << arr.number_of_edges() << ", F = " << arr.number_of_faces() << ", HE = " << arr.number_of_halfedges() << std::endl; /*Arrangement_2::Halfedge_const_handle he = arr.halfedges_begin(); do { std::cout << " [" << he->curve() << "] " << "(" << he->target()->point() << ")" << std::endl; } while (++he != arr.halfedges_end()); return 0; Arrangement_2::Edge_const_iterator eh = arr.edges_begin(); do { std::cout << " [" << eh->curve() << "] " << "(" << eh->target()->point() << ")" << std::endl; } while (eh != arr.edges_end());*/ Arrangement_2::Face_const_handle fh = arr.faces_begin(); Arrangement_2::Face_const_handle fe = arr.faces_end(); do { std::cout << " [" << fh->has_outer_ccb() << "] " << "[" << fh->number_of_outer_ccbs() << "]" << "(" << fh->number_of_holes() << ")" << fh->number_of_inner_ccbs() << std::endl; if (fh->has_outer_ccb()) { Arrangement_2::Ccb_halfedge_const_circulator ci = fh->outer_ccb(); Arrangement_2::Ccb_halfedge_const_circulator current_ci = ci; do { std::cout << " [" << current_ci->curve() << "] " << "[" << current_ci->source()->point() << "]" << "(" << current_ci->target()->point() << ")" << std::endl; current_ci++; } while (current_ci != ci); } } while (++fh != arr.faces_end()); } #endif可以看到我们程序的输出