Ejemplo n.º 1
0
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);
	}
}
Ejemplo n.º 2
0
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;
}