CGAL:在周期性三角剖分中使用边缘迭代器访问每个顶点的邻居时出现问题

时间:2019-05-02 14:52:16

标签: cgal delaunay

我在我的代码中的CGAL中使用了周期性Delaunay三角剖分,并为每个顶点生成所有相邻的顶点。为此,我使用Edge迭代器,因为就我而言,它比Vertex迭代器快得多。 这是代码段,

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef CGAL::Periodic_2_triangulation_traits_2<Kernel> Gt;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned int, Gt> Vb;
typedef CGAL::Periodic_2_triangulation_face_base_2<Gt> Fb;
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
typedef CGAL::Periodic_2_Delaunay_triangulation_2<Gt, Tds> Triangulation;
typedef Triangulation::Iso_rectangle Iso_rectangle;
typedef Triangulation::Edge_iterator Edge_iterator;
typedef Triangulation::Vertex_handle Vertex_handle;
typedef Triangulation::Point Point;
typedef vector<pair<Point, unsigned> > Vector_Paired;
Vector_Paired points;
Iso_rectangle domain(0,0,L,L);

for(int iat = 0; iat < N; iat++)
    {
 points.push_back(make_pair(Point(r_tot[iat][0],r_tot[iat][1]),iat));
    }
Triangulation T(points.begin(), points.end(), domain);

for(Edge_iterator ei=T.finite_edges_begin(); ei!=T.finite_edges_end(); ei++)
    {

      Triangulation::Face& f = *(ei->first);
      int ii = ei->second;
      Vertex_handle vi = f.vertex(f.cw(ii));     
      Vertex_handle vj = f.vertex(f.ccw(ii));    
      int iat = vi->info();
      int jat = vj->info();

      VecInd[iat].push_back(jat);
      VecInd[jat].push_back(iat);

    }

但是,有时不是每个顶点一个特殊的邻居,而是得到8或9或同一邻居的...副本。 例如在VecInd中,它是一个包含相邻索引的2D向量,我得到这样的东西: VecInd [0] = [2,2,2,2,4,4,4,...]

我在CGAL网站中找不到使用边缘迭代器的示例,并且在stackoverflow中没有任何相关内容。 我想知道这种实现是否正确?我应该在代码中添加什么以便每个邻居获得一个副本,我可以使用STL :: sets,但是我想知道问题的根源。

1 个答案:

答案 0 :(得分:0)

这是Mael的was posted on the CGAL-discuss mailing-list答案:


如果点集在几何上的间距不大,则这些点的三角剖分可能不会在平坦圆环上形成简单复形(换句话说,三角剖分的周期很短)。在这种情况下,该算法使用8个三角剖分副本来人为地创建简单复形。您可以使用函数is_triangulation_in_1_sheet()检查情况是否如此,并在User Manual中了解有关这些机制的更多信息。

使用副本时,在边缘上进行迭代确实可以为您提供底层数据结构的确切含义:每个边缘9个实体。要获得唯一的像素,只需查看边缘顶点的偏移量就可以从9个中筛选出8个。这是在返回唯一的周期段的迭代器中完成的。不幸的是,您需要边缘,并且此迭代器直接转换为边缘(线段)的几何形状。不过,您可以简单地使用该迭代器的主要过滤功能,即:is_canonical()。此功能将查看边缘的两个顶点的偏移量,并仅保留在域的第一个副本中至少具有一个顶点的顶点,这足以使其唯一。