/**
  * This method was created by a SmartGuide.
  * @return Point
  * @param a int
  * @param b int
  */
 public ColoredPoint getTriangle(int a, int b, Polygon p)
 {
     for (int i = 0; i < p.vertices.Count; i++)
     {
         if ((i != b) && (i != a))
         {
             if (p.areNeighbors(a, i) && p.areNeighbors(b, i) && (p.getColoredPoint(i).vertexColor == 0))
             {
                 return p.getColoredPoint(i);
             }
         }
     }
     return null;
 }
        /**
         * This method was created by a SmartGuide.
         * @return Point
         * @param a int
         * @param b int
         */
        public ColoredPoint getTriangle(int a, int b, Polygon p)
        {
            for (int i = 0; i < p.vertices.Count; i++)
            {
                if ((i != b) && (i != a))
                {
                    if((p.getColoredPoint(i).vertexColor == ColoredPoint.color.None))
                    {
                        return p.getColoredPoint(i);
                    }
                }
            }

            return null;
        }
 public DiagonalSet triangulate(Polygon P)
 {
     DiagonalSet d = new DiagonalSet();
     int i, i1, i2;
     int n = P.vertices.Count;
     if (n >= 3)
         for (i = 0; i < n; i++)
         {
             i1 = (i + 1) % n;
             i2 = (i + 2) % n;
             if (isDiagonal(i, i2, P))
             {
                 d.addDiagonal(P.getColoredPoint(i), P.getColoredPoint(i2), P.getColoredPoint(i1));
                 clipEar(i1, P);
                 return d.merge(triangulate(P));
             }
         }
     return d;
 }
        TriangulationColoring color(DiagonalSet d, Polygon p)
        {
            TriangulationColoring CSet = new TriangulationColoring();
            Edge curDiag = d.getDiagonal(0);
            ColoredPoint a, b, cut;
            int d1, d2;
            if (p.vertices.Count == 3)
            {
                a = p.getColoredPoint(0);
                b = p.getColoredPoint(1);
                cut = p.getColoredPoint(2);
                a.vertexColor = ColoredPoint.color.Blue;
                b.vertexColor = ColoredPoint.color.Red;
                cut.vertexColor = ColoredPoint.color.Blue;
                CSet.add(a);
                CSet.add(b);
                CSet.add(cut);
                return CSet;
            }

            a = p.getColoredPoint(curDiag.getStart().index);
            b = p.getColoredPoint(curDiag.getEnd().index);
            cut = p.getColoredPoint(curDiag.getCutPnt().index);

            p.getColoredPoint(a.index).vertexColor = ColoredPoint.color.Blue;
            p.getColoredPoint(b.index).vertexColor = ColoredPoint.color.Red;
            p.getColoredPoint(cut.index).vertexColor = ColoredPoint.color.Blue;

            CSet.add(a);
            CSet.add(b);
            CSet.add(cut);

            if ((d1 = d.isInDiagSet(a, cut)) != -1) CSet.add(recurseColor(d, p, d1));
            if ((d2 = d.isInDiagSet(b, cut)) != -1) CSet.add(recurseColor(d, p, d2));

            CSet.add(recurseColor(d, p, 0));
            return CSet;
        }
        TriangulationColoring recurseColor(DiagonalSet d, Polygon p, int i)
        {
            TriangulationColoring CSet = new TriangulationColoring();
            Edge curDiag = d.getDiagonal(i);
            ColoredPoint a, b, cut;
            int d1, d2;

            a = p.getColoredPoint(curDiag.Start.index);
            b = p.getColoredPoint(curDiag.End.index);
            cut = p.getColoredPoint(curDiag.Cutoff.index);

            if (cut.vertexColor == ColoredPoint.color.None) // point has not been colored
            {
                p.vertices[cut.index].vertexColor = (GeometryTest.ColoredPoint.color)nextColor(a.index, b.index);
                CSet.add(cut);
                if ((d1 = d.isInDiagSet(a, cut)) != -1)
                    CSet.add(recurseColor(d, p, d1));
                if ((d2 = d.isInDiagSet(b, cut)) != -1)
                    CSet.add(recurseColor(d, p, d2));

                if ((d1 = d.isInDiagSet2(a, cut)) != -1)
                    CSet.add(recurseColor(d, p, d1));
                if ((d2 = d.isInDiagSet2(b, cut)) != -1)
                    CSet.add(recurseColor(d, p, d2));
            }
            else
            {
                cut = getTriangle(a.index, b.index, p);
                if (cut == null)
                {
                    return CSet;
                }
                p.vertices[cut.index].vertexColor = (GeometryTest.ColoredPoint.color)nextColor((int)a.vertexColor, (int)b.vertexColor);
                CSet.add(cut);
                if ((d1 = d.isInDiagSet(a, cut)) != -1) CSet.add(recurseColor(d, p, d1));
                if ((d2 = d.isInDiagSet(b, cut)) != -1) CSet.add(recurseColor(d, p, d2));
                if ((d1 = d.isInDiagSet2(a, cut)) != -1) CSet.add(recurseColor(d, p, d1));
                if ((d2 = d.isInDiagSet2(b, cut)) != -1) CSet.add(recurseColor(d, p, d2));
            }
            return CSet;
        }
        bool inCone(int i, int j, Polygon P)
        {
            int n = P.vertices.Count;

            int i1 = (i + 1) % n;
            int in1 = (i + n - 1) % n;

            if (LeftOn(P.getColoredPoint(in1), P.getColoredPoint(i), P.getColoredPoint(i1)))
            {
                return Left(P.getColoredPoint(i), P.getColoredPoint(j), P.getColoredPoint(in1)) &&
                 Left(P.getColoredPoint(j), P.getColoredPoint(i), P.getColoredPoint(i1));
            }

            else
            {
                return !(LeftOn(P.getColoredPoint(i), P.getColoredPoint(j), P.getColoredPoint(i1)) && LeftOn(P.getColoredPoint(j), P.getColoredPoint(i), P.getColoredPoint(in1)));
            }
        }
        bool diagonal(int i, int j, Polygon P)
        {
            int k;
            int k1;
            int n = P.vertices.Count;

            for (k = 0; k < n; k++)
            {
                k1 = (k + 1) % n;
                if (!((k == i) || (k1 == i) || (k == j) || (k1 == j)))
                {
                    if (intersect(P.getColoredPoint(i), P.getColoredPoint(j), P.getColoredPoint(k), P.getColoredPoint(k1)))
                        return false;
                }
            }
            return true;
        }