Full Code of greenm01/poly2tri for AI

master a922022da4c0 cached
19 files
104.4 KB
31.1k tokens
65 symbols
1 requests
Download .txt
Repository: greenm01/poly2tri
Branch: master
Commit: a922022da4c0
Files: 19
Total size: 104.4 KB

Directory structure:
gitextract_iis_kvpo/

├── AUTHORS
├── LICENSE
├── README
├── poly2tri/
│   ├── common/
│   │   ├── shapes.cc
│   │   ├── shapes.h
│   │   └── utils.h
│   ├── poly2tri.h
│   └── sweep/
│       ├── advancing_front.cc
│       ├── advancing_front.h
│       ├── cdt.cc
│       ├── cdt.h
│       ├── sweep.cc
│       ├── sweep.h
│       ├── sweep_context.cc
│       └── sweep_context.h
├── testbed/
│   ├── data/
│   │   └── polygon.dae
│   └── main.cc
├── waf
└── wscript

================================================
FILE CONTENTS
================================================

================================================
FILE: AUTHORS
================================================
Primary Contributors:

  Mason Green <mason.green@gmail.com> (C++, Python)
  Thomas hln <thahlen@gmail.com>    (Java)

Other Contributors:

  


================================================
FILE: LICENSE
================================================
Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
http://code.google.com/p/poly2tri/

All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
* Neither the name of Poly2Tri nor the names of its contributors may be
  used to endorse or promote products derived from this software without specific
  prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: README
================================================
#####################################################################################
###
### Since there are no Input validation of the data given for triangulation you need 
### to think about this. Poly2Tri does not support repeat points within epsilon.
### 
### * If you have a cyclic function that generates random points make sure you don't 
### add the same coordinate twice.
###
### * If you are given input and aren't sure same point exist twice you need to 
### check for this yourself.
###      
### * Only simple polygons are supported. You may add holes or interior Steiner points
###
### * Interior holes must not touch other holes, nor touch the polyline boundary
###
### * Use the library in this order:
###
### 1) Initialize CDT with a simple polyline (this defines the constrained edges)
### 2) Add holes if necessary (also simple polylines)
### 3) Add Steiner points
### 4) Triangulate
###
### Make sure you understand the preceding notice before posting an issue. If you have 
### an issue not covered by the above, include your data-set with the problem.
###
### The only easy day was yesterday; have a nice day. <Mason Green>
###
######################################################################################

===========================
TESTBED INSTALLATION GUIDE
===========================

------------
Dependencies
------------

  Core poly2tri lib:
  - Standard Template Library (STL)
  
  Testbed:
  - gcc
  - OpenGL
  - GLFW (http://glfw.sf.net)
  - Python
 
waf (http://code.google.com/p/waf/) is used to compile the testbed.   
A waf script (86kb) is included in the repositoty.

----------------------------------------------
Building the Testbed
----------------------------------------------

Posix/MSYS environment:

  ./waf configure
  ./waf build

Windows command line:

  python waf configure
  python waf build

----------------------------------------------
Running the Examples
----------------------------------------------

Load data points from a file:
p2t <filename> <center_x> <center_y> <zoom>

Random distribution of points inside a consrained box:
p2t random <num_points> <box_radius> <zoom>

Examples:

  ./p2t dude.dat 300 500 2
  ./p2t nazca_monkey.dat 0 0 9
  
  ./p2t random 10 100 5.0
  ./p2t random 1000 20000 0.025


================================================
FILE: poly2tri/common/shapes.cc
================================================
/* 
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "shapes.h"
#include <iostream>

namespace p2t {

Triangle::Triangle(Point& a, Point& b, Point& c)
{
  points_[0] = &a; points_[1] = &b; points_[2] = &c;
  neighbors_[0] = NULL; neighbors_[1] = NULL; neighbors_[2] = NULL;
  constrained_edge[0] = constrained_edge[1] = constrained_edge[2] = false;
  delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
  interior_ = false;
}

// Update neighbor pointers
void Triangle::MarkNeighbor(Point* p1, Point* p2, Triangle* t)
{
  if ((p1 == points_[2] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[2]))
    neighbors_[0] = t;
  else if ((p1 == points_[0] && p2 == points_[2]) || (p1 == points_[2] && p2 == points_[0]))
    neighbors_[1] = t;
  else if ((p1 == points_[0] && p2 == points_[1]) || (p1 == points_[1] && p2 == points_[0]))
    neighbors_[2] = t;
  else
    assert(0);
}

// Exhaustive search to update neighbor pointers
void Triangle::MarkNeighbor(Triangle& t)
{
  if (t.Contains(points_[1], points_[2])) {
    neighbors_[0] = &t;
    t.MarkNeighbor(points_[1], points_[2], this);
  } else if (t.Contains(points_[0], points_[2])) {
    neighbors_[1] = &t;
    t.MarkNeighbor(points_[0], points_[2], this);
  } else if (t.Contains(points_[0], points_[1])) {
    neighbors_[2] = &t;
    t.MarkNeighbor(points_[0], points_[1], this);
  }
}

/**
 * Clears all references to all other triangles and points
 */
void Triangle::Clear()
{
    Triangle *t;
    for( int i=0; i<3; i++ )
    {
        t = neighbors_[i];
        if( t != NULL )
        {
            t->ClearNeighbor( this );
        }
    }
    ClearNeighbors();
    points_[0]=points_[1]=points_[2] = NULL;
}

void Triangle::ClearNeighbor(Triangle *triangle )
{
    if( neighbors_[0] == triangle )
    {
        neighbors_[0] = NULL;
    }
    else if( neighbors_[1] == triangle )
    {
        neighbors_[1] = NULL;            
    }
    else
    {
        neighbors_[2] = NULL;
    }
}
    
void Triangle::ClearNeighbors()
{
  neighbors_[0] = NULL;
  neighbors_[1] = NULL;
  neighbors_[2] = NULL;
}

void Triangle::ClearDelunayEdges()
{
  delaunay_edge[0] = delaunay_edge[1] = delaunay_edge[2] = false;
}

Point* Triangle::OppositePoint(Triangle& t, Point& p)
{
  Point *cw = t.PointCW(p);
  double x = cw->x;
  double y = cw->y;
  x = p.x;
  y = p.y;
  return PointCW(*cw);
}

// Legalized triangle by rotating clockwise around point(0)
void Triangle::Legalize(Point& point)
{
  points_[1] = points_[0];
  points_[0] = points_[2];
  points_[2] = &point;
}

// Legalize triagnle by rotating clockwise around oPoint
void Triangle::Legalize(Point& opoint, Point& npoint)
{
  if (&opoint == points_[0]) {
    points_[1] = points_[0];
    points_[0] = points_[2];
    points_[2] = &npoint;
  } else if (&opoint == points_[1]) {
    points_[2] = points_[1];
    points_[1] = points_[0];
    points_[0] = &npoint;
  } else if (&opoint == points_[2]) {
    points_[0] = points_[2];
    points_[2] = points_[1];
    points_[1] = &npoint;
  } else {
    assert(0);
  }
}

int Triangle::Index(const Point* p)
{
  if (p == points_[0]) {
    return 0;
  } else if (p == points_[1]) {
    return 1;
  } else if (p == points_[2]) {
    return 2;
  }
  assert(0);
}

int Triangle::EdgeIndex(const Point* p1, const Point* p2)
{
  if (points_[0] == p1) {
    if (points_[1] == p2) {
      return 2;
    } else if (points_[2] == p2) {
      return 1;
    }
  } else if (points_[1] == p1) {
    if (points_[2] == p2) {
      return 0;
    } else if (points_[0] == p2) {
      return 2;
    }
  } else if (points_[2] == p1) {
    if (points_[0] == p2) {
      return 1;
    } else if (points_[1] == p2) {
      return 0;
    }
  }
  return -1;
}

void Triangle::MarkConstrainedEdge(const int index)
{
  constrained_edge[index] = true;
}

void Triangle::MarkConstrainedEdge(Edge& edge)
{
  MarkConstrainedEdge(edge.p, edge.q);
}

// Mark edge as constrained
void Triangle::MarkConstrainedEdge(Point* p, Point* q)
{
  if ((q == points_[0] && p == points_[1]) || (q == points_[1] && p == points_[0])) {
    constrained_edge[2] = true;
  } else if ((q == points_[0] && p == points_[2]) || (q == points_[2] && p == points_[0])) {
    constrained_edge[1] = true;
  } else if ((q == points_[1] && p == points_[2]) || (q == points_[2] && p == points_[1])) {
    constrained_edge[0] = true;
  }
}

// The point counter-clockwise to given point
Point* Triangle::PointCW(Point& point)
{
  if (&point == points_[0]) {
    return points_[2];
  } else if (&point == points_[1]) {
    return points_[0];
  } else if (&point == points_[2]) {
    return points_[1];
  }
  assert(0);
}

// The point counter-clockwise to given point
Point* Triangle::PointCCW(Point& point)
{
  if (&point == points_[0]) {
    return points_[1];
  } else if (&point == points_[1]) {
    return points_[2];
  } else if (&point == points_[2]) {
    return points_[0];
  }
  assert(0);
}

// The neighbor clockwise to given point
Triangle* Triangle::NeighborCW(Point& point)
{
  if (&point == points_[0]) {
    return neighbors_[1];
  } else if (&point == points_[1]) {
    return neighbors_[2];
  }
  return neighbors_[0];
}

// The neighbor counter-clockwise to given point
Triangle* Triangle::NeighborCCW(Point& point)
{
  if (&point == points_[0]) {
    return neighbors_[2];
  } else if (&point == points_[1]) {
    return neighbors_[0];
  }
  return neighbors_[1];
}

bool Triangle::GetConstrainedEdgeCCW(Point& p)
{
  if (&p == points_[0]) {
    return constrained_edge[2];
  } else if (&p == points_[1]) {
    return constrained_edge[0];
  }
  return constrained_edge[1];
}

bool Triangle::GetConstrainedEdgeCW(Point& p)
{
  if (&p == points_[0]) {
    return constrained_edge[1];
  } else if (&p == points_[1]) {
    return constrained_edge[2];
  }
  return constrained_edge[0];
}

void Triangle::SetConstrainedEdgeCCW(Point& p, bool ce)
{
  if (&p == points_[0]) {
    constrained_edge[2] = ce;
  } else if (&p == points_[1]) {
    constrained_edge[0] = ce;
  } else {
    constrained_edge[1] = ce;
  }
}

void Triangle::SetConstrainedEdgeCW(Point& p, bool ce)
{
  if (&p == points_[0]) {
    constrained_edge[1] = ce;
  } else if (&p == points_[1]) {
    constrained_edge[2] = ce;
  } else {
    constrained_edge[0] = ce;
  }
}

bool Triangle::GetDelunayEdgeCCW(Point& p)
{
  if (&p == points_[0]) {
    return delaunay_edge[2];
  } else if (&p == points_[1]) {
    return delaunay_edge[0];
  }
  return delaunay_edge[1];
}

bool Triangle::GetDelunayEdgeCW(Point& p)
{
  if (&p == points_[0]) {
    return delaunay_edge[1];
  } else if (&p == points_[1]) {
    return delaunay_edge[2];
  }
  return delaunay_edge[0];
}

void Triangle::SetDelunayEdgeCCW(Point& p, bool e)
{
  if (&p == points_[0]) {
    delaunay_edge[2] = e;
  } else if (&p == points_[1]) {
    delaunay_edge[0] = e;
  } else {
    delaunay_edge[1] = e;
  }
}

void Triangle::SetDelunayEdgeCW(Point& p, bool e)
{
  if (&p == points_[0]) {
    delaunay_edge[1] = e;
  } else if (&p == points_[1]) {
    delaunay_edge[2] = e;
  } else {
    delaunay_edge[0] = e;
  }
}

// The neighbor across to given point
Triangle& Triangle::NeighborAcross(Point& opoint)
{
  if (&opoint == points_[0]) {
    return *neighbors_[0];
  } else if (&opoint == points_[1]) {
    return *neighbors_[1];
  }
  return *neighbors_[2];
}

void Triangle::DebugPrint()
{
  using namespace std;
  cout << points_[0]->x << "," << points_[0]->y << " ";
  cout << points_[1]->x << "," << points_[1]->y << " ";
  cout << points_[2]->x << "," << points_[2]->y << endl;
}

}



================================================
FILE: poly2tri/common/shapes.h
================================================
/*
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// Include guard
#ifndef SHAPES_H
#define SHAPES_H

#include <vector>
#include <cstddef>
#include <assert.h>
#include <cmath>

namespace p2t {

struct Edge;

struct Point {

  double x, y;

  /// Default constructor does nothing (for performance).
  Point()
  {
    x = 0.0;
    y = 0.0;
  }

  /// The edges this point constitutes an upper ending point
  std::vector<Edge*> edge_list;

  /// Construct using coordinates.
  Point(double x, double y) : x(x), y(y) {}

  /// Set this point to all zeros.
  void set_zero()
  {
    x = 0.0;
    y = 0.0;
  }

  /// Set this point to some specified coordinates.
  void set(double x_, double y_)
  {
    x = x_;
    y = y_;
  }

  /// Negate this point.
  Point operator -() const
  {
    Point v;
    v.set(-x, -y);
    return v;
  }

  /// Add a point to this point.
  void operator +=(const Point& v)
  {
    x += v.x;
    y += v.y;
  }

  /// Subtract a point from this point.
  void operator -=(const Point& v)
  {
    x -= v.x;
    y -= v.y;
  }

  /// Multiply this point by a scalar.
  void operator *=(double a)
  {
    x *= a;
    y *= a;
  }

  /// Get the length of this point (the norm).
  double Length() const
  {
    return sqrt(x * x + y * y);
  }

  /// Convert this point into a unit point. Returns the Length.
  double Normalize()
  {
    double len = Length();
    x /= len;
    y /= len;
    return len;
  }

};

// Represents a simple polygon's edge
struct Edge {

  Point* p, *q;

  /// Constructor
  Edge(Point& p1, Point& p2) : p(&p1), q(&p2)
  {
    if (p1.y > p2.y) {
      q = &p1;
      p = &p2;
    } else if (p1.y == p2.y) {
      if (p1.x > p2.x) {
        q = &p1;
        p = &p2;
      } else if (p1.x == p2.x) {
        // Repeat points
        assert(false);
      }
    }

    q->edge_list.push_back(this);
  }
};

// Triangle-based data structures are know to have better performance than quad-edge structures
// See: J. Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator and Delaunay Triangulator"
//      "Triangulations in CGAL"
class Triangle {
public:

/// Constructor
Triangle(Point& a, Point& b, Point& c);

/// Flags to determine if an edge is a Constrained edge
bool constrained_edge[3];
/// Flags to determine if an edge is a Delauney edge
bool delaunay_edge[3];

Point* GetPoint(const int& index);
Point* PointCW(Point& point);
Point* PointCCW(Point& point);
Point* OppositePoint(Triangle& t, Point& p);

Triangle* GetNeighbor(const int& index);
void MarkNeighbor(Point* p1, Point* p2, Triangle* t);
void MarkNeighbor(Triangle& t);

void MarkConstrainedEdge(const int index);
void MarkConstrainedEdge(Edge& edge);
void MarkConstrainedEdge(Point* p, Point* q);

int Index(const Point* p);
int EdgeIndex(const Point* p1, const Point* p2);

Triangle* NeighborCW(Point& point);
Triangle* NeighborCCW(Point& point);
bool GetConstrainedEdgeCCW(Point& p);
bool GetConstrainedEdgeCW(Point& p);
void SetConstrainedEdgeCCW(Point& p, bool ce);
void SetConstrainedEdgeCW(Point& p, bool ce);
bool GetDelunayEdgeCCW(Point& p);
bool GetDelunayEdgeCW(Point& p);
void SetDelunayEdgeCCW(Point& p, bool e);
void SetDelunayEdgeCW(Point& p, bool e);

bool Contains(Point* p);
bool Contains(const Edge& e);
bool Contains(Point* p, Point* q);
void Legalize(Point& point);
void Legalize(Point& opoint, Point& npoint);
/**
 * Clears all references to all other triangles and points
 */
void Clear();
void ClearNeighbor(Triangle *triangle );
void ClearNeighbors();
void ClearDelunayEdges();

inline bool IsInterior();
inline void IsInterior(bool b);

Triangle& NeighborAcross(Point& opoint);

void DebugPrint();

private:

/// Triangle points
Point* points_[3];
/// Neighbor list
Triangle* neighbors_[3];

/// Has this triangle been marked as an interior triangle?
bool interior_;
};

