Example #1
0
        private static void MakeEnterExitList(CircularLinkedList <Vector2> subject,
                                              CircularLinkedList <Vector2> clip,
                                              Dictionary <Vector2, Pair <Vector2> > intersections,
                                              CircularLinkedList <Vector2> entering,
                                              CircularLinkedList <Vector2> exiting,
                                              Polygon ClipP,
                                              Polygon SbujectP)
        {
            LinkedListNode <Vector2> curr = subject.First;

            do
            {
                if (intersections.ContainsKey(curr.Value))
                {
                    bool isEntering = Vector2Cross(subject.NextOrFirst(curr).Value.X - subject.PreviousOrLast(curr).Value.X,
                                                   subject.NextOrFirst(curr).Value.Y - subject.PreviousOrLast(curr).Value.Y,
                                                   intersections[curr.Value].Second.X - intersections[curr.Value].First.X,
                                                   intersections[curr.Value].Second.Y - intersections[curr.Value].First.Y) < 0;
                    if (isEntering)
                    {
                        entering.AddLast(curr.Value);
                    }
                    else
                    {
                        exiting.AddLast(curr.Value);
                    }
                }

                curr = subject.NextOrFirst(curr);
            } while (curr != subject.First);
        }
Example #2
0
        public CircularLinkedList <T> Reverse()
        {
            CircularLinkedList <T> temp = new CircularLinkedList <T>();

            foreach (var current in this)
            {
                temp.AddFirst(current);
            }

            return(temp);
        }
Example #3
0
        public static List <Polygon> GetClippedPolygons(Polygon Clip, Polygon Subject)
        {
            List <Polygon> output = new List <Polygon>();
            CircularLinkedList <Vector2> SubjectL = new CircularLinkedList <Vector2>();
            CircularLinkedList <Vector2> ClipL    = new CircularLinkedList <Vector2>();
            //todo check if subject inside clip
            bool AllPointsInside = true;

            for (int i = 0; i < Subject.points.Count; i++)
            {
                if (!Clip.IsInside(Subject.points[i]))
                {
                    AllPointsInside = false;
                    break;
                }
            }
            if (AllPointsInside)
            {
                output.Add(Subject);
                return(output);
            }
            for (int i = 0; i < Clip.points.Count; i++)
            {
                ClipL.AddLast(new Vector2(Clip.points[i].X, Clip.points[i].Y));
            }
            for (int i = 0; i < Subject.points.Count; i++)
            {
                SubjectL.AddLast(new Vector2(Subject.points[i].X, Subject.points[i].Y));
            }
            List <CircularLinkedList <Vector2> > result = (List <CircularLinkedList <Vector2> >)WeilerAtherton.Process(SubjectL, ClipL, Operation.Intersect, Clip, Subject);

            for (int i = 0; i < result.Count; i++)
            {
                output.Add(new Polygon()
                {
                    Completed = true
                });
                List <Vector2> temp = result[i].ToList <Vector2>();
                for (int j = 0; j < temp.Count; j++)
                {
                    output[output.Count - 1].Add(new Point((int)temp[j].X, (int)temp[j].Y));
                }
            }
            return(output);
        }
Example #4
0
        private static void Traverse(CircularLinkedList <Vector2> subject,
                                     CircularLinkedList <Vector2> clip,
                                     CircularLinkedList <Vector2> entering,
                                     CircularLinkedList <Vector2> exiting,
                                     List <CircularLinkedList <Vector2> > polygons,
                                     Operation operation)
        {
            while (entering.Count > 0)
            {
                CircularLinkedList <Vector2> polygon = new CircularLinkedList <Vector2>();
                Vector2 start = entering.First.Value;
                LinkedListNode <Vector2> curNode = subject.Find(start);
                polygon.AddLast(curNode.Value);
                curNode = subject.NextOrFirst(curNode);
                bool IsSubjectNode = true;
                while (curNode.Value != start)
                {
                    polygon.AddLast(curNode.Value);
                    if (entering.Contains(curNode.Value))
                    {
                        entering.Remove(curNode.Value);
                        IsSubjectNode = true;
                        curNode       = subject.Find(curNode.Value);
                    }
                    if (exiting.Contains(curNode.Value))
                    {
                        exiting.Remove(curNode.Value);

                        IsSubjectNode = false;
                        curNode       = clip.Find(curNode.Value);
                    }
                    if (IsSubjectNode)
                    {
                        curNode = subject.NextOrFirst(curNode);
                    }
                    else
                    {
                        curNode = clip.NextOrFirst(curNode);
                    }
                }
                entering.Remove(curNode.Value);
                polygons.Add(polygon);
            }
        }
