1 Вопрос: CGAL: проблема доступа к соседям каждой вершины с помощью итератора ребер в периодической триангуляции

вопрос создан в Thu, May 2, 2019 12:00 AM

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

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

    
0
  1. На этот вопрос уже был дан хороший ответ в списке рассылки, где вы разместили тот же вопрос: cgal-discuss.949826.n4.nabble.com/…
    2019-05-03 07: 51: 22Z
    1 ответ                              1                         

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

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

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

    . Эта функция будет проверять смещение двух вершин ваших ребер и сохранять только те из них, которые имеют хотя бы одну вершину в первой копии домена, что достаточно для того, чтобы сделать ее уникальной.

        
    0
    2019-05-03 07: 54: 16Z
    1. Спасибо и Еда за ответ. Я попытался напечатать смещение, связанное с каждой вершиной ребра, используя смещение ei- > first-> (f.cw (ei- > second)) для link , хотя она находится в режиме 9 листов, она дает 0 для многих вершин. Это правильный способ получить компенсацию? однако он печатает только 1 значение на вершину, но должно быть 2. И я не смог найти is_canonical () в документации CGAL, чтобы узнать, как я могу его использовать.
      2019-05-03 16: 30: 00Z
    2. Наконец, я могу получить смещения, используя это, `Periodic_point pp [3]; for (int i = 0; i < 3; i ++) {pp [i] = T.periodic_point (fh, i); } ` pp [я]. секунды дает мне смещение. Разве нет лучшего способа сделать это, так как мне не нужны очки, просто нужны смещения. Для некоторых вершин я получаю 3 для смещения. В чем может быть причина?
      2019-05-04 19: 44: 01Z
источник размещен Вот