QuadEdge *connect( QuadEdge *a, QuadEdge *b ) { QuadEdge *e = makeEdge(); e->setOrg( a->Dest() ); e->setDest( b->Org() ); splice( e, a->Lnext() ); splice( e->Sym(), b ); return e; }
Vertex* Voronoi::InsertPoint(const Vec2& p) { QuadEdge* e = LocateTriangleEdge(p); if (e == nullptr || p == e->Org()->p || p == e->Dest()->p) return nullptr; else if (VoronoiMath::Collinear(e, p)) { e = e->Oprev(); QuadEdge* et = e->Onext(); QuadEdge::Disconnect(et); deleteEdge(et->RootEdge()); } Vertex* v = createVertex(p); v->e = e; QuadEdge* e_begin = createEdge(); e_begin->SetEndPoints(e->Org(), v); QuadEdge* et = e_begin; QuadEdge::Splice(e_begin, e); do { QuadEdge* et2 = createEdge(); QuadEdge::Connect(et2, e, et->Sym()); et = et2; e = et->Oprev(); } while (e->Lnext() != e_begin); do { et = e->Oprev(); if (VoronoiMath::OnRight(e, et->Dest()->p) && VoronoiMath::InCircle(e->Org()->p, et->Dest()->p, e->Dest()->p, p)) { QuadEdge::Flip(e); e = e->Oprev(); } else if (e->Onext() == e_begin) break; else e = e->Onext()->Lprev(); } while (true); return v; }
QuadEdge * Voronoi::LocateTriangleEdge(const Vec2 & p) { int i = 0; QuadEdge* e = &edges.front().e[0]; while (true) { if (e->Org()->p == p || e->Dest()->p == p) return e; if (VoronoiMath::OnRight(e, p)) e = e->Sym(); else if (!VoronoiMath::OnRight(e->Onext(), p)) e = e->Onext(); else if (!VoronoiMath::OnRight(e->Dprev(), p)) e = e->Dprev(); else return e; if (++i > 100000) break; } return nullptr; }