示例#1
0
std::auto_ptr<QuadEdge>
QuadEdge::makeEdge(const Vertex &o, const Vertex &d)
{
	QuadEdge *q0 = new QuadEdge();
	//q1-q3 are free()'d by q0
	QuadEdge *q1 = new QuadEdge();
	QuadEdge *q2 = new QuadEdge();
	QuadEdge *q3 = new QuadEdge();

	q0->_rot = q1;
	q1->_rot = q2;
	q2->_rot = q3;
	q3->_rot = q0;

	q0->setNext(q0);
	q1->setNext(q3);
	q2->setNext(q2);
	q3->setNext(q1);

	QuadEdge *base = q0;
	base->setOrig(o);
	base->setDest(d);

	return std::auto_ptr<QuadEdge>(base);
}
示例#2
0
std::auto_ptr<QuadEdge>
QuadEdge::connect(QuadEdge &a, QuadEdge &b) 
{
	std::auto_ptr<QuadEdge> q0 = makeEdge(a.dest(), b.orig());
	splice(*q0, a.lNext());
	splice(q0->sym(), b);
	return q0;
}
示例#3
0
bool
QuadEdge::equalsOriented(const QuadEdge &qe) const
{
	if (orig().getCoordinate().equals2D(qe.orig().getCoordinate())
			&& dest().getCoordinate().equals2D(qe.dest().getCoordinate()))
		return true;
	return false;
}
示例#4
0
文件: edge.cpp 项目: dose78/FRPA
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;
}
示例#5
0
bool
QuadEdge::equalsNonOriented(const QuadEdge &qe) const
{
	if (equalsOriented(qe))
		return true;
	if (equalsOriented(qe.sym()))
		return true;
	return false;
}
示例#6
0
bool
QuadEdge::testEqualQuadEdge(const QuadEdge& qe2)
{
	/*
	   if(&qe1 == NULL && &qe2 == NULL)
	   {
	   return 1;
	   }
	   else if((&qe1==NULL && &qe2!=NULL) || (&qe1!=NULL && &qe2==NULL))
	   {
	   return 0;
	   }
	 */
	//when both of them are not null:
	if((*_rot).testEqualQuadEdge(qe2.rot()) && (*next).testEqualQuadEdge(qe2.oNext()) //&& (*data == *(qe2.data)) 
			&& (isAlive == qe2.isAlive) /*&& orig()==qe2.orig()*/)
		return 1;
	else
		return 0;

}
示例#7
0
void
QuadEdge::swap(QuadEdge &e)
{
	QuadEdge &a = e.oPrev();
	QuadEdge &b = e.sym().oPrev();
	splice(e, a);
	splice(e.sym(), b);
	splice(e, a.lNext());
	splice(e.sym(), b.lNext());
	e.setOrig(a.dest());
	e.setDest(b.dest());
}
示例#8
0
文件: edge.cpp 项目: dose78/FRPA
void splice( QuadEdge *a, QuadEdge *b ) {
  QuadEdge *alpha = a->Onext()->Rot();
  QuadEdge *beta = b->Onext()->Rot();

  QuadEdge *temp = a->Onext();
  a->setOnext( b->Onext() );
  b->setOnext( temp );

  temp = alpha->Onext();
  alpha->setOnext( beta->Onext() );
  beta->setOnext( temp );
}
示例#9
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);
	}
}
示例#10
0
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;
}
示例#11
0
void
QuadEdge::splice(QuadEdge &a, QuadEdge &b)
{
	QuadEdge &alpha = a.oNext().rot();
	QuadEdge &beta = b.oNext().rot();

	QuadEdge &t1 = b.oNext();
	QuadEdge &t2 = a.oNext();
	QuadEdge &t3 = beta.oNext();
	QuadEdge &t4 = alpha.oNext();

	a.setNext(&t1);
	b.setNext(&t2);
	alpha.setNext(&t3);
	beta.setNext(&t4);
}
QuadEdge& IncrementalDelaunayTriangulator::insertSite(const Vertex &v)
{
	/**
	 * This code is based on Guibas and Stolfi (1985), with minor modifications
	 * and a bug fix from Dani Lischinski (Graphic Gems 1993). (The modification
	 * I believe is the test for the inserted site falling exactly on an
	 * existing edge. Without this test zero-width triangles have been observed
	 * to be created)
	 */
	QuadEdge *e = subdiv->locate(v);

	if(!e) {
		throw LocateFailureException("");
	}

	if (subdiv->isVertexOfEdge(*e, v)) {
		// point is already in subdivision.
		return *e; 
	} 
	else if (subdiv->isOnEdge(*e, v.getCoordinate())) {
		// the point lies exactly on an edge, so delete the edge 
		// (it will be replaced by a pair of edges which have the point as a vertex)
		e = &e->oPrev();
		subdiv->remove(e->oNext());
	}

	/**
	 * Connect the new point to the vertices of the containing triangle 
	 * (or quadrilateral, if the new point fell on an existing edge.)
	 */
	QuadEdge* base = &subdiv->makeEdge(e->orig(), v);

	QuadEdge::splice(*base, *e);
	QuadEdge *startEdge = base;
	do {
		base = &subdiv->connect(*e, base->sym());
		e = &base->oPrev();
	} while (&e->lNext() != startEdge);


	// Examine suspect edges to ensure that the Delaunay condition
	// is satisfied.
	do {
		QuadEdge* t = &e->oPrev();
		if (t->dest().rightOf(*e) &&
				v.isInCircle(e->orig(), t->dest(), e->dest())) {
			QuadEdge::swap(*e);
			e = &e->oPrev();
		} else if (&e->oNext() == startEdge) {
			return *base; // no more suspect edges.
		} else {
			e = &e->oNext().lPrev();
		}
	} while (true);
}
示例#13
0
bool Vertex::leftOf(const QuadEdge &e) const {
	return isCCW(e.orig(), e.dest());
}
示例#14
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;
}