inline bool cmp(const Point* a, const Point* b)
{
  if (a->y < b->y) {
    return true;
  } else if (a->y == b->y) {
    // Make sure q is point with greater x value
    if (a->x < b->x) {
      return true;
    }
  }
  return false;
}

/// Add two points_ component-wise.
inline Point operator +(const Point& a, const Point& b)
{
  return Point(a.x + b.x, a.y + b.y);
}

/// Subtract two points_ component-wise.
inline Point operator -(const Point& a, const Point& b)
{
  return Point(a.x - b.x, a.y - b.y);
}

/// Multiply point by scalar
inline Point operator *(double s, const Point& a)
{
  return Point(s * a.x, s * a.y);
}

inline bool operator ==(const Point& a, const Point& b)
{
  return a.x == b.x && a.y == b.y;
}

inline bool operator !=(const Point& a, const Point& b)
{
  return !(a.x == b.x) || !(a.y == b.y);
}

/// Peform the dot product on two vectors.
inline double Dot(const Point& a, const Point& b)
{
  return a.x * b.x + a.y * b.y;
}

/// Perform the cross product on two vectors. In 2D this produces a scalar.
inline double Cross(const Point& a, const Point& b)
{
  return a.x * b.y - a.y * b.x;
}

/// Perform the cross product on a point and a scalar. In 2D this produces
/// a point.
inline Point Cross(const Point& a, double s)
{
  return Point(s * a.y, -s * a.x);
}

/// Perform the cross product on a scalar and a point. In 2D this produces
/// a point.
inline Point Cross(const double s, const Point& a)
{
  return Point(-s * a.y, s * a.x);
}

inline Point* Triangle::GetPoint(const int& index)
{
  return points_[index];
}

inline Triangle* Triangle::GetNeighbor(const int& index)
{
  return neighbors_[index];
}

inline bool Triangle::Contains(Point* p)
{
  return p == points_[0] || p == points_[1] || p == points_[2];
}

inline bool Triangle::Contains(const Edge& e)
{
  return Contains(e.p) && Contains(e.q);
}

inline bool Triangle::Contains(Point* p, Point* q)
{
  return Contains(p) && Contains(q);
}

inline bool Triangle::IsInterior()
{
  return interior_;
}

inline void Triangle::IsInterior(bool b)
{
  interior_ = b;
}

}

#endif




================================================
FILE: poly2tri/common/utils.h
================================================
/* 
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
#ifndef UTILS_H
#define UTILS_H

// Otherwise #defines like M_PI are undeclared under Visual Studio
#define _USE_MATH_DEFINES

#include <exception>
#include <math.h>

namespace p2t {

const double PI_3div4 = 3 * M_PI / 4;
const double PI_div2 = 1.57079632679489661923;
const double EPSILON = 1e-12;

enum Orientation { CW, CCW, COLLINEAR };

/**
 * Forumla to calculate signed area<br>
 * Positive if CCW<br>
 * Negative if CW<br>
 * 0 if collinear<br>
 * <pre>
 * A[P1,P2,P3]  =  (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
 *              =  (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
 * </pre>
 */
Orientation Orient2d(Point& pa, Point& pb, Point& pc)
{
  double detleft = (pa.x - pc.x) * (pb.y - pc.y);
  double detright = (pa.y - pc.y) * (pb.x - pc.x);
  double val = detleft - detright;
  if (val > -EPSILON && val < EPSILON) {
    return COLLINEAR;
  } else if (val > 0) {
    return CCW;
  }
  return CW;
}

/*
bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
{
  double pdx = pd.x;
  double pdy = pd.y;
  double adx = pa.x - pdx;
  double ady = pa.y - pdy;
  double bdx = pb.x - pdx;
  double bdy = pb.y - pdy;

  double adxbdy = adx * bdy;
  double bdxady = bdx * ady;
  double oabd = adxbdy - bdxady;

  if (oabd <= EPSILON) {
    return false;
  }

  double cdx = pc.x - pdx;
  double cdy = pc.y - pdy;

  double cdxady = cdx * ady;
  double adxcdy = adx * cdy;
  double ocad = cdxady - adxcdy;

  if (ocad <= EPSILON) {
    return false;
  }

  return true;
}

*/

bool InScanArea(Point& pa, Point& pb, Point& pc, Point& pd)
{
  double oadb = (pa.x - pb.x)*(pd.y - pb.y) - (pd.x - pb.x)*(pa.y - pb.y);
  if (oadb >= -EPSILON) {
    return false;
  }

  double oadc = (pa.x - pc.x)*(pd.y - pc.y) - (pd.x - pc.x)*(pa.y - pc.y);
  if (oadc <= EPSILON) {
    return false;
  }
  return true;
}

}

#endif



================================================
FILE: poly2tri/poly2tri.h
================================================
/* 
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef POLY2TRI_H
#define POLY2TRI_H

#include "common/shapes.h"
#include "sweep/cdt.h"

#endif



================================================
FILE: poly2tri/sweep/advancing_front.cc
================================================
/*
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "advancing_front.h"

namespace p2t {

AdvancingFront::AdvancingFront(Node& head, Node& tail)
{
  head_ = &head;
  tail_ = &tail;
  search_node_ = &head;
}

Node* AdvancingFront::LocateNode(const double& x)
{
  Node* node = search_node_;

  if (x < node->value) {
    while ((node = node->prev) != NULL) {
      if (x >= node->value) {
        search_node_ = node;
        return node;
      }
    }
  } else {
    while ((node = node->next) != NULL) {
      if (x < node->value) {
        search_node_ = node->prev;
        return node->prev;
      }
    }
  }
  return NULL;
}

Node* AdvancingFront::FindSearchNode(const double& x)
{
  (void)x; // suppress compiler warnings "unused parameter 'x'"
  // TODO: implement BST index
  return search_node_;
}

Node* AdvancingFront::LocatePoint(const Point* point)
{
  const double px = point->x;
  Node* node = FindSearchNode(px);
  const double nx = node->point->x;

  if (px == nx) {
    if (point != node->point) {
      // We might have two nodes with same x value for a short time
      if (point == node->prev->point) {
        node = node->prev;
      } else if (point == node->next->point) {
        node = node->next;
      } else {
        assert(0);
      }
    }
  } else if (px < nx) {
    while ((node = node->prev) != NULL) {
      if (point == node->point) {
        break;
      }
    }
  } else {
    while ((node = node->next) != NULL) {
      if (point == node->point)
        break;
    }
  }
  if(node) search_node_ = node;
  return node;
}

AdvancingFront::~AdvancingFront()
{
}

}



================================================
FILE: poly2tri/sweep/advancing_front.h
================================================
/*
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef ADVANCED_FRONT_H
#define ADVANCED_FRONT_H

#include "../common/shapes.h"

namespace p2t {

struct Node;

// Advancing front node
struct Node {
  Point* point;
  Triangle* triangle;

  Node* next;
  Node* prev;

  double value;

  Node(Point& p) : point(&p), triangle(NULL), next(NULL), prev(NULL), value(p.x)
  {
  }

  Node(Point& p, Triangle& t) : point(&p), triangle(&t), next(NULL), prev(NULL), value(p.x)
  {
  }

};

// Advancing front
class AdvancingFront {
public:

AdvancingFront(Node& head, Node& tail);
// Destructor
~AdvancingFront();

Node* head();
void set_head(Node* node);
Node* tail();
void set_tail(Node* node);
Node* search();
void set_search(Node* node);

/// Locate insertion point along advancing front
Node* LocateNode(const double& x);

Node* LocatePoint(const Point* point);

private:

Node* head_, *tail_, *search_node_;

Node* FindSearchNode(const double& x);
};

inline Node* AdvancingFront::head()
{
  return head_;
}
inline void AdvancingFront::set_head(Node* node)
{
  head_ = node;
}

inline Node* AdvancingFront::tail()
{
  return tail_;
}
inline void AdvancingFront::set_tail(Node* node)
{
  tail_ = node;
}

inline Node* AdvancingFront::search()
{
  return search_node_;
}

inline void AdvancingFront::set_search(Node* node)
{
  search_node_ = node;
}

}

#endif


================================================
FILE: poly2tri/sweep/cdt.cc
================================================
/* 
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "cdt.h"

namespace p2t {

CDT::CDT(std::vector<Point*> polyline)
{
  sweep_context_ = new SweepContext(polyline);
  sweep_ = new Sweep;
}

void CDT::AddHole(std::vector<Point*> polyline)
{
  sweep_context_->AddHole(polyline);
}

void CDT::AddPoint(Point* point) {
  sweep_context_->AddPoint(point);
}

void CDT::Triangulate()
{
  sweep_->Triangulate(*sweep_context_);
}

std::vector<p2t::Triangle*> CDT::GetTriangles()
{
  return sweep_context_->GetTriangles();
}

std::list<p2t::Triangle*> CDT::GetMap()
{
  return sweep_context_->GetMap();
}

CDT::~CDT()
{
  delete sweep_context_;
  delete sweep_;
}

}



================================================
FILE: poly2tri/sweep/cdt.h
================================================
/* 
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
#ifndef CDT_H
#define CDT_H

#include "advancing_front.h"
#include "sweep_context.h"
#include "sweep.h"

/**
 * 
 * @author Mason Green <mason.green@gmail.com>
 *
 */
 
