提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
本章描述了 CGAL 中提供的用于生成二维凸包的函数,以及用于检查点集是否为强凸包的函数。还有许多函数描述用于计算特定的极值点和船体点的子序列,例如一组点的下船体和上船体。
CGAL 提供了几种经典算法的实现,用于计算二维点集的逆时针极值点序列(即凸包上的逆时针点序列)。这些算法具有不同的渐近运行时间,并且需要略微不同的几何图元集。因此,您可以选择最适合您的设置的算法。
每个凸包函数都向用户呈现相同的界面。也就是说,用户提供一对迭代器first
和beyond
,一个输出迭代器result
和一个特征类traits
。first
[ , )范围内的点beyond
定义要计算其凸包的输入点。逆时针方向的极值点序列被写入从 position 开始的序列result
,并返回结果点集的尾后迭代器。函数的特征类指定输入点的类型和算法所需的几何基元。所有函数都提供一个接口,在该接口中不需要指定此类,并且默认为定义输入点类型的内核中定义的类型和操作。
在以下示例中,使用Graham_Andrew
算法从标准输入读取的点数据构建了一个凸包。生成的凸多边形显示在标准输出控制台中。将函数替换ch_graham_andrew()
为其他函数(例如ch_bykat()
.
#include
#include
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point_2;
int main()
{
CGAL::IO::set_ascii_mode(std::cin);
CGAL::IO::set_ascii_mode(std::cout);
std::istream_iterator< Point_2 > in_start( std::cin );
std::istream_iterator< Point_2 > in_end;
std::ostream_iterator< Point_2 > out( std::cout, "\n" );
CGAL::ch_graham_andrew( in_start, in_end, out );
return 0;
}
在下面的示例中,我们将点向量作为输入,并检索凸包上的点的索引。凸包函数将特征类作为第四个参数,该特征类必须是概念的模型ConvexHullTraits_2
。它提供诸如方向测试之类的谓词。Convex_hull_traits_adapter_2
与 , 组合的类Pointer_property_map
就是这样一个模型。索引i
就是“点”,适配器在 上执行谓词points[i]
。
#include
#include
#include
#include
#include
#include
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 Point_2;
typedef CGAL::Convex_hull_traits_adapter_2<K,
CGAL::Pointer_property_map<Point_2>::type > Convex_hull_traits_2;
int main()
{
std::vector<Point_2> points = { Point_2(10,0),
Point_2(10,0),
Point_2(0,10),
Point_2(1,1),
Point_2(3,4),
Point_2(0,0),
Point_2(10,10),
Point_2(2,6) };
std::vector<std::size_t> indices(points.size()), out;
std::iota(indices.begin(), indices.end(),0);
CGAL::convex_hull_2(indices.begin(), indices.end(), std::back_inserter(out),
Convex_hull_traits_2(CGAL::make_property_map(points)));
for( std::size_t i : out){
std::cout << "points[" << i << "] = " << points[i] << std::endl;
}
return 0;
}
除了用于生成凸包的函数外,还有许多用于计算与凸包相关的点集和序列的函数。
函数lower_hull_points_2()
和upper_hull_points_2()
分别提供下壳和上壳上极值点逆时针序列的计算。[这些函数中使用的算法是 Graham 扫描算法3]和[9]的 Andrew 变体,其最坏情况运行时间为。O (n logn)
还有一些函数可用于计算凸包上极值点序列的某些子序列。该函数ch_jarvis_march()
在给定的一对点之间生成逆时针排序的极值点子序列,并ch_graham_andrew_scan()
计算不在第一个和最后一个输入点定义的直线左侧的极值点的排序序列。
最后,提供了一组函数(ch_nswe_point()
, ch_ns_point()
, ch_we_point()
, ch_n_point()
, ch_s_point()
, ch_w_point()
, ch_e_point()
)用于计算二维点集在坐标方向上的极值点。
用于计算凸包或极值点的每个函数都由特征类参数化,该特征类指定要在计算中使用的类型和几何基元。库中提供了 2D 特征类的多种实现。该类Convex_hull_traits_2
对应于提供输入点所在的二维 CGAL 内核中呈现的类型和谓词的默认特征类。该类Convex_hull_constructive_traits_2
是基于 CGAL 原语的第二个特征类,但不同之处在于Convex_hull_traits_2
它的一些原语重用中间结果来加速计算。
此外,2D 和 3D 线性几何内核提供了三个投影特征类(Projection_traits_xy_3
、Projection_traits_xz_3
和Projection_traits_yz_3
),它们可用于计算投影到三个坐标平面中每一个平面的一组三维点的凸包。
函数is_ccw_strongly_convex_2()
并is_cw_strongly_convex_2()
检查给定的二维点序列是否形成(逆时针)强凸多边形。这些用于二维凸包函数的后置条件测试。