1、安装CGAL
Win10下VS配置CGAL-5.3.1(下载、安装、VS属性表配置)+ 测试代码_cgal下载_孙 悟 空的博客-CSDN博客
2、CGAL验证练习
#include <iostream>
#include <CGAL/Simple_cartesian.h>
typedef CGAL::Simple_cartesian<double> Kernel; //笛卡尔坐标(cartesian)double型
typedef Kernel::Point_2 Point_2; //_2 :2维
typedef Kernel::Segment_2 Segment_2;
int main()
{
Point_2 p(1, 1), q(10, 10);
std::cout << "p = " << p << std::endl;
std::cout << "q = " << q.x() << " " << q.y() << std::endl;
//使用CGAL::squared_distance(p, q)来计算点p和q之间的平方距离,并打印这个值。
std::cout << "sqdist(p,q) = "
<< CGAL::squared_distance(p, q) << std::endl;
Segment_2 s(p, q);
Point_2 m(5, 9);
std::cout << "m = " << m << std::endl;
//使用CGAL::squared_distance(s, m)来计算线段s与点m之间的平方距离,并打印这个值。这个距离是指点m到线段s上最近的点的距离。
std::cout << "sqdist(Segment_2(p,q), m) = "
<< CGAL::squared_distance(s, m) << std::endl;
std::cout << " midpoint(p,q) = " << CGAL::midpoint(p, q) << std::endl;
return 0;
}
3、CGAL深入学习(一)
c++ - CGAL的使用 - Linux/Windows下工具使用notes - SegmentFault 思否
4、二维线段相交
// 包括所需的头文件来使用CGAL的几何和交集功能
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/intersections.h>
// 定义一个精确的内核(Kernel),这在CGAL中是非常常见的。
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
typedef K::Point_2 Point_2; // 为二维点定义一个类型别名
typedef K::Line_2 Line_2; // 为二维线定义一个类型别名
typedef K::Intersect_2 Intersect_2; // 为交点函数定义一个类型别名
int main()
{
// 定义两条二维直线 lina 和 linb。
// 这些直线是在它们的参数形式 ax + by + c = 0 中定义的,其中 (a, b) 是线上的方向向量,c 是常数。
Line_2 lina(1, 1, 2); // 表示直线 x + y + 2 = 0
Line_2 linb(1, -1, 1); // 表示直线 x - y + 1 = 0
// 求两条线的交点。
// 如果交点存在,它将被存储在变量result中。
CGAL::cpp11::result_of<Intersect_2(Line_2, Line_2)>::type
result = intersection(lina, linb);
// 检查两条线是否相交
if (result)
{
// 如果相交,获取交点。
// 由于交点可能是一个点或一个线段(如果两条线重叠),所以我们使用boost::get来检索点。
const Point_2* p = boost::get<Point_2 >(&*result);
// 如果交点是一个点,打印它。
if (p) {
std::cout << *p << std::endl;
}
}
system("pause"); // 在Windows系统上暂停程序,等待用户按键。
return 0;
}
5、三维线段相交
// 包括所需的头文件来使用CGAL的几何和交集功能
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/intersections.h>
// 定义一个精确的内核(Kernel)。在CGAL中使用该内核可以确保计算的准确性。
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
typedef K::Point_3 Point_3; // 为三维点定义一个类型别名
typedef K::Line_3 Line_3; // 为三维线定义一个类型别名
typedef K::Intersect_3 Intersect_3; // 为交点函数定义一个类型别名
int main()
{
// 定义直线lina的起点和终点
Point_3 linea_b(0, 0, 0);
Point_3 linea_e(1, 1, 1);
// 定义直线linb的起点和终点
Point_3 lineb_b(0, 1, 0);
Point_3 lineb_e(1, 0, 1);
// 通过起点和终点创建两条三维直线lina和linb
Line_3 lina(linea_b, linea_e);
Line_3 linb(lineb_b, lineb_e);
// 计算两条直线的交点
CGAL::cpp11::result_of<Intersect_3(Line_3, Line_3)>::type
result = intersection(lina, linb);
// 检查两条直线是否有交点
if (result)
{
// 如果有交点,获取交点。
// 由于交点可能是一个点或一个线(如果两条线重叠)或没有(如果线是平行的),所以我们使用boost::get来检索点。
const Point_3* p = boost::get<Point_3>(&*result);
// 如果交点是一个点,打印它。
if(p) {
std::cout << *p << std::endl;
}
}
return 0;
}
6、求二维直线和二维三角形的交点和数量
// 包括CGAL库中所需的头文件以进行准确的几何计算、交点检测和二维三角形的表示
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/intersections.h>
#include <CGAL/Triangle_2.h>
// 定义一个精确的内核(Kernel)。在CGAL中使用该内核可以确保计算的准确性。
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
typedef K::Point_2 Point_2; // 为二维点定义一个类型别名
typedef K::Line_2 Line_2; // 为二维直线定义一个类型别名
typedef K::Intersect_2 Intersect_2; // 为交点函数定义一个类型别名
typedef K::Triangle_2 Triangle_2; // 为二维三角形定义一个类型别名
typedef K::Segment_2 Segment_2; // 为二维线段定义一个类型别名
int main()
{
// 定义一个二维直线line。直线方程为y = 1。
Line_2 line(0, -1, 1);
// 定义一个二维三角形triangle,顶点为(0,0),(2,0)和(1,1.732)。
Triangle_2 triangle(Point_2(0, 0), Point_2(2, 0), Point_2(1, 1.732));
// 计算直线line与三角形triangle的交点
CGAL::cpp11::result_of<Intersect_2(Line_2, Triangle_2)>::type
result = intersection(line, triangle);
// 检查是否有交点
if (result) {
// 交点存在
// 检查交点是否为一个点
if (const Point_2* p = boost::get<Point_2>(&*result)) {
std::cout << "Points intersect:" << std::endl;
std::cout << *p << std::endl; // 输出交点
}
else {
// 如果不是点,那么交点是一个线段
std::cout << "Segment intersect:" << std::endl;
const Segment_2* s = boost::get<Segment_2>(&*result);
std::cout << *s << std::endl; // 输出交线段
}
}
else {
// 交点不存在
std::cout << "None intersection!" << std::endl;
}
system("pause"); // 在Windows系统上暂停程序,等待用户按键。
return 0;
}
7、生成两个随机三角形并计算它们的交集
// 引入CGAL库中的各种头文件
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/point_generators_2.h>
#include <CGAL/random_polygon_2.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Boolean_set_operations_2.h>
#include <list>
// 定义精确内核和其相关类型
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_2 Point_2;
typedef CGAL::Polygon_2<Kernel> Polygon_2;
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
typedef std::list<Polygon_with_holes_2> Pwh_list_2;
// 定义不精确内核和其相关类型
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
// 使用前面定义的Point_2类型
typedef std::list<Point_2> Container;
// 使用前面定义的Polygon_2类型
typedef CGAL::Random_points_in_square_2< Point_2 > Point_generator;
// 引入打印工具
#include "print_utils.h"
int main() {
Polygon_2 triangle1;
Polygon_2 triangle2;
// 使用随机生成器生成两个随机三角形,并插入triangle1和triangle2中
CGAL::random_polygon_2(3, std::back_inserter(triangle1),
Point_generator(2));
CGAL::random_polygon_2(3, std::back_inserter(triangle2),
Point_generator(2));
// 打印这两个随机三角形
std::cout << triangle1 << std::endl;
std::cout << triangle2 << std::endl;
// 计算两个三角形的交集,并保存在intR列表中
Pwh_list_2 intR;
Pwh_list_2::const_iterator it;
CGAL::intersection(triangle1, triangle2, std::back_inserter(intR));
// 打印交集结果
std::cout << "The intersection:" << std::endl;
for (it = intR.begin(); it != intR.end(); ++it) {
std::cout << "--> ";
print_polygon_with_holes(*it);
}
return 0;
}
// 保护宏,防止头文件被重复包含
#ifndef CGAL_PRINT_UTILS_H
#define CGAL_PRINT_UTILS_H
// 引入必要的头文件
#include <CGAL/Polygon_with_holes_2.h>
#include <iostream>
// 函数模板:打印一个CGAL多边形
template<class Kernel, class Container>
void print_polygon(const CGAL::Polygon_2<Kernel, Container>& P)
{
// 使用常量迭代器遍历多边形的所有顶点
typename CGAL::Polygon_2<Kernel, Container>::Vertex_const_iterator vit;
std::cout << "[ " << P.size() << " vertices:"; // 打印顶点数量
for (vit = P.vertices_begin(); vit != P.vertices_end(); ++vit) // 遍历每个顶点
std::cout << " (" << *vit << ')'; // 打印顶点坐标
std::cout << " ]" << std::endl;
return;
}
// 函数模板:打印带孔的多边形
template<class Kernel, class Container>
void print_polygon_with_holes
(const CGAL::Polygon_with_holes_2<Kernel, Container>& pwh)
{
// 判断多边形是否是有界的
if (!pwh.is_unbounded())
{
std::cout << "{ Outer boundary = ";
print_polygon(pwh.outer_boundary()); // 打印外部边界
}
else
std::cout << "{ Unbounded polygon." << std::endl; // 如果是无界的,打印提示信息
// 使用常量迭代器遍历所有的孔
typename CGAL::Polygon_with_holes_2<Kernel, Container>::
Hole_const_iterator hit;
unsigned int k = 1; // 用于计数孔的编号
std::cout << " " << pwh.number_of_holes() << " holes:" << std::endl; // 打印孔的数量
for (hit = pwh.holes_begin(); hit != pwh.holes_end(); ++hit, ++k) // 遍历每个孔
{
std::cout << " Hole #" << k << " = ";
print_polygon(*hit); // 打印孔的边界
}
std::cout << " }" << std::endl;
return;
}
// 结束保护宏
#endif
8、两个2D多边形之间的布尔操作(即并集和交集)
// 引入必要的头文件
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Boolean_set_operations_2.h>
// 定义使用的核和相关的数据类型
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_2 Point_2;
typedef CGAL::Polygon_2<Kernel> Polygon_2;
typedef CGAL::Polygon_with_holes_2<Kernel> Polygon_with_holes_2;
typedef std::list<Polygon_with_holes_2> Pwh_list_2;
// 函数模板:用于打印CGAL多边形
template<class Kernel, class Container>
void print_polygon(const CGAL::Polygon_2<Kernel, Container>& P)
{
typename CGAL::Polygon_2<Kernel, Container>::Vertex_const_iterator vit;
std::cout << "[ " << P.size() << " vertices:";
for (vit = P.vertices_begin(); vit != P.vertices_end(); ++vit)
std::cout << " (" << *vit << ')';
std::cout << " ]" << std::endl;
}
// 函数模板:打印带孔多边形
template<class Kernel, class Container>
void print_polygon_with_holes(const CGAL::Polygon_with_holes_2<Kernel, Container>& pwh)
{
if (!pwh.is_unbounded()) {
std::cout << "{ Outer boundary = ";
print_polygon(pwh.outer_boundary());
}
else
std::cout << "{ Unbounded polygon." << std::endl;
typename CGAL::Polygon_with_holes_2<Kernel, Container>::Hole_const_iterator hit;
unsigned int k = 1;
std::cout << " " << pwh.number_of_holes() << " holes:" << std::endl;
for (hit = pwh.holes_begin(); hit != pwh.holes_end(); ++hit, ++k) {
std::cout << " Hole #" << k << " = ";
print_polygon(*hit);
}
std::cout << " }" << std::endl;
}
int main()
{
// 定义多边形P,并赋值
Polygon_2 P;
P.push_back(Point_2(0, 0));
P.push_back(Point_2(1000, 0));
P.push_back(Point_2(1000, 1000));
P.push_back(Point_2(0, 1000));
// 定义多边形Q,并赋值
Polygon_2 Q;
Q.push_back(Point_2(500, 500));
Q.push_back(Point_2(1500, 500));
Q.push_back(Point_2(1500, 1500));
Q.push_back(Point_2(500, 1500));
// 计算多边形P和Q的并集,并显示结果
Polygon_with_holes_2 unionR;
if (CGAL::join(P, Q, unionR)) {
std::cout << "The union: ";
print_polygon_with_holes(unionR);
}
else
std::cout << "P and Q are disjoint and their union is trivial." << std::endl;
std::cout << std::endl;
// 计算多边形P和Q的交集,并显示结果
Pwh_list_2 intR;
Pwh_list_2::const_iterator it;
CGAL::intersection(P, Q, std::back_inserter(intR));
std::cout << "The intersection:" << std::endl;
for (it = intR.begin(); it != intR.end(); ++it) {
std::cout << "--> ";
print_polygon_with_holes(*it);
}
}