namespace p2t {

class CDT
{
public:

  /**
   * Constructor - add polyline with non repeating points
   * 
   * @param polyline
   */
  CDT(std::vector<Point*> polyline);
  
   /**
   * Destructor - clean up memory
   */
  ~CDT();
  
  /**
   * Add a hole
   * 
   * @param polyline
   */
  void AddHole(std::vector<Point*> polyline);
  
  /**
   * Add a steiner point
   * 
   * @param point
   */
  void AddPoint(Point* point);
  
  /**
   * Triangulate - do this AFTER you've added the polyline, holes, and Steiner points
   */
  void Triangulate();
  
  /**
   * Get CDT triangles
   */
  std::vector<Triangle*> GetTriangles();
  
  /**
   * Get triangle map
   */
  std::list<Triangle*> GetMap();

  private:

  /**
   * Internals
   */
   
  SweepContext* sweep_context_;
  Sweep* sweep_;

};

}

#endif


================================================
FILE: poly2tri/sweep/sweep.cc
================================================
/*
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <stdexcept>
#include "sweep.h"
#include "sweep_context.h"
#include "advancing_front.h"
#include "../common/utils.h"

namespace p2t {

// Triangulate simple polygon with holes
void Sweep::Triangulate(SweepContext& tcx)
{
  tcx.InitTriangulation();
  tcx.CreateAdvancingFront(nodes_);
  // Sweep points; build mesh
  SweepPoints(tcx);
  // Clean up
  FinalizationPolygon(tcx);
}

void Sweep::SweepPoints(SweepContext& tcx)
{
  for (int i = 1; i < tcx.point_count(); i++) {
    Point& point = *tcx.GetPoint(i);
    Node* node = &PointEvent(tcx, point);
    for (unsigned int i = 0; i < point.edge_list.size(); i++) {
      EdgeEvent(tcx, point.edge_list[i], node);
    }
  }
}

void Sweep::FinalizationPolygon(SweepContext& tcx)
{
  // Get an Internal triangle to start with
  Triangle* t = tcx.front()->head()->next->triangle;
  Point* p = tcx.front()->head()->next->point;
  while (!t->GetConstrainedEdgeCW(*p)) {
    t = t->NeighborCCW(*p);
  }

  // Collect interior triangles constrained by edges
  tcx.MeshClean(*t);
}

Node& Sweep::PointEvent(SweepContext& tcx, Point& point)
{
  Node& node = tcx.LocateNode(point);
  Node& new_node = NewFrontTriangle(tcx, point, node);

  // Only need to check +epsilon since point never have smaller
  // x value than node due to how we fetch nodes from the front
  if (point.x <= node.point->x + EPSILON) {
    Fill(tcx, node);
  }

  //tcx.AddNode(new_node);

  FillAdvancingFront(tcx, new_node);
  return new_node;
}

void Sweep::EdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
{
  tcx.edge_event.constrained_edge = edge;
  tcx.edge_event.right = (edge->p->x > edge->q->x);

  if (IsEdgeSideOfTriangle(*node->triangle, *edge->p, *edge->q)) {
    return;
  }

  // For now we will do all needed filling
  // TODO: integrate with flip process might give some better performance
  //       but for now this avoid the issue with cases that needs both flips and fills
  FillEdgeEvent(tcx, edge, node);
  EdgeEvent(tcx, *edge->p, *edge->q, node->triangle, *edge->q);
}

void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point)
{
  if (IsEdgeSideOfTriangle(*triangle, ep, eq)) {
    return;
  }

  Point* p1 = triangle->PointCCW(point);
  Orientation o1 = Orient2d(eq, *p1, ep);
  if (o1 == COLLINEAR) {
    if( triangle->Contains(&eq, p1)) {
      triangle->MarkConstrainedEdge(&eq, p1 );
      // We are modifying the constraint maybe it would be better to 
      // not change the given constraint and just keep a variable for the new constraint
      tcx.edge_event.constrained_edge->q = p1;
      triangle = &triangle->NeighborAcross(point);
      EdgeEvent( tcx, ep, *p1, triangle, *p1 );
    } else {
      std::runtime_error("EdgeEvent - collinear points not supported");
      assert(0);
    }
    return;
  }

  Point* p2 = triangle->PointCW(point);
  Orientation o2 = Orient2d(eq, *p2, ep);
  if (o2 == COLLINEAR) {
    if( triangle->Contains(&eq, p2)) {
      triangle->MarkConstrainedEdge(&eq, p2 );
      // We are modifying the constraint maybe it would be better to 
      // not change the given constraint and just keep a variable for the new constraint
      tcx.edge_event.constrained_edge->q = p2;
      triangle = &triangle->NeighborAcross(point);
      EdgeEvent( tcx, ep, *p2, triangle, *p2 );
    } else {
      std::runtime_error("EdgeEvent - collinear points not supported");
      assert(0);
    }
    return;
  }

  if (o1 == o2) {
    // Need to decide if we are rotating CW or CCW to get to a triangle
    // that will cross edge
    if (o1 == CW) {
      triangle = triangle->NeighborCCW(point);
    }       else{
      triangle = triangle->NeighborCW(point);
    }
    EdgeEvent(tcx, ep, eq, triangle, point);
  } else {
    // This triangle crosses constraint so lets flippin start!
    FlipEdgeEvent(tcx, ep, eq, triangle, point);
  }
}

bool Sweep::IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq)
{
  int index = triangle.EdgeIndex(&ep, &eq);

  if (index != -1) {
    triangle.MarkConstrainedEdge(index);
    Triangle* t = triangle.GetNeighbor(index);
    if (t) {
      t->MarkConstrainedEdge(&ep, &eq);
    }
    return true;
  }
  return false;
}

Node& Sweep::NewFrontTriangle(SweepContext& tcx, Point& point, Node& node)
{
  Triangle* triangle = new Triangle(point, *node.point, *node.next->point);

  triangle->MarkNeighbor(*node.triangle);
  tcx.AddToMap(triangle);

  Node* new_node = new Node(point);
  nodes_.push_back(new_node);

  new_node->next = node.next;
  new_node->prev = &node;
  node.next->prev = new_node;
  node.next = new_node;

  if (!Legalize(tcx, *triangle)) {
    tcx.MapTriangleToNodes(*triangle);
  }

  return *new_node;
}

void Sweep::Fill(SweepContext& tcx, Node& node)
{
  Triangle* triangle = new Triangle(*node.prev->point, *node.point, *node.next->point);

  // TODO: should copy the constrained_edge value from neighbor triangles
  //       for now constrained_edge values are copied during the legalize
  triangle->MarkNeighbor(*node.prev->triangle);
  triangle->MarkNeighbor(*node.triangle);

  tcx.AddToMap(triangle);

  // Update the advancing front
  node.prev->next = node.next;
  node.next->prev = node.prev;

  // If it was legalized the triangle has already been mapped
  if (!Legalize(tcx, *triangle)) {
    tcx.MapTriangleToNodes(*triangle);
  }

}

void Sweep::FillAdvancingFront(SweepContext& tcx, Node& n)
{

  // Fill right holes
  Node* node = n.next;

  while (node->next) {
    // if HoleAngle exceeds 90 degrees then break.
    if (LargeHole_DontFill(node)) break;
    Fill(tcx, *node);
    node = node->next;
  }

  // Fill left holes
  node = n.prev;

  while (node->prev) {
    // if HoleAngle exceeds 90 degrees then break.
    if (LargeHole_DontFill(node)) break;
    Fill(tcx, *node);
    node = node->prev;
  }

  // Fill right basins
  if (n.next && n.next->next) {
    double angle = BasinAngle(n);
    if (angle < PI_3div4) {
      FillBasin(tcx, n);
    }
  }
}

// True if HoleAngle exceeds 90 degrees.
// LargeHole_DontFill checks if the advancing front has a large hole.
// A "Large hole" is a triangle formed by a sequence of points in the advancing
// front where three neighbor points form a triangle.
// And angle between left-top, bottom, and right-top points is more than 90 degrees.
// The first part of the algorithm reviews only three neighbor points, e.g. named A, B, C.
// Additional part of this logic reviews a sequence of 5 points -
// additionally reviews one point before and one after the sequence of three (A, B, C),
// e.g. named X and Y.
// In this case, angles are XBC and ABY and this if angles are negative or more
// than 90 degrees LargeHole_DontFill returns true.
// But there is a configuration when ABC has a negative angle but XBC or ABY is less
// than 90 degrees and positive.
// Then function LargeHole_DontFill return false and initiates filling.
// This filling creates a triangle ABC and adds it to the advancing front.
// But in the case when angle ABC is negative this triangle goes inside the advancing front
// and can intersect previously created triangles.
// This triangle leads to making wrong advancing front and problems in triangulation in the future.
// Looks like such a triangle should not be created.
// The simplest way to check and fix it is to check an angle ABC.
// If it is negative LargeHole_DontFill should return true and
// not initiate creating the ABC triangle in the advancing front.
// X______A         Y
//        \        /
//         \      /
//          \ B  /
//           |  /
//           | /
//           |/
//           C
bool Sweep::LargeHole_DontFill(Node* node) {
  
  Node* nextNode = node->next;
  Node* prevNode = node->prev;
  if (!AngleExceeds90Degrees(node->point, nextNode->point, prevNode->point))
          return false;

  if (AngleIsNegative(node->point, nextNode->point, prevNode->point))
          return true;

  // Check additional points on front.
  Node* next2Node = nextNode->next;
  // "..Plus.." because only want angles on same side as point being added.
  if ((next2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, next2Node->point, prevNode->point))
          return false;

  Node* prev2Node = prevNode->prev;
  // "..Plus.." because only want angles on same side as point being added.
  if ((prev2Node != NULL) && !AngleExceedsPlus90DegreesOrIsNegative(node->point, nextNode->point, prev2Node->point))
          return false;

  return true;
}

bool Sweep::AngleIsNegative(Point* origin, Point* pa, Point* pb) {
    const double angle = Angle(*origin, *pa, *pb);
    return angle < 0;
}

bool Sweep::AngleExceeds90Degrees(Point* origin, Point* pa, Point* pb) {
  double angle = Angle(*origin, *pa, *pb);
  bool exceeds90Degrees = ((angle > PI_div2) || (angle < -PI_div2));
  return exceeds90Degrees;
}

bool Sweep::AngleExceedsPlus90DegreesOrIsNegative(Point* origin, Point* pa, Point* pb) {
  double angle = Angle(*origin, *pa, *pb);
  bool exceedsPlus90DegreesOrIsNegative = (angle > PI_div2) || (angle < 0);
  return exceedsPlus90DegreesOrIsNegative;
}

double Sweep::Angle(Point& origin, Point& pa, Point& pb) {
  /* Complex plane
   * ab = cosA +i*sinA
   * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
   * atan2(y,x) computes the principal value of the argument function
   * applied to the complex number x+iy
   * Where x = ax*bx + ay*by
   *       y = ax*by - ay*bx
   */
  double px = origin.x;
  double py = origin.y;
  double ax = pa.x- px;
  double ay = pa.y - py;
  double bx = pb.x - px;
  double by = pb.y - py;
  double x = ax * by - ay * bx;
  double y = ax * bx + ay * by;
  double angle = atan2(x, y);
  return angle;
}

double Sweep::BasinAngle(Node& node)
{
  double ax = node.point->x - node.next->next->point->x;
  double ay = node.point->y - node.next->next->point->y;
  return atan2(ay, ax);
}

