diff options
Diffstat (limited to 'src/base/triangulate/Shapes.cpp')
-rw-r--r-- | src/base/triangulate/Shapes.cpp | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/src/base/triangulate/Shapes.cpp b/src/base/triangulate/Shapes.cpp new file mode 100644 index 0000000..08e2e13 --- /dev/null +++ b/src/base/triangulate/Shapes.cpp @@ -0,0 +1,353 @@ +// +// libavg - Media Playback Engine. +// Copyright (C) 2003-2014 Ulrich von Zadow +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// Current versions can be found at www.libavg.de +// + +// +// Based on Poly2Tri algorithm. +// Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors +// http://code.google.com/p/poly2tri/ +// + +#include "Shapes.h" +#include <iostream> + +namespace avg { + +TriangulationTriangle::TriangulationTriangle(Point& a, Point& b, Point& c) +{ + m_Points[0] = &a; + m_Points[1] = &b; + m_Points[2] = &c; + m_Neighbors[0] = NULL; + m_Neighbors[1] = NULL; + m_Neighbors[2] = NULL; + m_ConstrainedEdge[0] = m_ConstrainedEdge[1] = m_ConstrainedEdge[2] = false; + m_DelaunayEdge[0] = m_DelaunayEdge[1] = m_DelaunayEdge[2] = false; + m_Interior = false; +} + +// Update neighbor pointers +void TriangulationTriangle::markNeighbor(Point* p1, Point* p2, + TriangulationTriangle* t) +{ + if ((p1 == m_Points[2] && p2 == m_Points[1]) + || (p1 == m_Points[1] && p2 == m_Points[2])) { + m_Neighbors[0] = t; + } else if ((p1 == m_Points[0] && p2 == m_Points[2]) + || (p1 == m_Points[2] && p2 == m_Points[0])) { + m_Neighbors[1] = t; + } else if ((p1 == m_Points[0] && p2 == m_Points[1]) + || (p1 == m_Points[1] && p2 == m_Points[0])) { + m_Neighbors[2] = t; + } else { + assert(0); + } + +} + +// Exhaustive search to update neighbor pointers +void TriangulationTriangle::markNeighbor(TriangulationTriangle& t) +{ + if (t.contains(m_Points[1], m_Points[2])) { + m_Neighbors[0] = &t; + t.markNeighbor(m_Points[1], m_Points[2], this); + } else if (t.contains(m_Points[0], m_Points[2])) { + m_Neighbors[1] = &t; + t.markNeighbor(m_Points[0], m_Points[2], this); + } else if (t.contains(m_Points[0], m_Points[1])) { + m_Neighbors[2] = &t; + t.markNeighbor(m_Points[0], m_Points[1], this); + } +} + +void TriangulationTriangle::clear() +{ + TriangulationTriangle *t; + for (int i = 0; i < 3; i++) { + t = m_Neighbors[i]; + if (t != NULL) { + t->clearNeighbor(this); + } + } + clearNeighbors(); + m_Points[0] = m_Points[1] = m_Points[2] = NULL; +} + +void TriangulationTriangle::clearNeighbor(TriangulationTriangle *triangle) +{ + if (m_Neighbors[0] == triangle) { + m_Neighbors[0] = NULL; + } else if (m_Neighbors[1] == triangle) { + m_Neighbors[1] = NULL; + } else { + m_Neighbors[2] = NULL; + } +} + +void TriangulationTriangle::clearNeighbors() +{ + m_Neighbors[0] = NULL; + m_Neighbors[1] = NULL; + m_Neighbors[2] = NULL; +} + +void TriangulationTriangle::clearDelunayEdges() +{ + m_DelaunayEdge[0] = m_DelaunayEdge[1] = m_DelaunayEdge[2] = false; +} + +Point* TriangulationTriangle::oppositePoint(TriangulationTriangle& t, + Point& p) { + Point *cw = t.pointCW(p); + return pointCW(*cw); +} + +// Legalized triangle by rotating clockwise around point(0) +void TriangulationTriangle::legalize(Point& point) +{ + m_Points[1] = m_Points[0]; + m_Points[0] = m_Points[2]; + m_Points[2] = &point; +} + +// Legalize triagnle by rotating clockwise around oPoint +void TriangulationTriangle::legalize(Point& opoint, Point& npoint) +{ + if (&opoint == m_Points[0]) { + m_Points[1] = m_Points[0]; + m_Points[0] = m_Points[2]; + m_Points[2] = &npoint; + } else if (&opoint == m_Points[1]) { + m_Points[2] = m_Points[1]; + m_Points[1] = m_Points[0]; + m_Points[0] = &npoint; + } else if (&opoint == m_Points[2]) { + m_Points[0] = m_Points[2]; + m_Points[2] = m_Points[1]; + m_Points[1] = &npoint; + } else { + assert(0); + } +} + +unsigned int TriangulationTriangle::index(const Point* p) +{ + if (p == m_Points[0]) { + return 0; + } else if (p == m_Points[1]) { + return 1; + } else if (p == m_Points[2]) { + return 2; + } + assert(0); + return 0; +} + +unsigned int TriangulationTriangle::edgeIndex(const Point* p1, const Point* p2) +{ + if (m_Points[0] == p1) { + if (m_Points[1] == p2) { + return 2; + } else if (m_Points[2] == p2) { + return 1; + } + } else if (m_Points[1] == p1) { + if (m_Points[2] == p2) { + return 0; + } else if (m_Points[0] == p2) { + return 2; + } + } else if (m_Points[2] == p1) { + if (m_Points[0] == p2) { + return 1; + } else if (m_Points[1] == p2) { + return 0; + } + } + return -1; +} + +void TriangulationTriangle::markConstrainedEdge(const int index) +{ + m_ConstrainedEdge[index] = true; +} + +void TriangulationTriangle::markConstrainedEdge(Edge& edge) +{ + markConstrainedEdge(edge.m_P, edge.m_Q); +} + +void TriangulationTriangle::markConstrainedEdge(Point* p, Point* q) +{ + if ((q == m_Points[0] && p == m_Points[1]) + || (q == m_Points[1] && p == m_Points[0])) { + m_ConstrainedEdge[2] = true; + } else if ((q == m_Points[0] && p == m_Points[2]) + || (q == m_Points[2] && p == m_Points[0])) { + m_ConstrainedEdge[1] = true; + } else if ((q == m_Points[1] && p == m_Points[2]) + || (q == m_Points[2] && p == m_Points[1])) { + m_ConstrainedEdge[0] = true; + } +} + +// The point counter-clockwise to given point +Point* TriangulationTriangle::pointCW(Point& point) +{ + if (&point == m_Points[0]) { + return m_Points[2]; + } else if (&point == m_Points[1]) { + return m_Points[0]; + } else if (&point == m_Points[2]) { + return m_Points[1]; + } + assert(0); + return 0; // Silence compiler warning +} + +Point* TriangulationTriangle::pointCCW(Point& point) +{ + if (&point == m_Points[0]) { + return m_Points[1]; + } else if (&point == m_Points[1]) { + return m_Points[2]; + } else if (&point == m_Points[2]) { + return m_Points[0]; + } + assert(0); + return 0; // Silence compiler warning +} + +TriangulationTriangle* TriangulationTriangle::neighborCW(Point& point) +{ + if (&point == m_Points[0]) { + return m_Neighbors[1]; + } else if (&point == m_Points[1]) { + return m_Neighbors[2]; + } + return m_Neighbors[0]; +} + +TriangulationTriangle* TriangulationTriangle::neighborCCW(Point& point) +{ + if (&point == m_Points[0]) { + return m_Neighbors[2]; + } else if (&point == m_Points[1]) { + return m_Neighbors[0]; + } + return m_Neighbors[1]; +} + +bool TriangulationTriangle::getConstrainedEdgeCCW(Point& p) +{ + if (&p == m_Points[0]) { + return m_ConstrainedEdge[2]; + } else if (&p == m_Points[1]) { + return m_ConstrainedEdge[0]; + } + return m_ConstrainedEdge[1]; +} + +bool TriangulationTriangle::getConstrainedEdgeCW(Point& p) +{ + if (&p == m_Points[0]) { + return m_ConstrainedEdge[1]; + } else if (&p == m_Points[1]) { + return m_ConstrainedEdge[2]; + } + return m_ConstrainedEdge[0]; +} + +void TriangulationTriangle::setConstrainedEdgeCCW(Point& p, bool ce) +{ + if (&p == m_Points[0]) { + m_ConstrainedEdge[2] = ce; + } else if (&p == m_Points[1]) { + m_ConstrainedEdge[0] = ce; + } else { + m_ConstrainedEdge[1] = ce; + } +} + +void TriangulationTriangle::setConstrainedEdgeCW(Point& p, bool ce) +{ + if (&p == m_Points[0]) { + m_ConstrainedEdge[1] = ce; + } else if (&p == m_Points[1]) { + m_ConstrainedEdge[2] = ce; + } else { + m_ConstrainedEdge[0] = ce; + } +} + +bool TriangulationTriangle::getDelunayEdgeCCW(Point& p) +{ + if (&p == m_Points[0]) { + return m_DelaunayEdge[2]; + } else if (&p == m_Points[1]) { + return m_DelaunayEdge[0]; + } + return m_DelaunayEdge[1]; +} + +bool TriangulationTriangle::getDelunayEdgeCW(Point& p) +{ + if (&p == m_Points[0]) { + return m_DelaunayEdge[1]; + } else if (&p == m_Points[1]) { + return m_DelaunayEdge[2]; + } + return m_DelaunayEdge[0]; +} + +void TriangulationTriangle::setDelunayEdgeCCW(Point& p, bool e) +{ + if (&p == m_Points[0]) { + m_DelaunayEdge[2] = e; + } else if (&p == m_Points[1]) { + m_DelaunayEdge[0] = e; + } else { + m_DelaunayEdge[1] = e; + } +} + +void TriangulationTriangle::setDelunayEdgeCW(Point& p, bool e) +{ + if (&p == m_Points[0]) { + m_DelaunayEdge[1] = e; + } else if (&p == m_Points[1]) { + m_DelaunayEdge[2] = e; + } else { + m_DelaunayEdge[0] = e; + } +} + +TriangulationTriangle& TriangulationTriangle::neighborAcross(Point& opoint) +{ + if (&opoint == m_Points[0]) { + return *m_Neighbors[0]; + } else if (&opoint == m_Points[1]) { + return *m_Neighbors[1]; + } + return *m_Neighbors[2]; +} + +} + |