// swaps an edge (a.org, b.org) with (a.dst, b.dst) void swap(edge er) { Edge_Record a, b; a = er.oprev(); b = er.sym().oprev(); splice(er, a); splice(er.sym(), b); splice(er, a.lnext()); splice(er.sym(), b.lnext()); er.get_qr().v = a.sym().get_qr().v; er.sym().get_qr().v = b.sym().get_qr().v; }
void delete_all_edges(edge hull_edge) { edge e, e1, e2; std::vector<Quadedge*> *to_delete = new std::vector<Quadedge*>; // mark all hull edges as visited e = hull_edge.sym(); while (not e.get_qr().flag) { e.get_qr().flag = true; // visited to_delete->push_back(e.q); e = e.lnext(); } // perform dfs and mark all visited faces std::stack<edge> fringe = std::stack<edge>(); fringe.push(hull_edge); // invariants: // if e is popped, e's sym() was already visited // if e is not visited, neither have any of the other edges of the face while (not fringe.empty()) { e = fringe.top(); fringe.pop(); if (not e.get_qr().flag) { // visit the triangle left of e, mark e and all adjoining edges // add the sym() of each visited edge except e e1 = e.lnext(); e2 = e1.lnext(); // assert e == e2.lnext() e.get_qr().flag = true; if (not e.sym().get_qr().flag) { to_delete->push_back(e.q); } e1.get_qr().flag = true; if (not e1.sym().get_qr().flag) { to_delete->push_back(e1.q); fringe.push(e1.sym()); } e2.get_qr().flag = true; if (not e2.sym().get_qr().flag) { to_delete->push_back(e2.q); fringe.push(e2.sym()); } } } std::vector<Quadedge*>::iterator it; for (it = to_delete->begin(); it != to_delete->end(); ++it) { delete *it; } delete to_delete; }
// given a counterclockwise convex hull edge, returns a string of triangles // <v1> <v2> <v3> // oriented counter clockwise, separated by newlines std::string serialize_triangles(edge hull_edge) { edge e, e1, e2; // mark all hull edges as visited (we don't return the open face) e = hull_edge.sym(); while (not e.get_qr().flag) { e.get_qr().flag = true; // visited e = e.lnext(); } // perform dfs and mark all visited faces std::string output = ""; std::stack<edge> fringe = std::stack<edge>(); fringe.push(hull_edge); // invariants: // if e is popped, e's sym() was already visited // if e is not visited, neither have any of the other edges of the face while (not fringe.empty()) { e = fringe.top(); fringe.pop(); if (not e.get_qr().flag) { // visit the triangle left of e, mark e and all adjoining edges // add the sym() of each visited edge except e std::stringstream ss; e1 = e.lnext(); e2 = e1.lnext(); // assert e == e2.lnext() ss << e.org() << " "; e.get_qr().flag = true; ss << e1.org() << " "; e1.get_qr().flag = true; fringe.push(e1.sym()); ss << e2.org() << "\n"; e2.get_qr().flag = true; fringe.push(e2.sym()); std::string triangle = ss.str(); output += triangle; } } // unvisit the hull e = hull_edge.sym(); while (e.get_qr().flag) { e.get_qr().flag = false; // unvisit e = e.lnext(); } // perform dfs and unmark all visited faces fringe.push(hull_edge); // invariants: // if e is popped, e's sym() was already unvisited // if e is not visited, neither have any of the other edges of the face while (not fringe.empty()) { e = fringe.top(); fringe.pop(); if (e.get_qr().flag) { // unvisit the triangle left of e, unmark e and all adjoining edges // add the sym() of each unvisited edge except e e1 = e.lnext(); e2 = e1.lnext(); // assert e == e2.lnext() e.get_qr().flag = false; e1.get_qr().flag = false; fringe.push(e1.sym()); e2.get_qr().flag = false; fringe.push(e2.sym()); } } return output; }
// removes an edge er, deletes its corresponding quadedge. void delete_edge(edge er) { splice(er, er.oprev()); splice(er.sym(), er.sym().oprev()); delete er.q; }