double Sweep::HoleAngle(Node& node)
{
  /* Complex plane
   * ab = cosA +i*sinA
   * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
   * atan2(y,x) computes the principal value of the argument function
   * applied to the complex number x+iy
   * Where x = ax*bx + ay*by
   *       y = ax*by - ay*bx
   */
  double ax = node.next->point->x - node.point->x;
  double ay = node.next->point->y - node.point->y;
  double bx = node.prev->point->x - node.point->x;
  double by = node.prev->point->y - node.point->y;
  return atan2(ax * by - ay * bx, ax * bx + ay * by);
}

bool Sweep::Legalize(SweepContext& tcx, Triangle& t)
{
  // To legalize a triangle we start by finding if any of the three edges
  // violate the Delaunay condition
  for (int i = 0; i < 3; i++) {
    if (t.delaunay_edge[i])
      continue;

    Triangle* ot = t.GetNeighbor(i);

    if (ot) {
      Point* p = t.GetPoint(i);
      Point* op = ot->OppositePoint(t, *p);
      int oi = ot->Index(op);

      // If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)
      // then we should not try to legalize
      if (ot->constrained_edge[oi] || ot->delaunay_edge[oi]) {
        t.constrained_edge[i] = ot->constrained_edge[oi];
        continue;
      }

      bool inside = Incircle(*p, *t.PointCCW(*p), *t.PointCW(*p), *op);

      if (inside) {
        // Lets mark this shared edge as Delaunay
        t.delaunay_edge[i] = true;
        ot->delaunay_edge[oi] = true;

        // Lets rotate shared edge one vertex CW to legalize it
        RotateTrianglePair(t, *p, *ot, *op);

        // We now got one valid Delaunay Edge shared by two triangles
        // This gives us 4 new edges to check for Delaunay

        // Make sure that triangle to node mapping is done only one time for a specific triangle
        bool not_legalized = !Legalize(tcx, t);
        if (not_legalized) {
          tcx.MapTriangleToNodes(t);
        }

        not_legalized = !Legalize(tcx, *ot);
        if (not_legalized)
          tcx.MapTriangleToNodes(*ot);

        // Reset the Delaunay edges, since they only are valid Delaunay edges
        // until we add a new triangle or point.
        // XXX: need to think about this. Can these edges be tried after we
        //      return to previous recursive level?
        t.delaunay_edge[i] = false;
        ot->delaunay_edge[oi] = false;

        // If triangle have been legalized no need to check the other edges since
        // the recursive legalization will handles those so we can end here.
        return true;
      }
    }
  }
  return false;
}

bool Sweep::Incircle(Point& pa, Point& pb, Point& pc, Point& pd)
{
  double adx = pa.x - pd.x;
  double ady = pa.y - pd.y;
  double bdx = pb.x - pd.x;
  double bdy = pb.y - pd.y;

  double adxbdy = adx * bdy;
  double bdxady = bdx * ady;
  double oabd = adxbdy - bdxady;

  if (oabd <= 0)
    return false;

  double cdx = pc.x - pd.x;
  double cdy = pc.y - pd.y;

  double cdxady = cdx * ady;
  double adxcdy = adx * cdy;
  double ocad = cdxady - adxcdy;

  if (ocad <= 0)
    return false;

  double bdxcdy = bdx * cdy;
  double cdxbdy = cdx * bdy;

  double alift = adx * adx + ady * ady;
  double blift = bdx * bdx + bdy * bdy;
  double clift = cdx * cdx + cdy * cdy;

  double det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;

  return det > 0;
}

void Sweep::RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op)
{
  Triangle* n1, *n2, *n3, *n4;
  n1 = t.NeighborCCW(p);
  n2 = t.NeighborCW(p);
  n3 = ot.NeighborCCW(op);
  n4 = ot.NeighborCW(op);

  bool ce1, ce2, ce3, ce4;
  ce1 = t.GetConstrainedEdgeCCW(p);
  ce2 = t.GetConstrainedEdgeCW(p);
  ce3 = ot.GetConstrainedEdgeCCW(op);
  ce4 = ot.GetConstrainedEdgeCW(op);

  bool de1, de2, de3, de4;
  de1 = t.GetDelunayEdgeCCW(p);
  de2 = t.GetDelunayEdgeCW(p);
  de3 = ot.GetDelunayEdgeCCW(op);
  de4 = ot.GetDelunayEdgeCW(op);

  t.Legalize(p, op);
  ot.Legalize(op, p);

  // Remap delaunay_edge
  ot.SetDelunayEdgeCCW(p, de1);
  t.SetDelunayEdgeCW(p, de2);
  t.SetDelunayEdgeCCW(op, de3);
  ot.SetDelunayEdgeCW(op, de4);

  // Remap constrained_edge
  ot.SetConstrainedEdgeCCW(p, ce1);
  t.SetConstrainedEdgeCW(p, ce2);
  t.SetConstrainedEdgeCCW(op, ce3);
  ot.SetConstrainedEdgeCW(op, ce4);

  // Remap neighbors
  // XXX: might optimize the markNeighbor by keeping track of
  //      what side should be assigned to what neighbor after the
  //      rotation. Now mark neighbor does lots of testing to find
  //      the right side.
  t.ClearNeighbors();
  ot.ClearNeighbors();
  if (n1) ot.MarkNeighbor(*n1);
  if (n2) t.MarkNeighbor(*n2);
  if (n3) t.MarkNeighbor(*n3);
  if (n4) ot.MarkNeighbor(*n4);
  t.MarkNeighbor(ot);
}

void Sweep::FillBasin(SweepContext& tcx, Node& node)
{
  if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {
    tcx.basin.left_node = node.next->next;
  } else {
    tcx.basin.left_node = node.next;
  }

  // Find the bottom and right node
  tcx.basin.bottom_node = tcx.basin.left_node;
  while (tcx.basin.bottom_node->next
         && tcx.basin.bottom_node->point->y >= tcx.basin.bottom_node->next->point->y) {
    tcx.basin.bottom_node = tcx.basin.bottom_node->next;
  }
  if (tcx.basin.bottom_node == tcx.basin.left_node) {
    // No valid basin
    return;
  }

  tcx.basin.right_node = tcx.basin.bottom_node;
  while (tcx.basin.right_node->next
         && tcx.basin.right_node->point->y < tcx.basin.right_node->next->point->y) {
    tcx.basin.right_node = tcx.basin.right_node->next;
  }
  if (tcx.basin.right_node == tcx.basin.bottom_node) {
    // No valid basins
    return;
  }

  tcx.basin.width = tcx.basin.right_node->point->x - tcx.basin.left_node->point->x;
  tcx.basin.left_highest = tcx.basin.left_node->point->y > tcx.basin.right_node->point->y;

  FillBasinReq(tcx, tcx.basin.bottom_node);
}

void Sweep::FillBasinReq(SweepContext& tcx, Node* node)
{
  // if shallow stop filling
  if (IsShallow(tcx, *node)) {
    return;
  }

  Fill(tcx, *node);

  if (node->prev == tcx.basin.left_node && node->next == tcx.basin.right_node) {
    return;
  } else if (node->prev == tcx.basin.left_node) {
    Orientation o = Orient2d(*node->point, *node->next->point, *node->next->next->point);
    if (o == CW) {
      return;
    }
    node = node->next;
  } else if (node->next == tcx.basin.right_node) {
    Orientation o = Orient2d(*node->point, *node->prev->point, *node->prev->prev->point);
    if (o == CCW) {
      return;
    }
    node = node->prev;
  } else {
    // Continue with the neighbor node with lowest Y value
    if (node->prev->point->y < node->next->point->y) {
      node = node->prev;
    } else {
      node = node->next;
    }
  }

  FillBasinReq(tcx, node);
}

bool Sweep::IsShallow(SweepContext& tcx, Node& node)
{
  double height;

  if (tcx.basin.left_highest) {
    height = tcx.basin.left_node->point->y - node.point->y;
  } else {
    height = tcx.basin.right_node->point->y - node.point->y;
  }

  // if shallow stop filling
  if (tcx.basin.width > height) {
    return true;
  }
  return false;
}

void Sweep::FillEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
{
  if (tcx.edge_event.right) {
    FillRightAboveEdgeEvent(tcx, edge, node);
  } else {
    FillLeftAboveEdgeEvent(tcx, edge, node);
  }
}

void Sweep::FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
{
  while (node->next->point->x < edge->p->x) {
    // Check if next node is below the edge
    if (Orient2d(*edge->q, *node->next->point, *edge->p) == CCW) {
      FillRightBelowEdgeEvent(tcx, edge, *node);
    } else {
      node = node->next;
    }
  }
}

void Sweep::FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
{
  if (node.point->x < edge->p->x) {
    if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {
      // Concave
      FillRightConcaveEdgeEvent(tcx, edge, node);
    } else{
      // Convex
      FillRightConvexEdgeEvent(tcx, edge, node);
      // Retry this one
      FillRightBelowEdgeEvent(tcx, edge, node);
    }
  }
}

void Sweep::FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
{
  Fill(tcx, *node.next);
  if (node.next->point != edge->p) {
    // Next above or below edge?
    if (Orient2d(*edge->q, *node.next->point, *edge->p) == CCW) {
      // Below
      if (Orient2d(*node.point, *node.next->point, *node.next->next->point) == CCW) {
        // Next is concave
        FillRightConcaveEdgeEvent(tcx, edge, node);
      } else {
        // Next is convex
      }
    }
  }

}

void Sweep::FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
{
  // Next concave or convex?
  if (Orient2d(*node.next->point, *node.next->next->point, *node.next->next->next->point) == CCW) {
    // Concave
    FillRightConcaveEdgeEvent(tcx, edge, *node.next);
  } else{
    // Convex
    // Next above or below edge?
    if (Orient2d(*edge->q, *node.next->next->point, *edge->p) == CCW) {
      // Below
      FillRightConvexEdgeEvent(tcx, edge, *node.next);
    } else{
      // Above
    }
  }
}

void Sweep::FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node)
{
  while (node->prev->point->x > edge->p->x) {
    // Check if next node is below the edge
    if (Orient2d(*edge->q, *node->prev->point, *edge->p) == CW) {
      FillLeftBelowEdgeEvent(tcx, edge, *node);
    } else {
      node = node->prev;
    }
  }
}

void Sweep::FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
{
  if (node.point->x > edge->p->x) {
    if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) {
      // Concave
      FillLeftConcaveEdgeEvent(tcx, edge, node);
    } else {
      // Convex
      FillLeftConvexEdgeEvent(tcx, edge, node);
      // Retry this one
      FillLeftBelowEdgeEvent(tcx, edge, node);
    }
  }
}

void Sweep::FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
{
  // Next concave or convex?
  if (Orient2d(*node.prev->point, *node.prev->prev->point, *node.prev->prev->prev->point) == CW) {
    // Concave
    FillLeftConcaveEdgeEvent(tcx, edge, *node.prev);
  } else{
    // Convex
    // Next above or below edge?
    if (Orient2d(*edge->q, *node.prev->prev->point, *edge->p) == CW) {
      // Below
      FillLeftConvexEdgeEvent(tcx, edge, *node.prev);
    } else{
      // Above
    }
  }
}

void Sweep::FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node)
{
  Fill(tcx, *node.prev);
  if (node.prev->point != edge->p) {
    // Next above or below edge?
    if (Orient2d(*edge->q, *node.prev->point, *edge->p) == CW) {
      // Below
      if (Orient2d(*node.point, *node.prev->point, *node.prev->prev->point) == CW) {
        // Next is concave
        FillLeftConcaveEdgeEvent(tcx, edge, node);
      } else{
        // Next is convex
      }
    }
  }

}

void Sweep::FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p)
{
  Triangle& ot = t->NeighborAcross(p);
  Point& op = *ot.OppositePoint(*t, p);

  if (&ot == NULL) {
    // If we want to integrate the fillEdgeEvent do it here
    // With current implementation we should never get here
    //throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");
    assert(0);
  }

  if (InScanArea(p, *t->PointCCW(p), *t->PointCW(p), op)) {
    // Lets rotate shared edge one vertex CW
    RotateTrianglePair(*t, p, ot, op);
    tcx.MapTriangleToNodes(*t);
    tcx.MapTriangleToNodes(ot);

    if (p == eq && op == ep) {
      if (eq == *tcx.edge_event.constrained_edge->q && ep == *tcx.edge_event.constrained_edge->p) {
        t->MarkConstrainedEdge(&ep, &eq);
        ot.MarkConstrainedEdge(&ep, &eq);
        Legalize(tcx, *t);
        Legalize(tcx, ot);
      } else {
        // XXX: I think one of the triangles should be legalized here?
      }
    } else {
      Orientation o = Orient2d(eq, op, ep);
      t = &NextFlipTriangle(tcx, (int)o, *t, ot, p, op);
      FlipEdgeEvent(tcx, ep, eq, t, p);
    }
  } else {
    Point& newP = NextFlipPoint(ep, eq, ot, op);
    FlipScanEdgeEvent(tcx, ep, eq, *t, ot, newP);
    EdgeEvent(tcx, ep, eq, t, p);
  }
}

