public void classifySelf()
        {
            // we do need to compute the interior angle

            double pX, pY, qX, qY;

            pX = neighboor1.X - this.X;
            pY = neighboor1.Y - this.Y;
            qX = neighboor2.X - this.X;
            qY = neighboor2.Y - this.Y;

            double angle = PolygonVertex.Angle(pX, pY, qX, qY);

            if (PolygonVertex.CrossProductSign(pX, pY, qX, qY))
            {
                // it is exterior angle
                angle = 2 * Math.PI - angle;
            }
            if (neighboor1 < this && neighboor2 < this)
            {
                // start or split?
                type = (angle < Math.PI) ? PolygonVertexType.start : PolygonVertexType.split;
            }
            else if (neighboor1 > this && neighboor2 > this)
            {
                // end or merge?
                type = (angle < Math.PI) ? PolygonVertexType.end : PolygonVertexType.merge;
            }
            else
            {
                type = PolygonVertexType.regular;
            }
        }
Example #2
0
 private static bool intersect(PolygonVertex a, PolygonVertex b, PolygonVertex c, PolygonVertex d)
 {
     return(intersect_1(a.X, b.X, c.X, d.X) &&
            intersect_1(a.Y, b.Y, c.Y, d.Y) &&
            area(a, b, c) * area(a, b, d) <= 0 &&
            area(c, d, a) * area(c, d, b) <= 0);
 }
Example #3
0
        private void HandleRegularVertex(PolygonVertex v)
        {
            if (v.neighboor2.Y < v.Y)
            {
                // interior of P lies to the right of v (counterclockwise ordering)
                PolygonEdge   d  = edges.findEdgeEndingIn(v);
                PolygonEdge   e  = edges.findEdgeStartingIn(v);
                PolygonVertex dh = helpers[d];
                if (dh.type == PolygonVertexType.merge)
                {
                    insertDiagonal(dh, v);
                }
                T.Remove(d);

                T.Add(e);
                helpers[e] = v;
            }
            else
            {
                // interior of P lies to the left of v
                // search in T to find the edge ej directly left of v
                Dictionary <PolygonEdge, PointF> interSections = getIntersections(T, v);
                // take intersections to the left of vertex & select the leftmost _edge_ from them
                PolygonEdge ej = interSections.Where(kvp => kvp.Value.X < v.X).OrderBy(kvp => kvp.Value.X).Last().Key;
                if (helpers[ej].type == PolygonVertexType.merge)
                {
                    insertDiagonal(helpers[ej], v);
                }
                helpers[ej] = v;
            }
        }
Example #4
0
        private void HandleStartVertex(PolygonVertex v)
        {
            PolygonEdge e = edges.findEdgeStartingIn(v);

            T.Add(e);
            helpers[e] = v;
        }
Example #5
0
        private List <PolygonVertex> findMonotones(PolygonEdge diagonal)
        {
            PolygonVertex        start, end;
            List <PolygonVertex> vert = new List <PolygonVertex>();

            if (diagonal.edge1.index < diagonal.edge2.index)
            {
                start = diagonal.edge1;
                end   = diagonal.edge2;
            }
            else
            {
                start = diagonal.edge2;
                end   = diagonal.edge1;
            }

            PolygonVertex fixedStart = vertices.Find(v => v == start);
            PolygonVertex fixedEnd   = vertices.Find(v => v == end);

            while (start != end)
            {
                vert.Add(start);
                start = start.neighboor2;
            }
            vert.Add(end);

            fixedStart.neighboor2 = fixedEnd;
            fixedEnd.neighboor1   = fixedStart;

            vertices = vertices.Except(vert.Except(new[] { diagonal.edge1, diagonal.edge2 })).ToList();
            return(vert);
        }
Example #6
0
 private bool sameChain(Dictionary <PolygonVertex, int> chains, PolygonVertex a, PolygonVertex b)
 {
     if (a.neighboor1 == b || a.neighboor2 == b)
     {
         return(true);
     }
     return(chains[a] == chains[b]);
 }
Example #7
0
 public void insertDiagonal(PolygonVertex a, PolygonVertex b, Pen pen = null)
 {
     if (pen == null)
     {
         pen = Pens.Red;
     }
     graphics.DrawLine(pen, a.X, polygonBox.Height - a.Y, b.X, polygonBox.Height - b.Y);
     addedDiagonals.Add(new PolygonEdge(a, b));
 }
Example #8
0
        private void HandleEndVertex(PolygonVertex v)
        {
            PolygonEdge   d  = edges.findEdgeEndingIn(v);
            PolygonVertex dh = helpers[d];

            if (dh.type == PolygonVertexType.merge)
            {
                insertDiagonal(v, dh);
            }
            T.Remove(d);
        }
Example #9
0
        private void HandleSplitVertex(PolygonVertex v)
        {
            // search in T to find the edge ej directly left of v
            Dictionary <PolygonEdge, PointF> interSections = getIntersections(T, v);
            // take intersections to the left of vertex & select the leftmost _edge_ from them
            PolygonEdge ej = interSections.Where(kvp => kvp.Value.X < v.X).OrderBy(kvp => kvp.Value.X).Last().Key;
            PolygonEdge e  = edges.findEdgeStartingIn(v);

            insertDiagonal(v, helpers[ej]);
            helpers[ej] = v;
            T.Add(e);
            helpers[e] = v;
        }
