标记(或着色)CGAL 对象

Tagging (or coloring) CGAL objects

我正在尝试使用 CGAL 执行一些简单的 2D CSG 操作。这是两个多边形相交的示例。

实际问题是在生成的多边形中追踪每个线段的原点(用颜色标记)。

我想知道这是否可能,也许对 CGAL 本身进行一些黑客攻击。任何建议将不胜感激。

不幸的是,out-of-the-box 没有办法做到这一点。然而,它并不需要太多(famous last words...)。您需要做下面描述的两件事。第一个是支持的 API。第二个不是,因此您需要修补源文件。下面进一步提供一个简单的例子。请注意,您需要的数据(即每条边的原点规范)以二维排列数据结构结束。如果要获取包含此数据的多边形,则需要从排列中提取它们。您可以获得 header pgn_print.h, used in the example, from the 2D-Arrangement book.

  1. 使用 CGAL::Polygon_set_2<Kernel, Container, Dcel> 的实例,其中 Dcel 被替换为扩展的 Dcel,其半边用指示halfedge 的原点(即第一个多边形、第二个多边形或重叠时两者)。

  2. 修补 header 文件 Boolean_set_operations_2/Gps_base_functor.h。特别是,添加到名为 create_edge() 的三个函数的 body 语句中,根据其原点设置生成的半边的标签:

  void create_edge(Halfedge_const_handle h1, Halfedge_const_handle h2,
                   Halfedge_handle h)
  {
    h->set_label(3);
    h->twin()->set_label(3);
  }

  void create_edge(Halfedge_const_handle h1, Face_const_handle f2,
                   Halfedge_handle h)
  {
    h->set_label(1);
    h->twin()->set_label(1);
  }

  void create_edge(Face_const_handle f1, Halfedge_const_handle h2,
                   Halfedge_handle h)
  {
    h->set_label(2);
    h->twin()->set_label(2);
  }
#include <list>
#include <vector>

#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Boolean_set_operations_2.h>
#include <CGAL/Polygon_set_2.h>

#include "pgn_print.h"

/*! Extend the arrangement halfedge */
template <typename X_monotone_curve_2>
class Arr_labeled_halfedge :
  public CGAL::Arr_halfedge_base<X_monotone_curve_2>
{
private:
  unsigned m_label;

public:
  Arr_labeled_halfedge() : m_label(0) {}
  unsigned label() const { return m_label; }
  void set_label(unsigned label) { m_label = label; }

  virtual void assign(const Arr_labeled_halfedge& he)
  {
    CGAL::Arr_halfedge_base<X_monotone_curve_2>::assign(he);
    m_label = he.m_label;
  }
};

template <typename Traits>
class Arr_labeled_dcel :
  public CGAL::Arr_dcel_base<CGAL::Arr_vertex_base<typename Traits::Point_2>,
                             Arr_labeled_halfedge<typename Traits::
                                                  X_monotone_curve_2>,
                             CGAL::Gps_face_base>
{
public:
  Arr_labeled_dcel() {}
};

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::vector<Point_2>                              Container;
typedef CGAL::Gps_segment_traits_2<Kernel, Container>     Traits_2;
typedef Arr_labeled_dcel<Traits_2>                        Dcel;
typedef CGAL::Polygon_set_2<Kernel, Container, Dcel>      Polygon_set_2;
typedef std::list<Polygon_with_holes_2>                   Pwh_list_2;
typedef Polygon_set_2::Arrangement_2                      Arrangement_2;
typedef Arrangement_2::Edge_const_iterator                Edge_const_iterator;

void print_result(const Polygon_set_2& S)
{
  std::cout << "The result contains " << S.number_of_polygons_with_holes()
            << " components:" << std::endl;

  Pwh_list_2 res;
  S.polygons_with_holes(std::back_inserter(res));
  for (Pwh_list_2::const_iterator hit = res.begin(); hit != res.end(); ++hit) {
    std::cout << "--> ";
    print_polygon_with_holes(*hit);
  }

  const Arrangement_2& arr = S.arrangement();
  for (Edge_const_iterator it = arr.edges_begin(); it != arr.edges_end(); ++it) {
    std::cout << it->curve()
              << ", " << it->label()
              << std::endl;
  }
}

int main()
{
  // Construct the two input polygons.
  Polygon_2 P;
  P.push_back(Point_2(0, 0));
  P.push_back(Point_2(5, 0));
  P.push_back(Point_2(3.5, 1.5));
  P.push_back(Point_2(2.5, 0.5));
  P.push_back(Point_2(1.5, 1.5));
  std::cout << "P = "; print_polygon(P);

  Polygon_2 Q;
  Q.push_back(Point_2(0, 2));
  Q.push_back(Point_2(1.5, 0.5));
  Q.push_back(Point_2(2.5, 1.5));
  Q.push_back(Point_2(3.5, 0.5));
  Q.push_back(Point_2(5, 2));
  std::cout << "Q = "; print_polygon(Q);

  // Compute the union of P and Q.
  Polygon_set_2 intersection_set;
  intersection_set.insert(P);
  intersection_set.intersection(Q);
  print_result(intersection_set);

  // Compute the intersection of P and Q.
  Polygon_set_2 union_set;
  union_set.insert(P);
  union_set.join(Q);
  print_result(union_set);

  return 0;
}