【问题标题】:CGAL: problem accessing the neighbors of every vertex using edge iterator in periodic triangulationCGAL:在周期性三角剖分中使用边迭代器访问每个顶点的邻居的问题
【发布时间】:2019-09-21 03:07:09
【问题描述】:

我在我的代码中使用 CGAL 中的周期性 Delaunay 三角剖分,并为每个顶点生成所有相邻顶点。为此,我使用 Edge 迭代器,因为在我的情况下它会比 Vertex 迭代器快得多。 这里是代码sn-p,

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,但我想知道问题的根源。

【问题讨论】:

标签: cgal delaunay


【解决方案1】:

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


如果您的点集在几何上没有很好的间隔,则这些点的三角剖分可能不会在平面环面上形成单纯复形(换句话说,三角剖分中存在短循环)。在这种情况下,该算法使用 8 个三角剖分副本人为地创建单纯复形。您可以使用函数is_triangulation_in_1_sheet() 检查是否是这种情况,并在User Manual 中阅读有关这些机制的更多信息。

当使用副本时,遍历边确实会为您提供底层数据结构所具有的确切内容:每条边有 9 个实体。要获得唯一的,您可以通过查看边顶点的偏移量来简单地从 9 个中过滤 8 个。这是在返回唯一周期性段的迭代器中所做的。不幸的是,您需要边,并且此迭代器直接转换为边(段)的几何形状。不过,您可以简单地使用该迭代器中的主要过滤功能,即:is_canonical()。此函数将查看边的两个顶点的偏移量,并仅保留在域的第一个副本中至少具有一个顶点的那些,这足以使其唯一。

【讨论】:

  • 感谢您和 Meal 的回答。我尝试使用 ei->first->offset(f.cw(ei->second)) 为link 打印与边的每个顶点相关的偏移量,尽管它处于 9 张模式,但它为许多人提供了 0顶点。这是获得抵消的正确方法吗?但是它每个顶点只打印 1 个值,但应该是 2。而且,我在 CGAL 文档中找不到 is_canonical() 以了解如何使用它。
  • 最后我可以使用这个来获得偏移量,` Periodic_point pp[3]; for(int i=0;ipp[i].second 给了我偏移量。没有更好的方法吗,因为我不需要点只需要偏移量。对于某些顶点,我得到 3 的偏移量。可能是什么原因?
猜你喜欢
  • 2018-12-23
  • 1970-01-01
  • 1970-01-01
  • 2019-12-31
  • 1970-01-01
  • 2018-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多