void Voronoi::onInit() { assert((vertices.size() == 0) && (edges.size() == 0) && "container should be empty"); // should check if p_boundary is empty. //create boundary p_boundary = { Vec2(0,0),Vec2(1,0),Vec2(1,1),Vec2(0,1) }; for (auto& p : p_boundary) p = Vec2( ((p.x - 0.5) * 10 + 0.5)*boundary_rect.width + boundary_rect.left, ((p.y - 0.5) * 10 + 0.5)*boundary_rect.height + boundary_rect.top); for (int i = 0; i < p_boundary.size(); i++) { auto v = createVertex(p_boundary[i]); } auto it_back_v = std::prev(vertices.end()); for (auto it = vertices.begin(); it != vertices.end(); it++) { QuadEdge* e = createEdge(); e->SetEndPoints(&*it_back_v, &*it); (&*it_back_v)->e = &edges.back().e[0]; it_back_v = it; } auto it_back_e = std::prev(edges.end()); for (auto it = edges.begin(); it != edges.end(); it++) { QuadEdge::Splice((*it_back_e).e[0].Sym(), &(*it).e[0]); it_back_e = it; } //triangulation if (p_boundary.size() >= 4) { QuadEdge* e = &edges.begin()->e[0]; QuadEdge* e_end = e->Lprev()->Lprev(); e = e->Lnext(); do { QuadEdge* et = e->Lnext(); QuadEdge::Connect(createEdge(), e, e->Lprev()); e = et; } while (e != e_end); } }
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; }