Triangle& Sweep::NextFlipTriangle(SweepContext& tcx, int o, Triangle& t, Triangle& ot, Point& p, Point& op)
{
  if (o == CCW) {
    // ot is not crossing edge after flip
    int edge_index = ot.EdgeIndex(&p, &op);
    ot.delaunay_edge[edge_index] = true;
    Legalize(tcx, ot);
    ot.ClearDelunayEdges();
    return t;
  }

  // t is not crossing edge after flip
  int edge_index = t.EdgeIndex(&p, &op);

  t.delaunay_edge[edge_index] = true;
  Legalize(tcx, t);
  t.ClearDelunayEdges();
  return ot;
}

Point& Sweep::NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op)
{
  Orientation o2d = Orient2d(eq, op, ep);
  if (o2d == CW) {
    // Right
    return *ot.PointCCW(op);
  } else if (o2d == CCW) {
    // Left
    return *ot.PointCW(op);
  } else{
    //throw new RuntimeException("[Unsupported] Opposing point on constrained edge");
    assert(0);
  }
}

void Sweep::FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle,
                              Triangle& t, Point& p)
{
  Triangle& ot = t.NeighborAcross(p);
  Point& op = *ot.OppositePoint(t, p);

  if (&t.NeighborAcross(p) == NULL) {
    // If we want to integrate the fillEdgeEvent do it here
    // With current implementation we should never get here
    //throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");
    assert(0);
  }

  if (InScanArea(eq, *flip_triangle.PointCCW(eq), *flip_triangle.PointCW(eq), op)) {
    // flip with new edge op->eq
    FlipEdgeEvent(tcx, eq, op, &ot, op);
    // TODO: Actually I just figured out that it should be possible to
    //       improve this by getting the next ot and op before the the above
    //       flip and continue the flipScanEdgeEvent here
    // set new ot and op here and loop back to inScanArea test
    // also need to set a new flip_triangle first
    // Turns out at first glance that this is somewhat complicated
    // so it will have to wait.
  } else{
    Point& newP = NextFlipPoint(ep, eq, ot, op);
    FlipScanEdgeEvent(tcx, ep, eq, flip_triangle, ot, newP);
  }
}

Sweep::~Sweep() {

    // Clean up memory
    for(int i = 0; i < nodes_.size(); i++) {
        delete nodes_[i];
    }

}

}



================================================
FILE: poly2tri/sweep/sweep.h
================================================
/*
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/**
 * Sweep-line, Constrained Delauney Triangulation (CDT) See: Domiter, V. and
 * Zalik, B.(2008)'Sweep-line algorithm for constrained Delaunay triangulation',
 * International Journal of Geographical Information Science
 *
 * "FlipScan" Constrained Edge Algorithm invented by Thomas hln, thahlen@gmail.com
 */

#ifndef SWEEP_H
#define SWEEP_H

#include <vector>

namespace p2t {

class SweepContext;
struct Node;
struct Point;
struct Edge;
class Triangle;

class Sweep 
{
public:

  /**
   * Triangulate
   * 
   * @param tcx
   */
  void Triangulate(SweepContext& tcx);
  
  /**
   * Destructor - clean up memory
   */
  ~Sweep();

private:

  /**
   * Start sweeping the Y-sorted point set from bottom to top
   * 
   * @param tcx
   */
  void SweepPoints(SweepContext& tcx);

  /**
   * Find closes node to the left of the new point and
   * create a new triangle. If needed new holes and basins
   * will be filled to.
   *
   * @param tcx
   * @param point
   * @return
   */
  Node& PointEvent(SweepContext& tcx, Point& point);

   /**
     * 
     * 
     * @param tcx
     * @param edge
     * @param node
     */
  void EdgeEvent(SweepContext& tcx, Edge* edge, Node* node);

  void EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangle, Point& point);

  /**
   * Creates a new front triangle and legalize it
   * 
   * @param tcx
   * @param point
   * @param node
   * @return
   */
  Node& NewFrontTriangle(SweepContext& tcx, Point& point, Node& node);

  /**
   * Adds a triangle to the advancing front to fill a hole.
   * @param tcx
   * @param node - middle node, that is the bottom of the hole
   */
  void Fill(SweepContext& tcx, Node& node);

  /**
   * Returns true if triangle was legalized
   */
  bool Legalize(SweepContext& tcx, Triangle& t);

  /**
   * <b>Requirement</b>:<br>
   * 1. a,b and c form a triangle.<br>
   * 2. a and d is know to be on opposite side of bc<br>
   * <pre>
   *                a
   *                +
   *               / \
   *              /   \
   *            b/     \c
   *            +-------+
   *           /    d    \
   *          /           \
   * </pre>
   * <b>Fact</b>: d has to be in area B to have a chance to be inside the circle formed by
   *  a,b and c<br>
   *  d is outside B if orient2d(a,b,d) or orient2d(c,a,d) is CW<br>
   *  This preknowledge gives us a way to optimize the incircle test
   * @param a - triangle point, opposite d
   * @param b - triangle point
   * @param c - triangle point
   * @param d - point opposite a
   * @return true if d is inside circle, false if on circle edge
   */
  bool Incircle(Point& pa, Point& pb, Point& pc, Point& pd);

  /**
   * Rotates a triangle pair one vertex CW
   *<pre>
   *       n2                    n2
   *  P +-----+             P +-----+
   *    | t  /|               |\  t |
   *    |   / |               | \   |
   *  n1|  /  |n3           n1|  \  |n3
   *    | /   |    after CW   |   \ |
   *    |/ oT |               | oT \|
   *    +-----+ oP            +-----+
   *       n4                    n4
   * </pre>
   */
  void RotateTrianglePair(Triangle& t, Point& p, Triangle& ot, Point& op);

  /**
   * Fills holes in the Advancing Front
   *
   *
   * @param tcx
   * @param n
   */
  void FillAdvancingFront(SweepContext& tcx, Node& n);
  
  // Decision-making about when to Fill hole. 
  // Contributed by ToolmakerSteve2
  bool LargeHole_DontFill(Node* node);
  bool AngleIsNegative(Point* origin, Point* pa, Point* pb);
  bool AngleExceeds90Degrees(Point* origin, Point* pa, Point* pb);
  bool AngleExceedsPlus90DegreesOrIsNegative(Point* origin, Point* pa, Point* pb);
  double Angle(Point& origin, Point& pa, Point& pb);

  /**
   *
   * @param node - middle node
   * @return the angle between 3 front nodes
   */
  double HoleAngle(Node& node);

  /**
   * The basin angle is decided against the horizontal line [1,0]
   */
  double BasinAngle(Node& node);

  /**
   * Fills a basin that has formed on the Advancing Front to the right
   * of given node.<br>
   * First we decide a left,bottom and right node that forms the
   * boundaries of the basin. Then we do a reqursive fill.
   *
   * @param tcx
   * @param node - starting node, this or next node will be left node
   */
  void FillBasin(SweepContext& tcx, Node& node);

  /**
   * Recursive algorithm to fill a Basin with triangles
   *
   * @param tcx
   * @param node - bottom_node
   * @param cnt - counter used to alternate on even and odd numbers
   */
  void FillBasinReq(SweepContext& tcx, Node* node);

  bool IsShallow(SweepContext& tcx, Node& node);

  bool IsEdgeSideOfTriangle(Triangle& triangle, Point& ep, Point& eq);

  void FillEdgeEvent(SweepContext& tcx, Edge* edge, Node* node);

  void FillRightAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node);

  void FillRightBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);

  void FillRightConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);

  void FillRightConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);

  void FillLeftAboveEdgeEvent(SweepContext& tcx, Edge* edge, Node* node);

  void FillLeftBelowEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);

  void FillLeftConcaveEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);

  void FillLeftConvexEdgeEvent(SweepContext& tcx, Edge* edge, Node& node);

  void FlipEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* t, Point& p);

  /**
   * After a flip we have two triangles and know that only one will still be
   * intersecting the edge. So decide which to contiune with and legalize the other
   * 
   * @param tcx
   * @param o - should be the result of an orient2d( eq, op, ep )
   * @param t - triangle 1
   * @param ot - triangle 2
   * @param p - a point shared by both triangles 
   * @param op - another point shared by both triangles
   * @return returns the triangle still intersecting the edge
   */
  Triangle& NextFlipTriangle(SweepContext& tcx, int o, Triangle&  t, Triangle& ot, Point& p, Point& op);

   /**
     * When we need to traverse from one triangle to the next we need 
     * the point in current triangle that is the opposite point to the next
     * triangle. 
     * 
     * @param ep
     * @param eq
     * @param ot
     * @param op
     * @return
     */
  Point& NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point& op);

   /**
     * Scan part of the FlipScan algorithm<br>
     * When a triangle pair isn't flippable we will scan for the next 
     * point that is inside the flip triangle scan area. When found 
     * we generate a new flipEdgeEvent
     * 
     * @param tcx
     * @param ep - last point on the edge we are traversing
     * @param eq - first point on the edge we are traversing
     * @param flipTriangle - the current triangle sharing the point eq with edge
     * @param t
     * @param p
     */
  void FlipScanEdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle& flip_triangle, Triangle& t, Point& p);

  void FinalizationPolygon(SweepContext& tcx);

  std::vector<Node*> nodes_;

};

}

#endif


