Как получить исходные и целевые точки из Edge_iterator в CGAL - PullRequest
4 голосов
/ 28 января 2011

У меня есть триангуляция Делоне над некоторыми точками, и я хочу перебрать все ребра в ней в порядке возрастания длины, чтобы построить минимальный остовный поток.

Я пробовал использовать следующий подход, но не смог его скомпилировать:

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Delaunay_triangulation_2<K> T;
typedef K::Point_2 P;
typedef T::Vertex_handle Vh;
typedef T::Vertex_iterator Vi;
typedef T::Edge_iterator Ei;

bool sortFunction (Ei a, Ei b) {
    K::FT la, lb;
    la = CGAL::squared_distance(a.source().point(), a.target().point());
    lb = CGAL::squared_distance(b.source().point(), b.target().point());
    return la < lb;
}

...
T g;
...
std::vector<Ei> edges;
for (Ei ei = g.edges_begin(); ei != g.edges_end(); ei++) {
    edges.push_back(ei);
}
std::sort(edges.begin(), edges.end(), sortFunction);
...

Компиляция не удалась в sortFunction, сообщив, что source не является членом Edge_iterator. Однако документация меня здесь смущает.

Документация CGAL говорит, что тип значения итератора ребра - это полжедж. Там сказано, что я могу использовать source() и target() для доступа к точкам.

Однако, похоже, это не так. Что я тут испортил?

Ответы [ 4 ]

4 голосов
/ 03 февраля 2011

edge_iterator - это std::pair грани и индекса вершины.Доступ к исходным и целевым вершинам ребра возможен по этой ссылке на грань.Индекс вершины в edge_iterator соответствует противоположной вершине.Итак, у двух других есть идентификаторы (i+2)%3 и (i+1)%3.

. Некоторое другое решение - добраться до сегмента через triangulation.segment(edge_iterator), а затем использовать функции source() и target(), чтобы добраться до точекнепосредственно.Однако вы не можете получить доступ к дескрипторам вершин таким образом.

2 голосов
/ 03 ноября 2013
Triangulation::Edge e;
//TODO: get e
Triangulation::Vertex_handle v1 = e.first->vertex((e.second + 1) % 3);
Triangulation::Vertex_handle v2 = e.first->vertex((e.second + 2) % 3);
K::FT squared_distance = CGAL::squared_distance(v1->point(), v2->point());
1 голос
/ 09 октября 2013

вы можете получить доступ к vertex_handle конечных точек с помощью

T :: Vertex_handle sVertex = a-> first-> vertex (T :: cw (a-> second));

T :: Vertex_handle fVertex = a-> first-> vertex (T :: ccw (a-> second));

и т. Д. Из каждого дескриптора Vertex_handle вы можете восстановить координаты точки, используя метод point.

Надеюсь, что это может помочь

0 голосов
/ 28 января 2011

Итераторы должны немного походить на указатели на фактические элементы, поэтому вам нужно разыменовать его перед доступом к любым членам. Попробуйте изменить его на a->source().point()

Редактировать: я думаю, маркеры также похожи на указатели. Посмотри, понравится ли это.

la = CGAL::squared_distance(a->source()->point(), a->target()->point());
lb = CGAL::squared_distance(b->source()->point(), b->target()->point());
...