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); }
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); } }
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))); }
/// <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); }