================================================
FILE: poly2tri/sweep/sweep_context.cc
================================================
/*
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "sweep_context.h"
#include <algorithm>
#include "advancing_front.h"

namespace p2t {

SweepContext::SweepContext(std::vector<Point*> polyline) :
  front_(0),
  head_(0),
  tail_(0),
  af_head_(0),
  af_middle_(0),
  af_tail_(0)
{
  basin = Basin();
  edge_event = EdgeEvent();

  points_ = polyline;

  InitEdges(points_);
}

void SweepContext::AddHole(std::vector<Point*> polyline)
{
  InitEdges(polyline);
  for(unsigned int i = 0; i < polyline.size(); i++) {
    points_.push_back(polyline[i]);
  }
}

void SweepContext::AddPoint(Point* point) {
  points_.push_back(point);
}

std::vector<Triangle*> SweepContext::GetTriangles()
{
  return triangles_;
}

std::list<Triangle*> SweepContext::GetMap()
{
  return map_;
}

void SweepContext::InitTriangulation()
{
  double xmax(points_[0]->x), xmin(points_[0]->x);
  double ymax(points_[0]->y), ymin(points_[0]->y);

  // Calculate bounds.
  for (unsigned int i = 0; i < points_.size(); i++) {
    Point& p = *points_[i];
    if (p.x > xmax)
      xmax = p.x;
    if (p.x < xmin)
      xmin = p.x;
    if (p.y > ymax)
      ymax = p.y;
    if (p.y < ymin)
      ymin = p.y;
  }

  double dx = kAlpha * (xmax - xmin);
  double dy = kAlpha * (ymax - ymin);
  head_ = new Point(xmax + dx, ymin - dy);
  tail_ = new Point(xmin - dx, ymin - dy);

  // Sort points along y-axis
  std::sort(points_.begin(), points_.end(), cmp);

}

void SweepContext::InitEdges(std::vector<Point*> polyline)
{
  int num_points = polyline.size();
  for (int i = 0; i < num_points; i++) {
    int j = i < num_points - 1 ? i + 1 : 0;
    edge_list.push_back(new Edge(*polyline[i], *polyline[j]));
  }
}

Point* SweepContext::GetPoint(const int& index)
{
  return points_[index];
}

void SweepContext::AddToMap(Triangle* triangle)
{
  map_.push_back(triangle);
}

Node& SweepContext::LocateNode(Point& point)
{
  // TODO implement search tree
  return *front_->LocateNode(point.x);
}

void SweepContext::CreateAdvancingFront(std::vector<Node*> nodes)
{

  (void) nodes;
  // Initial triangle
  Triangle* triangle = new Triangle(*points_[0], *tail_, *head_);

  map_.push_back(triangle);

  af_head_ = new Node(*triangle->GetPoint(1), *triangle);
  af_middle_ = new Node(*triangle->GetPoint(0), *triangle);
  af_tail_ = new Node(*triangle->GetPoint(2));
  front_ = new AdvancingFront(*af_head_, *af_tail_);

  // TODO: More intuitive if head is middles next and not previous?
  //       so swap head and tail
  af_head_->next = af_middle_;
  af_middle_->next = af_tail_;
  af_middle_->prev = af_head_;
  af_tail_->prev = af_middle_;
}

void SweepContext::RemoveNode(Node* node)
{
  delete node;
}

void SweepContext::MapTriangleToNodes(Triangle& t)
{
  for (int i = 0; i < 3; i++) {
    if (!t.GetNeighbor(i)) {
      Node* n = front_->LocatePoint(t.PointCW(*t.GetPoint(i)));
      if (n)
        n->triangle = &t;
    }
  }
}

void SweepContext::RemoveFromMap(Triangle* triangle)
{
  map_.remove(triangle);
}

void SweepContext::MeshClean(Triangle& triangle)
{
  std::vector<Triangle *> triangles;
  triangles.push_back(&triangle);

  while(!triangles.empty()){
	Triangle *t = triangles.back();
	triangles.pop_back();

    if (t != NULL && !t->IsInterior()) {
      t->IsInterior(true);
      triangles_.push_back(t);
      for (int i = 0; i < 3; i++) {
        if (!t->constrained_edge[i])
          triangles.push_back(t->GetNeighbor(i));
      }
    }
  }
}

SweepContext::~SweepContext()
{

    // Clean up memory

    delete head_;
    delete tail_;
    delete front_;
    delete af_head_;
    delete af_middle_;
    delete af_tail_;

    typedef std::list<Triangle*> type_list;

    for(type_list::iterator iter = map_.begin(); iter != map_.end(); ++iter) {
        Triangle* ptr = *iter;
        delete ptr;
    }

     for(unsigned int i = 0; i < edge_list.size(); i++) {
        delete edge_list[i];
    }

}

}


================================================
FILE: poly2tri/sweep/sweep_context.h
================================================
/*
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SWEEP_CONTEXT_H
#define SWEEP_CONTEXT_H

#include <list>
#include <vector>
#include <cstddef>

namespace p2t {

// Inital triangle factor, seed triangle will extend 30% of
// PointSet width to both left and right.
const double kAlpha = 0.3;

struct Point;
class Triangle;
struct Node;
struct Edge;
class AdvancingFront;

class SweepContext {
public:

/// Constructor
SweepContext(std::vector<Point*> polyline);
/// Destructor
~SweepContext();

void set_head(Point* p1);

Point* head();

void set_tail(Point* p1);

Point* tail();

int point_count();

Node& LocateNode(Point& point);

void RemoveNode(Node* node);

void CreateAdvancingFront(std::vector<Node*> nodes);

/// Try to map a node to all sides of this triangle that don't have a neighbor
void MapTriangleToNodes(Triangle& t);

void AddToMap(Triangle* triangle);

Point* GetPoint(const int& index);

Point* GetPoints();

void RemoveFromMap(Triangle* triangle);

void AddHole(std::vector<Point*> polyline);

void AddPoint(Point* point);

AdvancingFront* front();

void MeshClean(Triangle& triangle);

std::vector<Triangle*> GetTriangles();
std::list<Triangle*> GetMap();

std::vector<Edge*> edge_list;

struct Basin {
  Node* left_node;
  Node* bottom_node;
  Node* right_node;
  double width;
  bool left_highest;

  Basin() : left_node(NULL), bottom_node(NULL), right_node(NULL), width(0.0), left_highest(false)
  {
  }

  void Clear()
  {
    left_node = NULL;
    bottom_node = NULL;
    right_node = NULL;
    width = 0.0;
    left_highest = false;
  }
};

struct EdgeEvent {
  Edge* constrained_edge;
  bool right;

  EdgeEvent() : constrained_edge(NULL), right(false)
  {
  }
};

Basin basin;
EdgeEvent edge_event;

private:

friend class Sweep;

std::vector<Triangle*> triangles_;
std::list<Triangle*> map_;
std::vector<Point*> points_;

// Advancing front
AdvancingFront* front_;
// head point used with advancing front
Point* head_;
// tail point used with advancing front
Point* tail_;

Node *af_head_, *af_middle_, *af_tail_;

void InitTriangulation();
void InitEdges(std::vector<Point*> polyline);

};

inline AdvancingFront* SweepContext::front()
{
  return front_;
}

inline int SweepContext::point_count()
{
  return points_.size();
}

inline void SweepContext::set_head(Point* p1)
{
  head_ = p1;
}

inline Point* SweepContext::head()
{
  return head_;
}

inline void SweepContext::set_tail(Point* p1)
{
  tail_ = p1;
}

inline Point* SweepContext::tail()
{
  return tail_;
}

}

#endif


================================================
FILE: testbed/data/polygon.dae
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
    <asset>
        <contributor>
            <authoring_tool>Google SketchUp 7.1.4871</authoring_tool>
        </contributor>
        <created>2009-12-21T01:51:00Z</created>
        <modified>2009-12-21T01:51:00Z</modified>
        <unit meter="0.0254" name="inch" />
        <up_axis>Z_UP</up_axis>
    </asset>
    <library_visual_scenes>
        <visual_scene id="ID1">
            <node name="SketchUp">
                <instance_geometry url="#ID2">
                    <bind_material>
                        <technique_common>
                            <instance_material symbol="Material2" target="#ID4">
                                <bind_vertex_input semantic="UVSET0" input_semantic="TEXCOORD" input_set="0" />
                            </instance_material>
                        </technique_common>
                    </bind_material>
                </instance_geometry>
            </node>
        </visual_scene>
    </library_visual_scenes>
    <library_geometries>
        <geometry id="ID2">
            <mesh>
                <source id="ID5">
                    <float_array id="ID8" count="324">-112.9393 -5.134218 -5.952325e-030 -115.783 -26.39329 -4.065249e-030 -116.1693 -15.52189 -5.174618e-030 -111.8239 -36.52552 -2.74901e-030 -106.4564 3.601217 -6.310887e-030 -104.7373 -44.7788 -1.373963e-030 -66.76277 70.05491 -5.637993e-014 -68.21937 53.83701 -4.127297e-014 -68.55863 62.04185 -5.054886e-014 -65.7681 45.99956 -2.91844e-014 -62.95416 77.33014 -5.83688e-014 -61.37187 39.0636 -1.510696e-014 -57.39237 83.37173 -5.637993e-014 -55.33028 33.5018 0 -50.4564 87.76796 -5.054886e-014 -54.18848 31.40854 0 -52.54381 29.68213 0 -50.50835 28.44022 0 -48.22082 27.76744 0 -42.61895 90.21923 -4.127297e-014 -45.8371 27.70964 0 -43.51965 28.27076 0 -41.4264 29.41256 0 -34.41412 90.55849 -2.91844e-014 -38.42946 47.11159 0 -39.69999 31.05723 0 -38.45807 33.09269 0 -36.86605 53.9672 0 -33.69118 60.24126 0 -26.40105 88.76263 -1.510696e-014 -29.09332 65.56134 0 -23.3454 69.61164 0 -19.12582 84.95402 1.877284e-029 -16.7886 72.15173 0 -13.74167 81.56284 1.269697e-029 -9.81216 73.03084 0 -8.03964 78.73864 7.636926e-030 -2.830188 72.19677 0 -2.079244 76.51087 3.64551e-030 3.742859 69.69904 0 4.077324 74.9028 7.643719e-031 9.516804 65.68592 0 10.36582 73.93119 -9.764253e-031 14.1489 60.39562 0 16.72063 73.60619 -1.558716e-030 17.36419 54.14218 0 23.07544 73.93119 -9.764253e-031 19.14039 41.22425 0 92.15467 80.62257 -5.238305e-014 88.83104 50.24595 2.085226e-030 88.0531 85.73196 -5.423092e-014 92.70476 55.53018 -1.403599e-014 94.79408 74.62572 -4.696535e-014 95.07883 61.63694 -2.711546e-014 95.79146 68.15007 -3.834705e-014 -138.3173 50.47565 -5.441105e-014 -137.432 24.73624 -3.697808e-014 -140.3168 37.52194 -4.746962e-014 -131.7115 61.79639 -5.68373e-014 -130.0639 13.89615 -2.439509e-014 -121.4177 69.91023 -5.441105e-014 -119.2369 6.508783 -1.147007e-014 -108.8671 73.6891 -4.746962e-014 -95.8047 72.60761 -3.697808e-014 -95.3204 -50.22474 -9.478654e-032 -84.0465 66.81613 -2.439509e-014 -84.63247 -52.25073 9.446271e-031 -73.87579 -50.62886 1.627355e-030 -75.22729 57.11985 -1.147007e-014 -70.57319 44.86685 0 -64.26037 -45.54158 1.876598e-030 -69.61521 31.86262 0 -64.96236 19.68153 0 -57.00677 9.350201 0 -56.86785 -37.56115 1.664318e-030 -51.7342 -16.73615 -6.04464e-035 -46.41893 1.739326 0 -52.52979 -27.58529 1.014396e-030 -43.24859 -39.15101 -3.163366e-031 -34.09116 -2.50966 0 -28.50562 -58.04747 -5.308165e-031 -21.06243 -3.038659 0 -8.827904 -71.73027 -6.242584e-031 -8.430764 0.1969107 0 14.01921 -78.97189 -5.882796e-031 2.739249 6.924362 0 11.50623 16.57672 0 17.1313 28.34049 0 37.98603 -79.12265 -4.261077e-031 29.36394 74.9028 7.643719e-031 35.52051 76.51087 3.64551e-030 41.48091 78.73864 7.636926e-030 60.92244 -72.16905 -1.522917e-031 47.18293 81.56284 1.269697e-029 52.56709 84.95402 1.877284e-029 57.67648 89.0556 -1.403599e-014 63.67333 91.69501 -2.711546e-014 80.77074 -58.7349 2.086037e-031 70.14898 92.69238 -3.834705e-014 76.66211 91.97975 -4.696535e-014 82.76887 89.60568 -5.238305e-014 95.75028 -40.02542 6.242015e-031 100.8951 29.53631 1.822036e-030 104.5172 -17.71909 1.057217e-030 106.285 6.182927 1.468804e-030 -38.28861 40.08139 0 -37.78529 35.38022 0 -37.72749 37.76394 0</float_array>
                    <technique_common>
                        <accessor count="108" source="#ID8" stride="3">
                            <param name="X" type="float" />
                            <param name="Y" type="float" />
                            <param name="Z" type="float" />
                        </accessor>
                    </technique_common>
                </source>
                <source id="ID6">
                    <float_array id="ID9" count="324">5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1 5.652422e-017 -2.025185e-016 -1</float_array>
                    <technique_common>
                        <accessor count="108" source="#ID9" stride="3">
                            <param name="X" type="float" />
                            <param name="Y" type="float" />
                            <param name="Z" type="float" />
                        </accessor>
                    </technique_common>
                </source>
                <vertices id="ID7">
                    <input semantic="POSITION" source="#ID5" />
                    <input semantic="NORMAL" source="#ID6" />
                </vertices>
                <triangles count="106" material="Material2">
                    <input offset="0" semantic="VERTEX" source="#ID7" />
                    <p>0 1 2 1 0 3 3 0 4 3 4 5 6 7 8 7 6 9 9 6 10 9 10 11 11 10 12 11 12 13 13 12 14 13 14 15 15 14 16 16 14 17 17 14 18 18 14 19 18 19 20 20 19 21 21 19 22 22 19 23 22 23 24 22 24 25 25 24 26 24 23 27 27 23 28 28 23 29 28 29 30 30 29 31 31 29 32 31 32 33 33 32 34 33 34 35 35 34 36 35 36 37 37 36 38 37 38 39 39 38 40 39 40 41 41 40 42 41 42 43 43 42 44 43 44 45 45 44 46 45 46 47 48 49 50 49 48 51 51 48 52 51 52 53 53 52 54 55 56 57 56 55 58 56 58 59 59 58 60 59 60 61 61 60 62 61 62 4 4 62 63 4 63 5 5 63 64 64 63 65 64 65 66 66 65 67 67 65 68 67 68 69 67 69 70 70 69 71 70 71 72 70 72 73 70 73 74 74 73 75 75 73 76 74 75 77 75 76 78 78 76 79 78 79 80 80 79 81 80 81 82 82 81 83 82 83 84 84 83 85 84 85 86 84 86 87 84 87 88 88 87 47 88 47 46 88 46 89 88 89 90 88 90 91 88 91 92 92 91 93 92 93 94 92 94 95 92 95 96 92 96 97 97 96 98 97 98 99 97 99 100 97 100 101 101 100 49 49 100 50 101 49 102 101 102 103 103 102 104 26 105 106 105 26 24 106 105 107</p>
                </triangles>
            </mesh>
        </geometry>
    </library_geometries>
    <library_materials>
        <material id="ID4" name="material_0">
            <instance_effect url="#ID3" />
        </material>
    </library_materials>
    <library_effects>
        <effect id="ID3">
            <profile_COMMON>
                <technique sid="COMMON">
                    <lambert>
                        <diffuse>
                            <color>1 1 1 1</color>
                        </diffuse>
                    </lambert>
                </technique>
            </profile_COMMON>
        </effect>
    </library_effects>
    <scene>
        <instance_visual_scene url="#ID1" />
    </scene>
</COLLADA>


================================================
FILE: testbed/main.cc
================================================
/*
 * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
 * http://code.google.com/p/poly2tri/
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 * * Neither the name of Poly2Tri nor the names of its contributors may be
 *   used to endorse or promote products derived from this software without specific
 *   prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <cstdlib>
#include <GL/glfw.h>
#include <time.h>
#include <fstream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;

#include "../poly2tri/poly2tri.h"
using namespace p2t;

void Init();
void ShutDown(int return_code);
void MainLoop(const double zoom);
void Draw(const double zoom);
void DrawMap(const double zoom);
void ConstrainedColor(bool constrain);
double StringToDouble(const std::string& s);
double Random(double (*fun)(double), double xmin, double xmax);
double Fun(double x);

/// Dude hole examples
vector<Point*> CreateHeadHole();
vector<Point*> CreateChestHole();

/// Stalactite hole example
vector<Point*> CreateStalactiteHole();

float rotate_y = 0,
      rotate_z = 0;
const float rotations_per_tick = .2;

/// Screen center x
double cx = 0.0;
/// Screen center y
double cy = 0.0;

/// Constrained triangles
vector<Triangle*> triangles;
/// Triangle map
list<Triangle*> map;
/// Polylines
vector< vector<Point*> > polylines;

/// Draw the entire triangle map?
bool draw_map = false;
/// Create a random distribution of points?
bool random_distribution = false;

template <class C> void FreeClear( C & cntr ) {
    for ( typename C::iterator it = cntr.begin(); 
              it != cntr.end(); ++it ) {
        delete * it;
    }
    cntr.clear();
}

int main(int argc, char* argv[])
{

  int num_points = 0;
  double max, min;
  double zoom;

  if (argc != 5) {
    cout << "-== USAGE ==-" << endl;
    cout << "Load Data File: p2t filename center_x center_y zoom" << endl;
    cout << "Example: ./build/p2t testbed/data/dude.dat 500 500 1" << endl;
    return 1;
  }

  if(string(argv[1]) == "random") {
    num_points = atoi(argv[2]);
    random_distribution = true;
    char* pEnd;
    max = strtod(argv[3], &pEnd);
    min = -max;
    cx = cy = 0;
    zoom = atof(argv[4]);
  } else {
    zoom = atof(argv[4]);
    cx = atof(argv[2]);
    cy = atof(argv[3]);
  }

  vector<p2t::Point*> polyline;
    
  if(random_distribution) {
    // Create a simple bounding box
    polyline.push_back(new Point(min,min));
    polyline.push_back(new Point(min,max));
    polyline.push_back(new Point(max,max));
    polyline.push_back(new Point(max,min));
  } else {
    // Load pointset from file

    // Parse and tokenize data file
    string line;
    ifstream myfile(argv[1]);
    if (myfile.is_open()) {
      while (!myfile.eof()) {
        getline(myfile, line);
        if (line.size() == 0) {
          break;
        }
        istringstream iss(line);
        vector<string> tokens;
        copy(istream_iterator<string>(iss), istream_iterator<string>(),
             back_inserter<vector<string> >(tokens));
        double x = StringToDouble(tokens[0]);
        double y = StringToDouble(tokens[1]);
        polyline.push_back(new Point(x, y));
        num_points++;
      }
      myfile.close();
    } else {
      cout << "File not opened" << endl;
    }
  }
  
  cout << "Number of constrained edges = " << polyline.size() << endl;
  polylines.push_back(polyline);

  Init();

  /*
   * Perform triangulation!
   */

  double init_time = glfwGetTime();

  /*
   * STEP 1: Create CDT and add primary polyline
   * NOTE: polyline must be a simple polygon. The polyline's points
   * constitute constrained edges. No repeat points!!!
   */
  CDT* cdt = new CDT(polyline);

  /*
   * STEP 2: Add holes or Steiner points if necessary
   */
      
  string s(argv[1]);
  if(s.find("dude.dat", 0) != string::npos) {
    // Add head hole
    vector<Point*> head_hole = CreateHeadHole();
    num_points += head_hole.size();
    cdt->AddHole(head_hole);
    // Add chest hole
    vector<Point*> chest_hole = CreateChestHole();
    num_points += chest_hole.size();
    cdt->AddHole(chest_hole);
    polylines.push_back(head_hole);
    polylines.push_back(chest_hole);
  } else if (s.find("stalactite.dat", 0) != string::npos) {
    vector<Point*> stalactite_hole = CreateStalactiteHole();
    num_points += stalactite_hole.size();
    cdt->AddHole(stalactite_hole);
    polylines.push_back(stalactite_hole);
  } else if (random_distribution) {
    max-=(1e-4);
    min+=(1e-4);
    for(int i = 0; i < num_points; i++) {
      double x = Random(Fun, min, max);
      double y = Random(Fun, min, max);
      cdt->AddPoint(new Point(x, y));
    }
  }
  
  /*
   * STEP 3: Triangulate!
   */
  cdt->Triangulate();

  double dt = glfwGetTime() - init_time;

  triangles = cdt->GetTriangles();
  map = cdt->GetMap();

  cout << "Number of points = " << num_points << endl;
  cout << "Number of triangles = " << triangles.size() << endl;
  cout << "Elapsed time (ms) = " << dt*1000.0 << endl;

  MainLoop(zoom);

  // Cleanup
  
  delete cdt;
  
  // Free points
  for(int i = 0; i < polylines.size(); i++) {
    vector<Point*> poly = polylines[i];
    FreeClear(poly);
  }
  
  ShutDown(0);
  return 0;
}

