CGAL笔记之凸包算法—2D凸包和极值点

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


1 介绍

本章描述了 CGAL 中提供的用于生成二维凸包的函数,以及用于检查点集是否为强凸包的函数。还有许多函数描述用于计算特定的极值点和船体点的子序列,例如一组点的下船体和上船体。

在这里插入图片描述

2 凸包

CGAL 提供了几种经典算法的实现,用于计算二维点集的逆时针极值点序列(凸包上的逆时针点序列)。这些算法具有不同的渐近运行时间,并且需要略微不同的几何图元集。因此,您可以选择最适合您的设置的算法。

每个凸包函数都向用户呈现相同的界面。也就是说,用户提供一对迭代器firstbeyond,一个输出迭代器result和一个特征类traitsfirst[ , )范围内的点beyond定义要计算其凸包的输入点。逆时针方向的极值点序列被写入从 position 开始的序列result,并返回结果点集的尾后迭代器。函数的特征类指定输入点的类型和算法所需的几何基元。所有函数都提供一个接口,在该接口中不需要指定此类,并且默认为定义输入点类型的内核中定义的类型和操作。

3个 使用 Graham-Andrew 算法的示例

在以下示例中,使用Graham_Andrew算法从标准输入读取的点数据构建了一个凸包。生成的凸多边形显示在标准输出控制台中。将函数替换ch_graham_andrew()为其他函数(例如ch_bykat().

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/ch_graham_andrew.h>
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;
}

4个 使用 Property Map 的示例

在下面的示例中,我们将点向量作为输入,并检索凸包上的点的索引。凸包函数将特征类作为第四个参数,该特征类必须是概念的模型ConvexHullTraits_2。它提供诸如方向测试之类的谓词。Convex_hull_traits_adapter_2与 , 组合的类Pointer_property_map就是这样一个模型。索引i就是“点”,适配器在 上执行谓词points[i]

#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/convex_hull_2.h>
#include <CGAL/Convex_hull_traits_adapter_2.h>
#include <CGAL/property_map.h>
#include <vector>
#include <numeric>
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;
}

5个 极值点和船体子序列

除了用于生成凸包的函数外,还有许多用于计算与凸包相关的点集和序列的函数。

函数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())用于计算二维点集在坐标方向上的极值点。

6个 特征类

用于计算凸包或极值点的每个函数都由特征类参数化,该特征类指定要在计算中使用的类型和几何基元。库中提供了 2D 特征类的多种实现。该类Convex_hull_traits_2对应于提供输入点所在的二维 CGAL 内核中呈现的类型和谓词的默认特征类。该类Convex_hull_constructive_traits_2是基于 CGAL 原语的第二个特征类,但不同之处在于Convex_hull_traits_2它的一些原语重用中间结果来加速计算。

此外,2D 和 3D 线性几何内核提供了三个投影特征类(Projection_traits_xy_3Projection_traits_xz_3Projection_traits_yz_3),它们可用于计算投影到三个坐标平面中每一个平面的一组三维点的凸包。

7 凸性检查

函数is_ccw_strongly_convex_2()is_cw_strongly_convex_2()检查给定的二维点序列是否形成(逆时针)强凸多边形。这些用于二维凸包函数的后置条件测试。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值