Subdivision::Subdivision(const Point2d& a, const Point2d& b, const Point2d& c) // Initialize a subdivision to the triangle defined by the points a, b, c. { Point2d *da, *db, *dc; da = new Point2d(a), db = new Point2d(b), dc = new Point2d(c); Edge* ea = MakeEdge(); ea->EndPoints(da, db); Edge* eb = MakeEdge(); Splice(ea->Sym(), eb); eb->EndPoints(db, dc); Edge* ec = MakeEdge(); Splice(eb->Sym(), ec); ec->EndPoints(dc, da); Splice(ec->Sym(), ea); startingEdge = ea; }
Edge *Subdivision::connect(Edge *a, Edge *b) { Edge *e = makeEdge(); splice(e, a->Lnext()); splice(e->Sym(), b); e->EndPoints(a->Dest(), b->Org()); return e; }
Edge* Connect(Edge* a, Edge* b) // Add a new edge e connecting the destination of a to the // origin of b, in such a way that all three have the same // left face after the connection is complete. // Additionally, the data pointers of the new edge are set. { Edge* e = MakeEdge(); Splice(e, a->Lnext()); Splice(e->Sym(), b); e->EndPoints(a->Dest(), b->Org()); return e; }
void Subdivision::initMesh(const Vec2& A,const Vec2& B, const Vec2& C,const Vec2& D) { Vec2& a = A.clone(); Vec2& b = B.clone(); Vec2& c = C.clone(); Vec2& d = D.clone(); Edge *ea = makeEdge(); ea->EndPoints(a, b); Edge *eb = makeEdge(); splice(ea->Sym(), eb); eb->EndPoints(b, c); Edge *ec = makeEdge(); splice(eb->Sym(), ec); ec->EndPoints(c, d); Edge *ed = makeEdge(); splice(ec->Sym(), ed); ed->EndPoints(d, a); splice(ed->Sym(), ea); Edge *diag = makeEdge(); splice(ed->Sym(),diag); splice(eb->Sym(),diag->Sym()); diag->EndPoints(a,c); startingEdge = ea; first_face = NULL; makeFace(ea->Sym()).update(*this); makeFace(ec->Sym()).update(*this); }
void Subdivision::InsertSite(const Point2d& x) // Inserts a new point into a subdivision representing a Delaunay // triangulation, and fixes the affected edges so that the result // is still a Delaunay triangulation. This is based on the // pseudocode from Guibas and Stolfi (1985) p.120, with slight // modifications and a bug fix. { Edge* e = Locate(x); if ((x == e->Org2d()) || (x == e->Dest2d())) // point is already in return; else if (OnEdge(x, e)) { e = e->Oprev(); DeleteEdge(e->Onext()); } // Connect the new point to the vertices of the containing // triangle (or quadrilateral, if the new point fell on an // existing edge.) Edge* base = MakeEdge(); base->EndPoints(e->Org(), new Point2d(x)); Splice(base, e); startingEdge = base; do { base = Connect(e, base->Sym()); e = base->Oprev(); } while (e->Lnext() != startingEdge); // Examine suspect edges to ensure that the Delaunay condition // is satisfied. do { Edge* t = e->Oprev(); if (RightOf(t->Dest2d(), e) && InCircle(e->Org2d(), t->Dest2d(), e->Dest2d(), x)) { Swap(e); e = e->Oprev(); } else if (e->Onext() == startingEdge) // no more suspect edges return; else // pop a suspect edge e = e->Onext()->Lprev(); } while (TRUE); }
Edge *Subdivision::makeEdge(Vec2& org, Vec2& dest) { Edge *e = new Edge(); e->EndPoints(org, dest); return e; }