void Init()
{
  const int window_width = 800,
            window_height = 600;

  if (glfwInit() != GL_TRUE)
    ShutDown(1);
  // 800 x 600, 16 bit color, no depth, alpha or stencil buffers, windowed
  if (glfwOpenWindow(window_width, window_height, 5, 6, 5, 0, 0, 0, GLFW_WINDOW) != GL_TRUE)
    ShutDown(1);

  glfwSetWindowTitle("Poly2Tri - C++");
  glfwSwapInterval(1);

  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glClearColor(0.0, 0.0, 0.0, 0.0);
  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
}

void ShutDown(int return_code)
{
  glfwTerminate();
  exit(return_code);
}

void MainLoop(const double zoom)
{
  // the time of the previous frame
  double old_time = glfwGetTime();
  // this just loops as long as the program runs
  bool running = true;

  while (running) {
    // calculate time elapsed, and the amount by which stuff rotates
    double current_time = glfwGetTime(),
           delta_rotate = (current_time - old_time) * rotations_per_tick * 360;
    old_time = current_time;

    // escape to quit, arrow keys to rotate view
    // Check if ESC key was pressed or window was closed
    running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED);

    if (glfwGetKey(GLFW_KEY_LEFT) == GLFW_PRESS)
      rotate_y += delta_rotate;
    if (glfwGetKey(GLFW_KEY_RIGHT) == GLFW_PRESS)
      rotate_y -= delta_rotate;
    // z axis always rotates
    rotate_z += delta_rotate;

    // Draw the scene
    if (draw_map) {
      DrawMap(zoom);
    } else {
      Draw(zoom);
    }

    // swap back and front buffers
    glfwSwapBuffers();
  }
}

void ResetZoom(double zoom, double cx, double cy, double width, double height)
{
  double left = -width / zoom;
  double right = width / zoom;
  double bottom = -height / zoom;
  double top = height / zoom;

  // Reset viewport
  glLoadIdentity();
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  // Reset ortho view
  glOrtho(left, right, bottom, top, 1, -1);
  glTranslatef(-cx, -cy, 0);
  glMatrixMode(GL_MODELVIEW);
  glDisable(GL_DEPTH_TEST);
  glLoadIdentity();

  // Clear the screen
  glClear(GL_COLOR_BUFFER_BIT);
}

void Draw(const double zoom)
{
  // reset zoom
  Point center = Point(cx, cy);

  ResetZoom(zoom, center.x, center.y, 800, 600);

  for (int i = 0; i < triangles.size(); i++) {
    Triangle& t = *triangles[i];
    Point& a = *t.GetPoint(0);
    Point& b = *t.GetPoint(1);
    Point& c = *t.GetPoint(2);

    // Red
    glColor3f(1, 0, 0);

    glBegin(GL_LINE_LOOP);
    glVertex2f(a.x, a.y);
    glVertex2f(b.x, b.y);
    glVertex2f(c.x, c.y);
    glEnd();
  }

  // green
  glColor3f(0, 1, 0);

  for(int i = 0; i < polylines.size(); i++) {
    vector<Point*> poly = polylines[i];
    glBegin(GL_LINE_LOOP);
      for(int j = 0; j < poly.size(); j++) {
        glVertex2f(poly[j]->x, poly[j]->y);
      }
    glEnd();
  }
}

void DrawMap(const double zoom)
{
  // reset zoom
  Point center = Point(cx, cy);

  ResetZoom(zoom, center.x, center.y, 800, 600);

  list<Triangle*>::iterator it;
  for (it = map.begin(); it != map.end(); it++) {
    Triangle& t = **it;
    Point& a = *t.GetPoint(0);
    Point& b = *t.GetPoint(1);
    Point& c = *t.GetPoint(2);

    ConstrainedColor(t.constrained_edge[2]);
    glBegin(GL_LINES);
    glVertex2f(a.x, a.y);
    glVertex2f(b.x, b.y);
    glEnd( );

    ConstrainedColor(t.constrained_edge[0]);
    glBegin(GL_LINES);
    glVertex2f(b.x, b.y);
    glVertex2f(c.x, c.y);
    glEnd( );

    ConstrainedColor(t.constrained_edge[1]);
    glBegin(GL_LINES);
    glVertex2f(c.x, c.y);
    glVertex2f(a.x, a.y);
    glEnd( );
  }
}

void ConstrainedColor(bool constrain)
{
  if (constrain) {
    // Green
    glColor3f(0, 1, 0);
  } else {
    // Red
    glColor3f(1, 0, 0);
  }
}

vector<Point*> CreateHeadHole() {

  vector<Point*> head_hole;
  head_hole.push_back(new Point(325, 437));
  head_hole.push_back(new Point(320, 423));
  head_hole.push_back(new Point(329, 413));
  head_hole.push_back(new Point(332, 423));

  return head_hole;
}

vector<Point*> CreateChestHole() {

  vector<Point*> chest_hole;
  chest_hole.push_back(new Point(320.72342,480));
  chest_hole.push_back(new Point(338.90617,465.96863));
  chest_hole.push_back(new Point(347.99754,480.61584));
  chest_hole.push_back(new Point(329.8148,510.41534));
  chest_hole.push_back(new Point(339.91632,480.11077));
  chest_hole.push_back(new Point(334.86556,478.09046));

  return chest_hole;

}

vector<Point*> CreateStalactiteHole() {
  vector<Point*> hole;
  hole.push_back(new Point(980, 1636));
  hole.push_back(new Point(950, 1600));
  hole.push_back(new Point(650, 1230));
  hole.push_back(new Point(625, 1247));
  hole.push_back(new Point(600, 1250));
  hole.push_back(new Point(591, 1350));
  hole.push_back(new Point(550, 2050));

  return hole;
}