Example #5
0
        private static LinkedListNode <Vector2> TraverseList(CircularLinkedList <Vector2> contour,
                                                             CircularLinkedList <Vector2> entering,
                                                             CircularLinkedList <Vector2> exiting,
                                                             CircularLinkedList <Vector2> polygon,
                                                             LinkedListNode <Vector2> currentNode,
                                                             Vector2 startNode,
                                                             CircularLinkedList <Vector2> contour2)
        {
            LinkedListNode <Vector2> contourNode = contour.Find(currentNode.Value);

            if (contourNode == null)
            {
                return(null);
            }

            entering.Remove(currentNode.Value);

            while (contourNode != null
                   &&
                   !entering.Contains(contourNode.Value)
                   &&
                   !exiting.Contains(contourNode.Value)
                   )
            {
                polygon.AddLast(contourNode.Value);
                contourNode = contour.NextOrFirst(contourNode);

                if (contourNode.Value == startNode)
                {
                    return(null);
                }
            }

            entering.Remove(contourNode.Value);
            polygon.AddLast(contourNode.Value);

            return(contour2.NextOrFirst(contour2.Find(contourNode.Value)));
        }
Example #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="subject">Первый контур.</param>
        /// <param name="clip">Второй контур.</param>
        /// <param name="operation">Операция, проводимая над контурами.</param>
        /// <returns></returns>
        public static ICollection <CircularLinkedList <Vector2> > Process(CircularLinkedList <Vector2> subject,
                                                                          CircularLinkedList <Vector2> clip,
                                                                          Operation operation,
                                                                          Polygon ClipP,
                                                                          Polygon SubjectP)
        {
            LinkedListNode <Vector2> curSubject = subject.First;
            Dictionary <Vector2, Pair <Vector2> > intersections = new Dictionary <Vector2, Pair <Vector2> >();
            List <CircularLinkedList <Vector2> >  polygons      = new List <CircularLinkedList <Vector2> >();

            if (AreEqual <Vector2>(subject, clip))
            {
                switch (operation)
                {
                case Operation.Union:
                    polygons.Add(subject);
                    return(polygons);

                case Operation.Intersect:
                    polygons.Add(subject);
                    return(polygons);

                case Operation.Difference:
                    // нужно как-то разграничивать внешние и внутренние полигоны
                    return(polygons);

                default:
                    break;
                }
            }

            do
            {
                LinkedListNode <Vector2> curClip = clip.First;
                do
                {
                    Vector2 intersectionPoint;
                    if (IntersectSegment(curSubject.Value,
                                         subject.NextOrFirst(curSubject).Value,
                                         curClip.Value,
                                         clip.NextOrFirst(curClip).Value,
                                         out intersectionPoint))
                    {
                        if (!intersections.ContainsKey(intersectionPoint))
                        {
                            subject.AddAfter(curSubject, intersectionPoint);
                            clip.AddAfter(curClip, intersectionPoint);
                            intersections.Add(intersectionPoint, new Pair <Vector2>(curClip.Value, clip.NextOrFirst(curClip).Value));
                        }
                    }
                    curClip = clip.NextOrFirst(curClip);
                }while (curClip != clip.First);

                curSubject = subject.NextOrFirst(curSubject);
            }while (curSubject != subject.First);


            CircularLinkedList <Vector2> entering = new CircularLinkedList <Vector2>();
            CircularLinkedList <Vector2> exiting  = new CircularLinkedList <Vector2>();

            MakeEnterExitList(subject, clip, intersections, entering, exiting, ClipP, SubjectP);

            Traverse(subject, clip, entering, exiting, polygons, operation);

            return(polygons);
        }