Example #10
0
        public bool checkCrossing(PolygonVertex newVertex)
        {
            PolygonVertex lastPoint = vertices[vertices.Count - 1];

            for (int i = 0; i < vertices.Count - 2; i++)
            {
                if (intersect(vertices[i], vertices[i + 1], newVertex, lastPoint))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #11
0
        public void addVertex(PolygonVertex pv)
        {
            if (vertices.Count > 2 && checkCrossing(pv))
            {
                MessageBox.Show("Добавленная вершина создаст в прямоугольнике самопересечение!", "Ошибка");
                return;
            }
            ;

            pv.index = vertices.Count;
            vertices.Add(pv);
            graphics.FillEllipse(Brushes.Black, pv.X - 5, (polygonBox.Height - pv.Y - 5), 10, 10);
            if (vertices.Count > 1)
            {
                PolygonVertex prevVertex = vertices[vertices.Count - 2];
                pv.neighboor1         = prevVertex;
                prevVertex.neighboor2 = pv;
                edges.Add(new PolygonEdge(prevVertex, pv));
                graphics.DrawLine(Pens.Black, pv.X, polygonBox.Height - pv.Y, prevVertex.X, polygonBox.Height - prevVertex.Y);
            }
        }
Example #12
0
        private void HandleMergeVertex(PolygonVertex v)
        {
            PolygonEdge   d  = edges.findEdgeEndingIn(v);
            PolygonVertex dh = helpers[d];

            if (dh.type == PolygonVertexType.merge)
            {
                insertDiagonal(v, dh);
            }
            T.Remove(d);
            // search in T to find the edge ej directly left of v
            Dictionary <PolygonEdge, PointF> interSections = getIntersections(T, v);
            // take intersections to the left of vertex & select the leftmost _edge_ from them
            PolygonEdge ej = interSections.Where(kvp => kvp.Value.X < v.X).OrderBy(kvp => kvp.Value.X).Last().Key;

            if (helpers[ej].type == PolygonVertexType.merge)
            {
                insertDiagonal(v, helpers[ej]);
            }
            helpers[ej] = v;
        }
Example #13
0
 public static PolygonEdge findEdgeStartingIn(this List <PolygonEdge> edges, PolygonVertex v)
 {
     return(edges.Find(e => e.edge1 == v));
 }
Example #14
0
 public PolygonEdge(PolygonVertex e1, PolygonVertex e2)
 {
     edge1 = e1;
     edge2 = e2;
 }
Example #15
0
        private bool orientation(PolygonVertex a, PolygonVertex b, PolygonVertex c)
        {
            int v = (b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X);

            return(v > 0);
        }
Example #16
0
 private static float area(PolygonVertex a, PolygonVertex b, PolygonVertex c)
 {
     return((b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X));
 }
Example #17
0
        private Dictionary <PolygonEdge, PointF> getIntersections(HashSet <PolygonEdge> where, PolygonVertex v)
        {
            var ints = new Dictionary <PolygonEdge, PointF>();

            foreach (PolygonEdge e in where)
            {
                var line = e.toLine();
                ints[e] = intersectionPoint(line, v.Y);
            }
            return(ints);
        }
Example #18
0
        private void triangulateMonotonePolygon(List <PolygonVertex> polygon)
        {
            List <PolygonVertex>            V      = polygon.OrderByDescending(v => v.Y).ToList();
            Dictionary <PolygonVertex, int> chains = new Dictionary <PolygonVertex, int>();

            PolygonVertex chainStart = V[0], chainEnd = V.Last(), lc = chainStart.neighboor2, rc = chainStart.neighboor1;

            while (lc != chainEnd)
            {
                chains[lc] = -1; // left chain
                lc         = lc.neighboor2;
            }

            while (rc != chainEnd)
            {
                chains[rc] = 1; // right chain
                rc         = rc.neighboor1;
            }

            Stack <PolygonVertex> S = new Stack <PolygonVertex>();

            S.Push(V[0]);
            S.Push(V[1]);

            for (int j = 2; j < V.Count - 1; j++)
            {
                if (!sameChain(chains, V[j], S.Peek()))
                {
                    while (S.Count > 0)
                    {
                        if (S.Count != 1)
                        {
                            insertDiagonal(V[j], S.Peek(), new Pen(Color.SeaGreen, 1f));
                        }
                        S.Pop();
                    }
                    S.Push(V[j - 1]);
                    S.Push(V[j]);
                }
                else
                {
                    PolygonVertex last = S.Pop();
                    while (S.Count > 0 && (
                               (orientation(S.Peek(), last, V[j]) && chains[last] == -1) || (!orientation(S.Peek(), last, V[j]) && chains[last] == 1)))
                    {
                        last = S.Pop();
                        insertDiagonal(V[j], last, new Pen(Color.Yellow, 1f));
                    }
                    S.Push(last);
                    S.Push(V[j]);
                }
            }
            S.Pop(); // except the first
            while (S.Count > 0)
            {
                if (S.Count != 1)
                {
                    insertDiagonal(V[V.Count - 1], S.Peek(), Pens.Violet); // diag from u_j to all vert on the stack
                }
                S.Pop();                                                   // and the last one
            }
        }