static PriorityHeap <VertexEv> setupEvQueue(IList <Vector3> poly)
        {
            PriorityHeap <VertexEv> queue = new PriorityHeap <VertexEv>();

            for (int i = 0; i < poly.Count; ++i)
            {
                Vector3 pv = poly[i];
                Vector3 nv = poly[(i + 1) % poly.Count];

                // [v_i, v_i+1]
                VertexEv ev1 = new VertexEv(pv, i, VertexEv.vType.LEFT);
                VertexEv ev2 = new VertexEv(nv, i, VertexEv.vType.LEFT);

                if (compareVector3(pv, nv) < 0)           // pv is left of nv
                {
                    ev2.type = VertexEv.vType.RIGHT;
                }
                else
                {
                    ev1.type = VertexEv.vType.RIGHT;
                }

                queue.Add(ev1);
                queue.Add(ev2);
            }
            return(queue);
        }
        public static bool isSimple(IList <Vector3> poly)
        {
            PriorityHeap <VertexEv> evQueue = setupEvQueue(poly);
            SweepLine SL = new SweepLine(poly);

            //Debug.LogWarning("Queue size=" + evQueue.Count);

            while (!evQueue.Empty)
            {
                VertexEv ev = evQueue.Pop();

                if (ev.type == VertexEv.vType.LEFT)
                {
                    int idx = SL.Add(ev.edge);

                    //Debug.Log("Left: " + idx + "/" + SL.Count);

                    if (SL.intersect(idx, idx - 1))
                    {
                        return(false);
                    }
                    if (SL.intersect(idx, idx + 1))
                    {
                        return(false);
                    }
                }
                else             // right vertex


                {
                    int idx = SL.Find(ev.edge);

                    //Debug.Log("Right: " + idx + "/" + SL.Count);

                    if (SL.intersect(idx - 1, idx + 1))
                    {
                        return(false);
                    }
                    SL.Remove(idx);
                }
            }

            return(true);
        }
        /*
         * List<List<Vector3>> decompose(List<Vector3> poly) {
         *
         * }
         */

        // returns one intersection point or null if polygon is simple

        static IntersectionPoint oneIntersection(IList <Vector3> poly)
        {
            PriorityHeap <VertexEv> evQueue = setupEvQueue(poly);
            SweepLine SL = new SweepLine(poly);

            IntersectionPoint I;

            while (!evQueue.Empty)
            {
                VertexEv ev = evQueue.Pop();

                if (ev.type == VertexEv.vType.LEFT)
                {
                    int idx = SL.Add(ev.edge);

                    I = SL.GetIntersectionPoint(idx, idx - 1);
                    if (I != null)
                    {
                        return(I);
                    }

                    I = SL.GetIntersectionPoint(idx, idx + 1);
                    if (I != null)
                    {
                        return(I);
                    }
                }
                else             // right vertex

                {
                    int idx = SL.Find(ev.edge);

                    I = SL.GetIntersectionPoint(idx - 1, idx + 1);
                    if (I != null)
                    {
                        return(I);
                    }
                    SL.Remove(idx);
                }
            }

            return(null);
        }
        public static void BentleyOttmann(IList <Vector3> poly)
        {
            PriorityHeap <VertexEv> evQ = setupEvQueue(poly);
            SweepLine SL = new SweepLine(poly);

            Dictionary <int, IntersectionPoint> intersectionPoints = new Dictionary <int, IntersectionPoint>();

            IntersectionPoint I;

            while (!evQ.Empty)
            {
                VertexEv ev = evQ.Pop();

                if (ev.type == VertexEv.vType.LEFT)
                {
                    int idx = SL.Add(ev.edge);

                    I = SL.GetIntersectionPoint(idx, idx - 1);

                    if (I != null)               // Intersection

                    {
                        int ID = I.Id(poly.Count);
                        if (!intersectionPoints.ContainsKey(ID))
                        {
                            intersectionPoints[ID] = I;
                            //evQ.Add(new VertexEv(I.v, I.Edge1, I.Edge2, VertexEv.vType.INTERSECT));
                            evQ.Add(new VertexEv(I));
                        }
                    }


                    I = SL.GetIntersectionPoint(idx, idx + 1);

                    if (I != null)               // intersection

                    {
                        int ID = I.Id(poly.Count);
                        if (!intersectionPoints.ContainsKey(ID))
                        {
                            intersectionPoints[ID] = I;
                            evQ.Add(new VertexEv(I.P, I.Edge1, I.Edge2, VertexEv.vType.INTERSECT));
                        }
                    }
                }
                else if (ev.type == VertexEv.vType.RIGHT)
                {
                    int idx = SL.Find(ev.edge);

                    I = SL.GetIntersectionPoint(idx - 1, idx + 1);

                    if (I != null)
                    {
                        int ID = I.Id(poly.Count);
                        if (!intersectionPoints.ContainsKey(ID))
                        {
                            intersectionPoints[ID] = I;
                            evQ.Add(new VertexEv(I));
                        }
                    }
                }
                else             // intersection point

                // unfinished business ...
                {
                }
            }
        }