Edge * splitFace(Face *fl, Vertex *v1, Vertex *v2) {

	Face *fr = new Face();

	//cout << "  split vertices: " << v1->p << "-" << v2->p << endl;
	Edge *a = v1->getEdge();
	Edge *b = v2->getEdge();
	Edge *c = Edge::makeEdge(v1, v2, fl, fr);

	while (a->Left() != fl) { a = a->Onext(); }
	while (b->Left() != fl) { b = b->Onext(); }

	Edge::splice(a, c);
	Edge::splice(b, c->Sym());

	Edge *cIter = c->Lnext();
	while (cIter != c) {
		cIter->setLeft(fl);
		cIter = cIter->Lnext();
	}
	cIter = c->Rnext();
	while (cIter != c) {
		cIter->setRight(fr);
		cIter = cIter->Rnext();
	}

	return c;
}
Пример #2
0
//
// s is a spoke pointing OUT from x
//
void Subdivision::optimize(Vec2& x, Edge *s)
{
    Edge *start_spoke = s;
    Edge *spoke = s;

    do {

	Edge *e = spoke->Lnext();
	Edge *t = e->Oprev();

	if( isInterior(e) && shouldSwap(x, e) )
	    swap(e);
	else
	{
	    spoke = spoke->Onext();
	    if( spoke == start_spoke )
		break;
	}

    } while( true );

    //
    // Now, update all the triangles

    spoke = start_spoke;

    do {
	Edge *e = spoke->Lnext();
	Triangle *t = e->Lface();

	if( t ) t->update(*this);

	spoke = spoke->Onext();
    } while( spoke != start_spoke );
}
Пример #3
0
void Swap(Edge* e)
// Essentially turns edge e counterclockwise inside its enclosing
// quadrilateral. The data pointers are modified accordingly.
{
	Edge* a = e->Oprev();
	Edge* b = e->Sym()->Oprev();
	Splice(e, a);
	Splice(e->Sym(), b);
	Splice(e, a->Lnext());
	Splice(e->Sym(), b->Lnext());
	e->EndPoints(a->Dest(), b->Dest());
}
int getFaceOrder(Edge *e, vector<Vertex>& pts) {
	int count = 1;
	Edge *iter = e->Lnext();

	if (iter->Left() == NULL) {
		return -1;
	}
	if (iter == NULL) {
		cout << "Erro: ponteiro next == NULL\n";
		return -1;
	}

	pts.clear();
	pts.push_back(*e->Orig());

	while (iter != e && count < 100) {
		count++;
		pts.push_back(*iter->Orig());
		iter = iter->Lnext();
	}

	if (count == 100) {
		cout << "Erro: loop infinito\n";
		return -1;
	}

	return count;
}
Пример #5
0
void Subdivision::swap(Edge *e)
{
    Triangle *f1 = e->Lface();
    Triangle *f2 = e->Sym()->Lface();

    Edge *a = e->Oprev();
    Edge *b = e->Sym()->Oprev();

    splice(e, a);
    splice(e->Sym(), b);
    splice(e, a->Lnext());
    splice(e->Sym(), b->Lnext());
    e->EndPoints(a->Dest(), b->Dest());


    f1->reshape(e);
    f2->reshape(e->Sym());
}
Пример #6
0
void Cell::setOrbitLeft(Edge *edge, Face *left) {
    assert(edge != 0);
    assert(left != 0);

    // traverse the Lnext orbit of _edge_, setting the left face of each edge to
    // _left_
    Edge *scan = edge;

    do {
        scan->setLeft(left);
        scan = scan->Lnext();
    } while (scan != edge);
}
Point getFaceCentroid(Face *f) {
	int count = 1;
	Point p(-1,-1);

	if (f == NULL)
		return p;

	Edge *e = f->getEdge();
	Edge *iter = e->Lnext();

	p = e->Orig()->p;

	while (iter != e) {
		Point np = iter->Orig()->p;
		p += np;
		count++;
		iter = iter->Lnext();
	}

	p.x /= count;
	p.y /= count;

	return p;
}
Пример #8
0
Edge *Cell::getOrbitOrg(Edge *edge, Vertex *org) {
    assert(edge != 0);
    assert(org != 0);

    // traverse the Lnext orbit of _edge_ looking for an edge whose origin is
    // _org_
    Edge *scan = edge;

    do {
        if (scan->Org() == org) {
            return scan;
        }

        scan = scan->Lnext();
    } while (scan != edge);

    return 0;
}
Пример #9
0
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);
}
int getFaceOrder(Edge *e) {
	int count = 1;
	Edge *iter = e->Lnext();

	if (iter->Left() == NULL) {
		return -1;
	}
	if (iter == NULL) {
		cout << "Erro: ponteiro next == NULL\n";
		return -1;
	}

	while (iter != e && count < 100) {
		count++;
		iter = iter->Lnext();
	}

	if (count == 100) {
		cout << "Erro: loop infinito\n";
		return -1;
	}

	return count;
}
Пример #11
0
int main() {
        using cgl::Point2d;
        using cgl::Edge;
        using cgl::make_edge;

        // Point2d *a = new Point2d(0.0, 0.0); // 0
        // Point2d *b = new Point2d(1.0, 0.0); // 1
        // Point2d *c = new Point2d(1.0, 1.0); // 2
        // Point2d *d = new Point2d(0.0, 1.0); // 3

        Edge *ea = make_edge(0, 1);
        Edge *eb = make_edge(ea->Dest(), 2);
        Edge *ec = make_edge(eb->Dest(), 3);
        Edge *ed = make_edge(ec->Dest(), 0);
        Edge *ee = make_edge(eb->Dest(), ea->Org());

        // Connect eb to ea->Dest()
        splice(ea->Sym(), eb);
        // Connect ec to eb->Dest()
        splice(eb->Sym(), ec);
        // Connect ed to ec->Sym() and ea
        splice(ec->Sym(), ed);
        splice(ed->Sym(), ea);
        // Connect ee to ec and ea -- this is equivalent to Delaunay::connect
        splice(ee, eb->Lnext());
        splice(ee->Sym(), ea);

        // Traverse the convex hull
        if (ea->Dnext() != eb->Sym()) {
                std::cerr << "Error: ea->Dnext() != eb->Sym()" << std::endl;
                return 1;
        }

        if (eb->Dnext() != ec->Sym()) {
                std::cerr << "Error: eb->Dnext() != ec->Sym()" << std::endl;
                return 1;
        }

        if (ec->Dnext() != ed->Sym()) {
                std::cerr << "Error: ec->Dnext() != ed->Sym()" << std::endl;
                return 1;
        }

        if (ed->Dprev() != ee) {
                std::cerr << "Error: ed->Dprev() != ee" << std::endl;
                return 1;
        }

        // Cross linkage -- test algebra
        // Rot / invRot
        if (ee->Rot()->Org() != ed->invRot()->Org()) {
                std::cerr << "Error: ee->Rot()->Org() != ed->invRot()->Org()" <<
                        std::endl;
                return 1;
        }

        // Sym
        if (ee->Sym()->Org() != 0) {
                std::cerr << "Error: ee->Sym()->Org() != a" << std::endl;
                return 1;
        }

        // Onext
        if (ee->Onext() != eb->Sym()) {
                std::cerr << "Error: ee->Onext() != eb->Sym()" << std::endl;
                return 1;
        }

        // Oprev
        if (ee->Oprev() != ec) {
                std::cerr << "Error: ee->Oprev() != ec" << std::endl;
                return 1;
        }

        // Dnext
        if (ee->Dnext() != ed) {
                std::cerr << "Error: ee->Dnext() != ed" << std::endl;
                return 1;
        }

        // Dprev
        if (ee->Dprev() != ea->Sym()) {
                std::cerr << "Error: ee->Dprev() != ea->Sym()" << std::endl;
                return 1;
        }

        // Lnext
        if (ee->Lnext() != ea) {
                std::cerr << "Error: ee->Lnext() != ea" << std::endl;
                return 1;
        }

        // Lprev
        if (ee->Lprev() != eb) {
                std::cerr << "Error: ee->Lprev() != eb" << std::endl;
                return 1;
        }

        // Rnext
        if (ee->Rnext() != ec->Sym()) {
                std::cerr << "Error: ee->Rnext() != ec->Sym()" << std::endl;
                return 1;
        }

        // Rprev
        if (ee->Rprev() != ed->Sym()) {
                std::cerr << "Error: ee->Rprev() != ed->Sym()" << std::endl;
                return 1;
        }

        // Org / Dest
        if (ed->Org() != 3) {
                std::cerr << "Error: ed->Org() != d" << std::endl;
                return 1;
        }

        if (ed->Dest() != 0) {
                std::cerr << "Error: ed->Dest() != a" << std::endl;
                return 1;
        }

        if (ee->Org()  != 2) {
                std::cerr << "Error: ee->Org() != c" << std::endl;
                return 1;
        }

        if (ee->Dest()  != 0) {
                std::cerr << "Error: ee->Dest() != a" << std::endl;
                return 1;
        }

        // Let the system clean up the memory

        return 0;
}