double StringToDouble(const std::string& s)
{
  std::istringstream i(s);
  double x;
  if (!(i >> x))
    return 0;
  return x;
}

double Fun(double x)
{
  return 2.5 + sin(10 * x) / x;
}

double Random(double (*fun)(double), double xmin = 0, double xmax = 1)
{
  static double (*Fun)(double) = NULL, YMin, YMax;
  static bool First = true;

  // Initialises random generator for first call
  if (First)
  {
    First = false;
    srand((unsigned) time(NULL));
  }

  // Evaluates maximum of function
  if (fun != Fun)
  {
    Fun = fun;
    YMin = 0, YMax = Fun(xmin);
    for (int iX = 1; iX < RAND_MAX; iX++)
    {
      double X = xmin + (xmax - xmin) * iX / RAND_MAX;
      double Y = Fun(X);
      YMax = Y > YMax ? Y : YMax;
    }
  }

  // Gets random values for X & Y
  double X = xmin + (xmax - xmin) * rand() / RAND_MAX;
  double Y = YMin + (YMax - YMin) * rand() / RAND_MAX;

  // Returns if valid and try again if not valid
  return Y < fun(X) ? X : Random(Fun, xmin, xmax);
}


================================================
FILE: wscript
================================================
#! /usr/bin/env python
# encoding: utf-8
# waf 1.6.10

VERSION='0.3.3'
import sys
APPNAME='p2t'
top = '.'
out = 'build'

CPP_SOURCES = ['poly2tri/common/shapes.cc',
               'poly2tri/sweep/cdt.cc',
               'poly2tri/sweep/advancing_front.cc',
               'poly2tri/sweep/sweep_context.cc',
               'poly2tri/sweep/sweep.cc',
               'testbed/main.cc']

from waflib.Tools.compiler_cxx import cxx_compiler
cxx_compiler['win32'] = ['g++']

#Platform specific libs
if sys.platform == 'win32':
    # MS Windows
    sys_libs = ['glfw', 'opengl32']
elif sys.platform == 'darwin':
    # Apple OSX
    sys_libs = ['glfw', 'OpenGL']
else:
    # GNU/Linux, BSD, etc
    sys_libs = ['glfw', 'GL']

def options(opt):
  print('  set_options')
  opt.load('compiler_cxx')

def configure(conf):
  print('  calling the configuration')
  conf.load('compiler_cxx')
  conf.env.CXXFLAGS = ['-O3', '-ffast-math']
  conf.env.DEFINES_P2T = ['P2T']
  conf.env.LIB_P2T = sys_libs

def build(bld):
  print('  building')
  bld.program(features = 'cxx cxxprogram', source=CPP_SOURCES, target = 'p2t', uselib = 'P2T')
Download .txt
gitextract_iis_kvpo/

├── AUTHORS
├── LICENSE
├── README
├── poly2tri/
│   ├── common/
│   │   ├── shapes.cc
│   │   ├── shapes.h
│   │   └── utils.h
│   ├── poly2tri.h
│   └── sweep/
│       ├── advancing_front.cc
│       ├── advancing_front.h
│       ├── cdt.cc
│       ├── cdt.h
│       ├── sweep.cc
│       ├── sweep.h
│       ├── sweep_context.cc
│       └── sweep_context.h
├── testbed/
│   ├── data/
│   │   └── polygon.dae
│   └── main.cc
├── waf
└── wscript
Download .txt
SYMBOL INDEX (65 symbols across 12 files)

FILE: poly2tri/common/shapes.cc
  type p2t (line 34) | namespace p2t {
    function Point (line 119) | Point* Triangle::OppositePoint(Triangle& t, Point& p)
    function Point (line 216) | Point* Triangle::PointCW(Point& point)
    function Point (line 229) | Point* Triangle::PointCCW(Point& point)
    function Triangle (line 242) | Triangle* Triangle::NeighborCW(Point& point)
    function Triangle (line 253) | Triangle* Triangle::NeighborCCW(Point& point)
    function Triangle (line 348) | Triangle& Triangle::NeighborAcross(Point& opoint)

FILE: poly2tri/common/shapes.h
  function namespace (line 41) | namespace p2t {
  function set_zero (line 63) | void set_zero()
  function set (line 70) | void set(double x_, double y_)
  function Normalize (line 112) | double Normalize()
  type Edge (line 123) | struct Edge {
  function class (line 150) | class Triangle {
  function cmp (line 219) | inline bool cmp(const Point* a, const Point* b)
  function Dot (line 261) | inline double Dot(const Point& a, const Point& b)
  function Cross (line 267) | inline double Cross(const Point& a, const Point& b)
  function Point (line 274) | inline Point Cross(const Point& a, double s)
  function Point (line 281) | inline Point Cross(const double s, const Point& a)
  function Point (line 286) | inline Point* Triangle::GetPoint(const int& index)
  function Triangle (line 291) | inline Triangle* Triangle::GetNeighbor(const int& index)
  function Contains (line 296) | inline bool Triangle::Contains(Point* p)
  function Contains (line 301) | inline bool Triangle::Contains(const Edge& e)
  function Contains (line 306) | inline bool Triangle::Contains(Point* p, Point* q)
  function IsInterior (line 311) | inline bool Triangle::IsInterior()
  function IsInterior (line 316) | inline void Triangle::IsInterior(bool b)

FILE: poly2tri/common/utils.h
  function namespace (line 41) | namespace p2t {

FILE: poly2tri/sweep/advancing_front.cc
  type p2t (line 33) | namespace p2t {
    function Node (line 42) | Node* AdvancingFront::LocateNode(const double& x)
    function Node (line 64) | Node* AdvancingFront::FindSearchNode(const double& x)
    function Node (line 71) | Node* AdvancingFront::LocatePoint(const Point* point)

FILE: poly2tri/sweep/advancing_front.h
  function namespace (line 37) | namespace p2t {

FILE: poly2tri/sweep/cdt.cc
  type p2t (line 33) | namespace p2t {

FILE: poly2tri/sweep/cdt.h
  function namespace (line 45) | namespace p2t {

FILE: poly2tri/sweep/sweep.cc
  type p2t (line 37) | namespace p2t {
    function Node (line 74) | Node& Sweep::PointEvent(SweepContext& tcx, Point& point)
    function Node (line 177) | Node& Sweep::NewFrontTriangle(SweepContext& tcx, Point& point, Node& n...
    function Triangle (line 776) | Triangle& Sweep::NextFlipTriangle(SweepContext& tcx, int o, Triangle& ...
    function Point (line 796) | Point& Sweep::NextFlipPoint(Point& ep, Point& eq, Triangle& ot, Point&...

FILE: poly2tri/sweep/sweep.h
  function namespace (line 44) | namespace p2t {

FILE: poly2tri/sweep/sweep_context.cc
  type p2t (line 35) | namespace p2t {
    function Point (line 112) | Point* SweepContext::GetPoint(const int& index)
    function Node (line 122) | Node& SweepContext::LocateNode(Point& point)

FILE: poly2tri/sweep/sweep_context.h
  function namespace (line 39) | namespace p2t {
  type EdgeEvent (line 120) | struct EdgeEvent {
  function AdvancingFront (line 154) | inline AdvancingFront* SweepContext::front()
  function point_count (line 159) | inline int SweepContext::point_count()
  function set_head (line 164) | inline void SweepContext::set_head(Point* p1)
  function Point (line 169) | inline Point* SweepContext::head()
  function set_tail (line 174) | inline void SweepContext::set_tail(Point* p1)
  function Point (line 179) | inline Point* SweepContext::tail()

FILE: testbed/main.cc
  function FreeClear (line 83) | void FreeClear( C & cntr ) {
  function main (line 91) | int main(int argc, char* argv[])
  function Init (line 233) | void Init()
  function ShutDown (line 253) | void ShutDown(int return_code)
  function MainLoop (line 259) | void MainLoop(const double zoom)
  function ResetZoom (line 295) | void ResetZoom(double zoom, double cx, double cy, double width, double h...
  function Draw (line 318) | void Draw(const double zoom)
  function DrawMap (line 354) | void DrawMap(const double zoom)
  function ConstrainedColor (line 388) | void ConstrainedColor(bool constrain)
  function CreateHeadHole (line 399) | vector<Point*> CreateHeadHole() {
  function CreateChestHole (line 410) | vector<Point*> CreateChestHole() {
  function CreateStalactiteHole (line 424) | vector<Point*> CreateStalactiteHole() {
  function StringToDouble (line 437) | double StringToDouble(const std::string& s)
  function Fun (line 446) | double Fun(double x)
  function Random (line 451) | double Random(double (*fun)(double), double xmin = 0, double xmax = 1)
Condensed preview — 19 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (113K chars).
[
  {
    "path": "AUTHORS",
    "chars": 143,
    "preview": "Primary Contributors:\n\n  Mason Green <mason.green@gmail.com> (C++, Python)\n  Thomas hln <thahlen@gmail.com>    (Java)\n\nO"
  },
  {
    "path": "LICENSE",
    "chars": 1533,
    "preview": "Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\nhttp://code.google.com/p/poly2tri/\n\nAll rights reserved.\nRedistr"
  },
  {
    "path": "README",
    "chars": 2282,
    "preview": "#####################################################################################\n###\n### Since there are no Input "
  },
  {
    "path": "poly2tri/common/shapes.cc",
    "chars": 9126,
    "preview": "/* \n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\n * http://code.google.com/p/poly2tri/\n *\n * All rights re"
  },
  {
    "path": "poly2tri/common/shapes.h",
    "chars": 7462,
    "preview": "/*\n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\n * http://code.google.com/p/poly2tri/\n *\n * All rights res"
  },
  {
    "path": "poly2tri/common/utils.h",
    "chars": 3572,
    "preview": "/* \r\n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r\n * http://code.google.com/p/poly2tri/\r\n *\r\n * All right"
  },
  {
    "path": "poly2tri/poly2tri.h",
    "chars": 1721,
    "preview": "/* \n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\n * http://code.google.com/p/poly2tri/\n *\n * All rights re"
  },
  {
    "path": "poly2tri/sweep/advancing_front.cc",
    "chars": 3182,
    "preview": "/*\n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\n * http://code.google.com/p/poly2tri/\n *\n * All rights res"
  },
  {
    "path": "poly2tri/sweep/advancing_front.h",
    "chars": 2928,
    "preview": "/*\n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\n * http://code.google.com/p/poly2tri/\n *\n * All rights res"
  },
  {
    "path": "poly2tri/sweep/cdt.cc",
    "chars": 2310,
    "preview": "/* \r\n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r\n * http://code.google.com/p/poly2tri/\r\n *\r\n * All right"
  },
  {
    "path": "poly2tri/sweep/cdt.h",
    "chars": 2709,
    "preview": "/* \r\n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r\n * http://code.google.com/p/poly2tri/\r\n *\r\n * All right"
  },
  {
    "path": "poly2tri/sweep/sweep.cc",
    "chars": 26661,
    "preview": "/*\r\n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r\n * http://code.google.com/p/poly2tri/\r\n *\r\n * All rights"
  },
  {
    "path": "poly2tri/sweep/sweep.h",
    "chars": 8688,
    "preview": "/*\n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\n * http://code.google.com/p/poly2tri/\n *\n * All rights res"
  },
  {
    "path": "poly2tri/sweep/sweep_context.cc",
    "chars": 5473,
    "preview": "/*\n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\n * http://code.google.com/p/poly2tri/\n *\n * All rights res"
  },
  {
    "path": "poly2tri/sweep/sweep_context.h",
    "chars": 4275,
    "preview": "/*\r\n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r\n * http://code.google.com/p/poly2tri/\r\n *\r\n * All rights"
  },
  {
    "path": "testbed/data/polygon.dae",
    "chars": 10856,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\r\n<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" v"
  },
  {
    "path": "testbed/main.cc",
    "chars": 12776,
    "preview": "/*\r\n * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r\n * http://code.google.com/p/poly2tri/\r\n *\r\n * All rights"
  },
  {
    "path": "wscript",
    "chars": 1163,
    "preview": "#! /usr/bin/env python\r\n# encoding: utf-8\r\n# waf 1.6.10\r\n\r\nVERSION='0.3.3'\r\nimport sys\r\nAPPNAME='p2t'\r\ntop = '.'\r\nout = "
  }
]

// ... and 1 more files (download for full content)

About this extraction

This page contains the full source code of the greenm01/poly2tri GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 19 files (104.4 KB), approximately 31.1k tokens, and a symbol index with 65 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!