CGAL: проблема доступа к соседям каждой вершины с помощью итератора ребер в периодической триангуляции - PullRequest
0 голосов
/ 02 мая 2019

Я использую периодическую триангуляцию Делоне в CGAL в своем коде и создаю для каждой вершины все соседние вершины.Для этого я использую итератор 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, ...]

IНе удалось найти пример с использованием пограничного итератора на веб-сайте CGAL, и ничего не связано с stackoverflow.Мне интересно, является ли эта реализация правильной?Что я должен добавить в свой код, чтобы получить по одной копии на каждого соседа, я могу использовать STL :: sets, но я хотел бы знать источник проблемы.

1 Ответ

0 голосов
/ 03 мая 2019

Вот ответ, который был размещен в списке рассылки CGAL-обсуждения , от Mael:


Если ваш набор точек не геометрически разнесен, возможно, чтотриангуляция этих точек не образует симплициальный комплекс над плоским тором (иными словами, в триангуляции есть короткие циклы).В этом случае алгоритм использует 8 копий триангуляции для искусственного создания симплициального комплекса.Вы можете проверить, так ли это, используя функцию is_triangulation_in_1_sheet() и узнать больше об этих механизмах в Руководстве пользователя .

Когда используются копии, выполняйте итерациипо краям действительно даст вам именно то, что базовая структура данных имеет: 9 сущностей для каждого ребра.Чтобы получить уникальные, вы можете просто отфильтровать 8 из 9, посмотрев на смещение вершин ребра.Это то, что делается в итераторе, который возвращает уникальные периодические сегменты.К сожалению, вам нужны ребра, и этот итератор преобразует непосредственно в геометрию ребра (сегмента).Тем не менее, вы можете просто использовать основную функцию фильтрации этого итератора, а именно: is_canonical().Эта функция будет проверять смещение двух вершин ваших ребер и сохранять только те из них, которые имеют хотя бы одну вершину в первой копии домена, что достаточно для того, чтобы сделать ее уникальной.

...