private void HandleSplit(Event ev) { Event Left = T.DirectUpperAndLower(ev).Value; output.Add(new Line(ev.vertix, helper[Left.edgeIndex].vertix)); //here helper[Left.edgeIndex] = ev; T.Add(ev); helper[ev.edgeIndex] = ev; //throw new NotImplementedException(); }
private void handleEvent(Event curEvent, OrderedSet <Event> L, OrderedSet <Event> Q, List <Point> outPoints) { switch (curEvent.pType) { case PointType.Start: { KeyValuePair <Event, Event> upLow = L.DirectUpperAndLower(curEvent); if (upLow.Key != null) { checkIntersection(upLow.Key, curEvent, Q, outPoints); } if (upLow.Value != null) { checkIntersection(curEvent, upLow.Value, Q, outPoints); } L.Add(curEvent); break; } case PointType.End: { KeyValuePair <Event, Event> upLow = L.DirectUpperAndLower(curEvent); if (upLow.Key != null && upLow.Value != null) { checkIntersection(upLow.Key, upLow.Value, Q, outPoints); } L.Remove(new Event(segments[curEvent.segIdx].Start, PointType.Start, curEvent.segIdx, null, null)); break; } case PointType.Intersection: { Event upup = L.DirectUpperAndLower(curEvent.upper).Key; Event lowlow = L.DirectUpperAndLower(curEvent.lower).Value; if (upup != null) { checkIntersection(upup, curEvent.lower, Q, outPoints); } if (lowlow != null) { checkIntersection(curEvent.upper, lowlow, Q, outPoints); } L.Remove(curEvent.upper); L.Remove(curEvent.lower); curEvent.lower.point.X = curEvent.point.X; curEvent.lower.point.Y = curEvent.point.Y; curEvent.upper.point.X = curEvent.point.X; curEvent.upper.point.Y = curEvent.point.Y; L.Add(curEvent.upper); L.Add(curEvent.lower); break; } default: break; } }
private void handleRegular(int i) { if (interiorRight(i)) { handleEnd(i); T.Add(i); helper[i] = i; } else { int dirLeft = T.DirectUpperAndLower(i).Value; if (checkCase(helper[dirLeft]) == 3) { ll.Add(new Line(p[helper[dirLeft]], p[i])); neighbors[Math.Max(helper[dirLeft], i)].Add(Math.Min(helper[dirLeft], i)); //neighbors[helper[dirLeft]].Add(i); //neighbors[i].Add(helper[dirLeft]); } helper[dirLeft] = i; } }
public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons) { if (points.Count < 3) { for (int i = 0; i < points.Count; i++) { outPoints.Add(points[i]); } return; } Point myCenterPoint = HelperMethods.getCenterOfTriangle(points[0], points[1], points[2]); baseLine = new Line(myCenterPoint, new Point(myCenterPoint.X + 50, myCenterPoint.Y)); OrderedSet <Point> ConvexHull = new OrderedSet <Point>(new Comparison <Point>(compareByAngle)); ConvexHull.Add(points[0]); ConvexHull.Add(points[1]); ConvexHull.Add(points[2]); for (int i = 3; i < points.Count; i++) { Point p = points[i]; Point previousPoint = ConvexHull.DirectUpperAndLower(p).Key; Point nextPoint = ConvexHull.DirectUpperAndLower(p).Value; if (HelperMethods.CheckTurn(new Line(previousPoint, nextPoint), p) == Enums.TurnType.Right) { Point newPrev = ConvexHull.DirectUpperAndLower(previousPoint).Key; while (HelperMethods.CheckTurn(new Line(p, previousPoint), newPrev) == Enums.TurnType.Left) { ConvexHull.Remove(previousPoint); previousPoint = newPrev; newPrev = ConvexHull.DirectUpperAndLower(previousPoint).Key; } Point newNext = ConvexHull.DirectUpperAndLower(nextPoint).Value; while (HelperMethods.CheckTurn(new Line(p, nextPoint), newNext) == Enums.TurnType.Right) { ConvexHull.Remove(nextPoint); nextPoint = newNext; newNext = ConvexHull.DirectUpperAndLower(nextPoint).Value; } ConvexHull.Add(p); } } outPoints.AddRange(ConvexHull); }
public override void Run(List<Point> points, List<Line> lines, List<Polygon> polygons, ref List<Point> outPoints, ref List<Line> outLines, ref List<Polygon> outPolygons) { OrderedDictionary<double, Point> point = new OrderedDictionary<double, Point>(); OrderedSet<double> angles = new OrderedSet<double>(); if (points.Count == 1) { outPoints.Add(points[0]); } else if (points.Count == 2 && points[0] != points[1]) { outPoints.Add(points[0]); outPoints.Add(points[1]); } else { double X = 0; double Y = 0; for (int i = 0; i < 3; i++) { X += points[i].X; Y += points[i].Y; } Point medPoint = new Point(X / 3, Y / 3); Point medPoint2 = new Point((X / 3) + 100, Y / 3); Point ab = new Point(medPoint.X - medPoint2.X, medPoint.Y - medPoint2.Y); for (int i = 0; i < points.Count; i++) { Point ac = new Point(points[i].X - medPoint.X, points[i].Y - medPoint.Y); double cross = HelperMethods.CrossProduct(ab, ac); double dot = (ab.X * ac.X) + (ab.Y * ac.Y); double angle = Math.Atan2(cross, dot); if (angle < 0) angle = angle + (2 * Math.PI); angles.Add(angle); point[angle] = points[i]; } for (int i = 3; i < point.Count; i++) { double next = 0; double prev = 0; if (angles[i] == angles.Max()) { next = angles[0]; prev = angles.Max(); } else if (angles[i] == angles.Min()) { prev = angles[0]; next = angles.Max(); } else { KeyValuePair<double, double> x = angles.DirectUpperAndLower(angles[i]); next = x.Key; if (next == 0.0) { next = angles[0]; } prev = x.Value; if (prev == 0.0) { prev = angles.Max(); } } if (HelperMethods.CheckTurn(new Line(point[prev], point[next]), point.ElementAt(i).Value) == Enums.TurnType.Right || HelperMethods.CheckTurn(new Line(point[prev], point[next]), point.ElementAt(i).Value) == Enums.TurnType.Colinear) { int count = 0; double newprev = angles.DirectUpperAndLower(prev).Value; if (newprev == 0.0) { newprev = angles.Max(); } while (HelperMethods.CheckTurn(new Line(point[angles[i]], point[prev]), point[newprev]) == Enums.TurnType.Left) { double oldprev = prev; prev = newprev; newprev = angles.DirectUpperAndLower(prev).Value; if (newprev == 0.0) { newprev = angles.Max(); } point.Remove(oldprev); angles.Remove(oldprev); i--; } double newnext = angles.DirectUpperAndLower(next).Key; if (newnext == 0.0) { newnext = angles[0]; } while (HelperMethods.CheckTurn(new Line(point[angles[i]], point[next]), point[newnext]) == Enums.TurnType.Right) { double oldnext = next; next = newnext; newnext = angles.DirectUpperAndLower(next).Key; if (newnext == 0.0) { newnext = angles[0]; } point.Remove(oldnext); angles.Remove(oldnext); } } else { point.Remove(angles[i]); angles.Remove(angles[i]); i--; } } } for (int i = 0; i < point.Count; i++) { outPoints.Add(point.ElementAt(i).Value); } }
public override void Run(List <CGUtilities.Point> points, List <CGUtilities.Line> lines, List <CGUtilities.Polygon> polygons, ref List <CGUtilities.Point> outPoints, ref List <CGUtilities.Line> outLines, ref List <CGUtilities.Polygon> outPolygons) { OrderedSet <Tuple <int, int> > Intersected_lines = new OrderedSet <Tuple <int, int> >(); EventPoint.lines = lines; OrderedSet <EventPoint> Q = new OrderedSet <EventPoint>(Compare_X); OrderedSet <EventPoint> L = new OrderedSet <EventPoint>(Compare_Y); for (int i = 0; i < lines.Count; ++i) { if (ComparePoints(lines[i].Start, lines[i].End) == false) { lines[i] = new Line(lines[i].End, lines[i].Start); } Q.Add(new EventPoint(lines[i].Start, i, 1)); Q.Add(new EventPoint(lines[i].End, i, -1)); } int counter = lines.Count; while (Q.Count != 0) { EventPoint current_event = Q.GetFirst(); Q.RemoveFirst(); if (current_event.event_type == 1) { L.Add(current_event); if (lines[current_event.index].Start.X == lines[current_event.index].End.Y) { IEnumerable <EventPoint> vertical__ = L; foreach (EventPoint e in vertical__) { if (TwoSegmentsIntersectionTest(lines[e.index], lines[current_event.index])) { Point point_of_intersection = twoLinesIntersectionPoint(lines[e.index], lines[current_event.index]); if (HasValue(point_of_intersection.X) && HasValue(point_of_intersection.Y) && !Intersected_lines.Contains(new Tuple <int, int>(current_event.index, e.index))) { outPoints.Add(point_of_intersection); Intersected_lines.Add(new Tuple <int, int>(current_event.index, e.index)); Intersected_lines.Add(new Tuple <int, int>(e.index, current_event.index)); Q.Add(new EventPoint(point_of_intersection, e, current_event, 0)); } } } continue; } EventPoint pre = L.DirectUpperAndLower(current_event).Key; EventPoint next = L.DirectUpperAndLower(current_event).Value; if (pre != null) { if (TwoSegmentsIntersectionTest(lines[pre.index], lines[current_event.index])) { Point point_of_intersection = twoLinesIntersectionPoint(lines[pre.index], lines[current_event.index]); if (!Q.Contains(new EventPoint(point_of_intersection, pre, current_event, 0)) && !Intersected_lines.Contains(new Tuple <int, int>(pre.index, current_event.index))) { outPoints.Add(point_of_intersection); Intersected_lines.Add(new Tuple <int, int>(current_event.index, pre.index)); Intersected_lines.Add(new Tuple <int, int>(pre.index, current_event.index)); Q.Add(new EventPoint(point_of_intersection, pre, current_event, 0)); } } } if (next != null) { if (TwoSegmentsIntersectionTest(lines[current_event.index], lines[next.index])) { Point point_of_intersection = twoLinesIntersectionPoint(lines[current_event.index], lines[next.index]); if (!Q.Contains(new EventPoint(point_of_intersection, current_event, next, 0)) && !Intersected_lines.Contains(new Tuple <int, int>(current_event.index, next.index))) { outPoints.Add(point_of_intersection); Q.Add(new EventPoint(point_of_intersection, current_event, next, 0)); Intersected_lines.Add(new Tuple <int, int>(next.index, current_event.index)); Intersected_lines.Add(new Tuple <int, int>(current_event.index, next.index)); } } } } else if (current_event.event_type == -1) { EventPoint pre = L.DirectUpperAndLower(current_event).Key; EventPoint next = L.DirectUpperAndLower(current_event).Value; if (pre != null && next != null) { if (TwoSegmentsIntersectionTest(lines[pre.index], lines[next.index])) { Point point_of_intersection = twoLinesIntersectionPoint(lines[pre.index], lines[next.index]); if (!Q.Contains(new EventPoint(point_of_intersection, pre, next, 0)) && !Intersected_lines.Contains(new Tuple <int, int>(pre.index, next.index))) { Intersected_lines.Add(new Tuple <int, int>(pre.index, next.index)); Intersected_lines.Add(new Tuple <int, int>(next.index, pre.index)); Q.Add(new EventPoint(point_of_intersection, pre, next, 0)); outPoints.Add(point_of_intersection); } } } if (current_event.index != 0) { List <EventPoint> LL = L.RemoveAll(p => p.index == current_event.index).ToList(); for (int i = 0; i < LL.Count; ++i) { L.Remove(LL[i]); } } else { L.Remove(current_event); } } else { EventPoint s1 = current_event.intersection_segment_1; EventPoint s2 = current_event.intersection_segment_2; /* if (HasValue(current_event.point.X) && HasValue(current_event.point.Y) && !Intersected_lines.Contains(new Tuple<int, int>(s1.index, s2.index))) * { * outPoints.Add(current_event.point); * Intersected_lines.Add(new Tuple<int, int>(s1.index, s2.index)); * Intersected_lines.Add(new Tuple<int, int>(s2.index, s1.index)); * * }*/ EventPoint s1_prev = L.DirectUpperAndLower(s1).Key; EventPoint s2_next = L.DirectUpperAndLower(s2).Value; if (s1_prev != null) { if (TwoSegmentsIntersectionTest(lines[s1_prev.index], lines[s2.index])) { Point point_of_intersection = twoLinesIntersectionPoint(lines[s1_prev.index], lines[s2.index]); if (!Q.Contains(new EventPoint(point_of_intersection, s1_prev, s2, 0)) && !Intersected_lines.Contains(new Tuple <int, int>(s1_prev.index, s2.index))) { Q.Add(new EventPoint(point_of_intersection, s1_prev, s2, 0)); outPoints.Add(point_of_intersection); Intersected_lines.Add(new Tuple <int, int>(s1_prev.index, s2.index)); Intersected_lines.Add(new Tuple <int, int>(s2.index, s1_prev.index)); } } } if (s2_next != null) { if (TwoSegmentsIntersectionTest(lines[s1.index], lines[s2_next.index])) { Point point_of_intersection = twoLinesIntersectionPoint(lines[s1.index], lines[s2_next.index]); if (!Q.Contains(new EventPoint(point_of_intersection, s1, s2_next, 0)) && !Intersected_lines.Contains(new Tuple <int, int>(s1.index, s2_next.index))) { Q.Add(new EventPoint(point_of_intersection, s1, s2_next, 0)); outPoints.Add(point_of_intersection); Intersected_lines.Add(new Tuple <int, int>(s1.index, s2_next.index)); Intersected_lines.Add(new Tuple <int, int>(s2_next.index, s1.index)); } } } L.Remove(s1); L.Remove(s2); double PX = current_event.point.X + 0.3; double PY1 = current_event.point.Y + 10000; double PY2 = current_event.point.Y - 10000; Line sweepL = new Line(new Point(PX, PY1), new Point(PX, PY2)); Point P1 = twoLinesIntersectionPoint(sweepL, lines[s1.index]); Point P2 = twoLinesIntersectionPoint(sweepL, lines[s2.index]); s1.point = P1; s2.point = P2; L.Add(s1); L.Add(s2); } } }
public override void Run(List <CGUtilities.Point> points, List <CGUtilities.Line> lines, List <CGUtilities.Polygon> polygons, ref List <CGUtilities.Point> outPoints, ref List <CGUtilities.Line> outLines, ref List <CGUtilities.Polygon> outPolygons) { OrderedSet <EventPoint> Q = new OrderedSet <EventPoint>(Compare_Y); Dictionary <int, EventPoint> prev_event = new Dictionary <int, EventPoint>(); Dictionary <int, EventPoint> helper = new Dictionary <int, EventPoint>(); OrderedSet <EventPoint> T = new OrderedSet <EventPoint>(Compare_X); string type; for (int i = 0; i < polygons[0].lines.Count; ++i) { Point n1 = polygons[0].lines[(polygons[0].lines.Count + i - 1) % polygons[0].lines.Count].Start; Point p = polygons[0].lines[i].Start; Point n2 = polygons[0].lines[(i + 1) % polygons[0].lines.Count].Start; double angle = CalcAngle(n1, p, n2); if (((n1.Y < p.Y) || ((n1.Y == p.Y) && (n1.X > p.Y))) && ((n2.Y < p.Y) || ((n2.Y == p.Y) && (n2.X > p.X)))) { if (angle < 180) { type = "Start"; } else { type = "Split"; } } else if (((p.Y < n1.Y) || ((p.Y == n1.Y) && (p.X > n1.Y))) && ((p.Y < n2.Y) || ((p.Y == n2.Y) && (p.X > n2.X)))) { if (angle < 180) { type = "End"; } else { type = "Merge"; } } else { type = "Regular"; } EventPoint ev = new EventPoint(polygons[0].lines[i].Start, i, type, polygons[0].lines[i].End); Q.Add(ev); EventPoint prev; if (i != (polygons[0].lines.Count - 1)) { prev = new EventPoint(polygons[0].lines[i].Start, i, type, polygons[0].lines[i].End); prev_event.Add(i + 1, prev); } else { prev = new EventPoint(polygons[0].lines[i].Start, i, type, polygons[0].lines[i].End); prev_event.Add(0, prev); } } while (Q.Count != 0) { EventPoint ev = Q.First(); Y = ev.point.Y; if (ev.event_type == "Start") { helper.Add(ev.index, ev); T.Add(ev); } else if (ev.event_type == "End") { if (ev.index - 1 >= 0) { if (helper[ev.index - 1].event_type == "Merge") { outLines.Add(new Line(ev.point, helper[ev.index - 1].point)); } T.Remove(helper[ev.index - 1]); } } else if (ev.event_type == "Merge") { // if (ev.index - 1 >= 0) //{ EventPoint ev2 = helper[ev.index - 1]; if (ev2.event_type == "Merge") { outLines.Add(new Line(ev.point, ev2.point)); } EventPoint prev = prev_event[ev.index]; T.Remove(prev); //} KeyValuePair <EventPoint, EventPoint> temp = new KeyValuePair <EventPoint, EventPoint>(T.DirectUpperAndLower(ev).Key, T.DirectUpperAndLower(ev).Value); if (temp.Value != null) { if (helper[temp.Value.index].event_type == "Merge") { outLines.Add(new Line(ev.point, helper[temp.Value.index].point)); } helper[temp.Value.index] = ev; } } else if (ev.event_type == "Split") { KeyValuePair <EventPoint, EventPoint> temp = new KeyValuePair <EventPoint, EventPoint>(T.DirectUpperAndLower(ev).Key, T.DirectUpperAndLower(ev).Value); if (temp.Value != null) { outLines.Add(new Line(ev.point, helper[temp.Value.index].point)); helper[temp.Value.index] = ev; } helper[ev.index] = ev; T.Add(ev); } else { var y = ev.edge.Y; if (ev.point.Y > y) { if (ev.index - 1 >= 0) { if (helper[ev.index - 1].event_type == "Merge") { outLines.Add(new Line(ev.point, helper[ev.index - 1].point)); } T.Remove(prev_event[ev.index]); } helper.Add(ev.index, ev); T.Add(ev); } else { KeyValuePair <EventPoint, EventPoint> temp = new KeyValuePair <EventPoint, EventPoint>(T.DirectUpperAndLower(ev).Key, T.DirectUpperAndLower(ev).Value); if (temp.Value != null) { if (helper[temp.Value.index].event_type == "Merge") { outLines.Add(new Line(ev.point, helper[temp.Value.index].point)); helper[temp.Value.index] = ev; } } } } Q.Remove(ev); } }
private void handleEvent(Event curEvent, OrderedSet<Event> L, OrderedSet<Event> Q, List<Point> outPoints) { switch (curEvent.pType) { case PointType.Start: { KeyValuePair<Event, Event> upLow = L.DirectUpperAndLower(curEvent); if (upLow.Key != null) checkIntersection(upLow.Key, curEvent, Q, outPoints); if (upLow.Value != null) checkIntersection(curEvent, upLow.Value, Q, outPoints); L.Add(curEvent); break; } case PointType.End: { KeyValuePair<Event, Event> upLow = L.DirectUpperAndLower(curEvent); if (upLow.Key != null && upLow.Value != null) checkIntersection(upLow.Key, upLow.Value, Q, outPoints); L.Remove(new Event(segments[curEvent.segIdx].Start, PointType.Start, curEvent.segIdx, null, null)); break; } case PointType.Intersection: { Event upup = L.DirectUpperAndLower(curEvent.upper).Key; Event lowlow = L.DirectUpperAndLower(curEvent.lower).Value; if (upup !=null) checkIntersection(upup, curEvent.lower, Q, outPoints); if (lowlow != null) checkIntersection(curEvent.upper,lowlow, Q, outPoints); L.Remove(curEvent.upper); L.Remove(curEvent.lower); curEvent.lower.point.X = curEvent.point.X;curEvent.lower.point.Y = curEvent.point.Y; curEvent.upper.point.X = curEvent.point.X; curEvent.upper.point.Y = curEvent.point.Y; L.Add(curEvent.upper); L.Add(curEvent.lower); break; } default: break; } }
public override void Run(List <CGUtilities.Point> points, List <CGUtilities.Line> lines, List <CGUtilities.Polygon> polygons, ref List <CGUtilities.Point> outPoints, ref List <CGUtilities.Line> outLines, ref List <CGUtilities.Polygon> outPolygons) { Event.lines = lines; OrderedSet <Event> Q = new OrderedSet <Event>(EventComparer.CompareX); OrderedSet <Event> L = new OrderedSet <Event>(EventComparer.CompareY); for (int i = 0; i < lines.Count; i++) { if (lines[i].Start > lines[i].End) { HelperMethods.Swap(lines[i].Start, lines[i].End); } Q.Add(new Event(lines[i].Start, i, Enums.EventType.StartPoint)); Q.Add(new Event(lines[i].End, i, Enums.EventType.EndPoint)); } while (Q.Count != 0) { Event e = Q.GetFirst(); Q.Remove(e); #region Start Point if (e.eventType == Enums.EventType.StartPoint) { Point intersection = null; if (HelperMethods.IsVertical(lines[e.index])) { IList <Event> toBeCompared = L.AsList(); for (int i = 0; i < toBeCompared.Count; i++) { intersection = HelperMethods.GetIntersection(lines[toBeCompared[i].index], lines[e.index]); if (intersection != null) { outPoints.Add(intersection); } } continue; } L.Add(e); KeyValuePair <Event, Event> KVP = L.DirectUpperAndLower(e); Event prev = KVP.Key; Event next = KVP.Value; if (prev != null) { intersection = HelperMethods.GetIntersection(lines[prev.index], lines[e.index]); if (intersection != null) { Q.Add(new Event(intersection, prev, e, Enums.EventType.Intersection)); } } if (next != null) { intersection = HelperMethods.GetIntersection(lines[e.index], lines[next.index]); if (intersection != null) { Q.Add(new Event(intersection, e, next, Enums.EventType.Intersection)); } } } #endregion #region End Point else if (e.eventType == Enums.EventType.EndPoint) { KeyValuePair <Event, Event> KVP = L.DirectUpperAndLower(e); Event prev = KVP.Key; Event next = KVP.Value; if (prev != null && next != null) { Point intersection = HelperMethods.GetIntersection(lines[prev.index], lines[next.index]); if (intersection != null) { Q.Add(new Event(intersection, prev, next, Enums.EventType.Intersection)); } } L.RemoveAll(p => p.index == e.index); } #endregion #region Intersection Point else { if (!outPoints.Contains(e.point)) { outPoints.Add(e.point); } Event prev = e.prev; Event next = e.next; Event prev_prev = L.DirectUpperAndLower(prev).Key; Event next_next = L.DirectUpperAndLower(next).Value; Point intersection = null; if (prev_prev != null) { intersection = HelperMethods.GetIntersection(lines[prev_prev.index], lines[next.index]); if (intersection != null) { Q.Add(new Event(intersection, prev_prev, next, Enums.EventType.Intersection)); } } if (next_next != null) { intersection = HelperMethods.GetIntersection(lines[prev.index], lines[next_next.index]); if (intersection != null) { Q.Add(new Event(intersection, prev, next_next, Enums.EventType.Intersection)); } } prev.point = next.point = e.point; L.RemoveAll(p => p.index == prev.index); L.RemoveAll(p => p.index == next.index); L.Add(next); L.Add(prev); } #endregion } }
public override void Run(List <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons) { HashSet <PointComparer> hashP = new HashSet <PointComparer>(); for (int i = 0; i < points.Count; ++i) { hashP.Add(new PointComparer(points[i])); } PointComparer[] res = hashP.ToArray(); points.Clear(); for (int i = 0; i < res.Length; ++i) { points.Add(res[i].p); } if (points.Count < 4) { outPoints = new List <Point>(points); return; } OrderedSet <LinkedListNode <Point> > S = new OrderedSet <LinkedListNode <Point> >(compS); if (!handleColinearCase(points)) { outPoints = new List <Point>(); outPoints.Add(points[0]); outPoints.Add(points[1]); return; } basePoint = centroid(points[0], points[1], points[2]); S.Add(new LinkedListNode <Point>(points[0])); S.Add(new LinkedListNode <Point>(points[1])); S.Add(new LinkedListNode <Point>(points[2])); LinkedList <Point> ll = new LinkedList <Point>(); ll.AddLast(S[0]); ll.AddLast(S[1]); ll.AddLast(S[2]); for (int i = 3; i < points.Count; ++i) { KeyValuePair <LinkedListNode <Point>, LinkedListNode <Point> > upLow = S.DirectUpperAndLower(new LinkedListNode <Point>(points[i])); LinkedListNode <Point> up = upLow.Key == null ? ll.First : upLow.Key; LinkedListNode <Point> low = upLow.Value == null ? ll.Last : upLow.Value; if (up.Value.Equals(points[i]) || low.Value.Equals(points[i])) { S.Add(ll.AddBefore(up, points[i])); LinkedListNode <Point> toBeRem = up.Value.Equals(points[i]) ? up : low; S.Remove(toBeRem); ll.Remove(toBeRem); } while (true) { if (HelperMethods.CheckTurn(new Line(low.Value, up.Value), points[i]) != Enums.TurnType.Right) { break; } LinkedListNode <Point> nextUp = up.Next == null ? ll.First : up.Next; Enums.TurnType turn = HelperMethods.CheckTurn(new Line(points[i], up.Value), nextUp.Value); if (turn != Enums.TurnType.Right) { if (upLow.Key == null) { S.Add(ll.AddLast(points[i])); } else { S.Add(ll.AddBefore(up, points[i])); } if (turn == Enums.TurnType.Colinear) { up = removeNodeUp(up, ll, S); } break; } else { up = removeNodeUp(up, ll, S); } } while (true) { if (HelperMethods.CheckTurn(new Line(low.Value, up.Value), points[i]) != Enums.TurnType.Right) { break; } LinkedListNode <Point> nextLow = low.Previous == null ? ll.Last : low.Previous; Enums.TurnType turn = HelperMethods.CheckTurn(new Line(points[i], low.Value), nextLow.Value); if (turn != Enums.TurnType.Right) { low = removeNodeLow(low, ll, S); } else { break; } } } outPoints = new List <Point>(); List <LinkedListNode <Point> > ls = new List <LinkedListNode <Point> >(S); for (int i = 0; i < ls.Count; ++i) { outPoints.Add(ls[i].Value); } }
public override void Run(List<Point> points, List<Line> lines, List<Polygon> polygons, ref List<Point> outPoints, ref List<Line> outLines, ref List<Polygon> outPolygons) { HashSet<PointComparer> hashP = new HashSet<PointComparer>(); for (int i = 0; i < points.Count; ++i) hashP.Add(new PointComparer(points[i])); PointComparer[] res = hashP.ToArray(); points.Clear(); for (int i = 0; i < res.Length; ++i) points.Add(res[i].p); if (points.Count < 4) { outPoints = new List<Point>(points); return; } OrderedSet<LinkedListNode<Point>> S = new OrderedSet<LinkedListNode<Point>>(compS); if (!handleColinearCase(points)) { outPoints = new List<Point>(); outPoints.Add(points[0]); outPoints.Add(points[1]); return; } basePoint = centroid(points[0], points[1], points[2]); S.Add(new LinkedListNode<Point>(points[0])); S.Add(new LinkedListNode<Point>(points[1])); S.Add(new LinkedListNode<Point>(points[2])); LinkedList<Point> ll = new LinkedList<Point>(); ll.AddLast(S[0]); ll.AddLast(S[1]); ll.AddLast(S[2]); for (int i = 3; i < points.Count; ++i) { KeyValuePair<LinkedListNode<Point>, LinkedListNode<Point>> upLow = S.DirectUpperAndLower(new LinkedListNode<Point>(points[i])); LinkedListNode<Point> up = upLow.Key == null ? ll.First : upLow.Key; LinkedListNode<Point> low = upLow.Value == null ? ll.Last : upLow.Value; if (up.Value.Equals(points[i]) || low.Value.Equals(points[i])) { S.Add(ll.AddBefore(up, points[i])); LinkedListNode<Point> toBeRem = up.Value.Equals(points[i]) ? up : low; S.Remove(toBeRem); ll.Remove(toBeRem); } while (true) { if (HelperMethods.CheckTurn(new Line(low.Value, up.Value), points[i]) != Enums.TurnType.Right) break; LinkedListNode<Point> nextUp = up.Next == null ? ll.First : up.Next; Enums.TurnType turn = HelperMethods.CheckTurn(new Line(points[i], up.Value), nextUp.Value); if (turn != Enums.TurnType.Right) { if (upLow.Key == null) S.Add(ll.AddLast(points[i])); else S.Add(ll.AddBefore(up, points[i])); if (turn == Enums.TurnType.Colinear) up = removeNodeUp(up, ll, S); break; } else up = removeNodeUp(up,ll,S); } while (true) { if (HelperMethods.CheckTurn(new Line(low.Value, up.Value), points[i]) != Enums.TurnType.Right) break; LinkedListNode<Point> nextLow = low.Previous == null ? ll.Last : low.Previous; Enums.TurnType turn = HelperMethods.CheckTurn(new Line(points[i], low.Value), nextLow.Value); if (turn != Enums.TurnType.Right) low = removeNodeLow(low, ll, S); else break; } } outPoints = new List<Point>(); List<LinkedListNode<Point>> ls = new List<LinkedListNode<Point>>(S); for (int i = 0; i < ls.Count; ++i) outPoints.Add(ls[i].Value); }
void HandleEvent() { KeyValuePair <Line, Line> UpperAndLower = L.DirectUpperAndLower(currentEvent.seg1); if (currentEvent.eventType == Enums.EventType.Start) { Line newSegment = currentEvent.seg1; L.Add(newSegment); if (UpperAndLower.Key != null) { Point intersectionPoint = CheckIntersection(newSegment, UpperAndLower.Key); if (intersectionPoint != null && intersectionPoint.X > currentEvent._point.X) { EventPoint newEvent = new EventPoint(intersectionPoint, Enums.EventType.Intersection, UpperAndLower.Key, newSegment); if (!Q.Contains(newEvent)) { Q.Add(newEvent); } } } if (UpperAndLower.Value != null) { Point intersectionPoint = CheckIntersection(newSegment, UpperAndLower.Value); if (intersectionPoint != null && intersectionPoint.X > currentEvent._point.X) { EventPoint newEvent = new EventPoint(intersectionPoint, Enums.EventType.Intersection, newSegment, UpperAndLower.Value); if (!Q.Contains(newEvent)) { Q.Add(newEvent); } } } } else if (currentEvent.eventType == Enums.EventType.End) { if (UpperAndLower.Key != null && UpperAndLower.Value != null) { Point intersectionPoint = CheckIntersection(UpperAndLower.Key, UpperAndLower.Value); if (intersectionPoint != null && intersectionPoint.X > currentEvent._point.X) { EventPoint newEvent = new EventPoint(intersectionPoint, Enums.EventType.Intersection, UpperAndLower.Key, UpperAndLower.Value); if (!Q.Contains(newEvent)) { Q.Add(newEvent); } } } L.Remove(currentEvent.seg1); } else if (currentEvent.eventType == Enums.EventType.Intersection) { intersections.Add(currentEvent._point); Line S1below = L.DirectUpperAndLower(currentEvent.seg1).Key; Line S2upper = L.DirectUpperAndLower(currentEvent.seg2).Value; if (S1below != null) { Point intersectionPoint = CheckIntersection(S1below, currentEvent.seg2); if (intersectionPoint != null && intersectionPoint.X > currentEvent._point.X) { EventPoint newEvent = new EventPoint(intersectionPoint, Enums.EventType.Intersection, S1below, currentEvent.seg2); if (!Q.Contains(newEvent)) { Q.Add(newEvent); } } } if (S2upper != null) { Point intersectionPoint = CheckIntersection(S2upper, currentEvent.seg1); if (intersectionPoint != null && intersectionPoint.X > currentEvent._point.X) { EventPoint newEvent = new EventPoint(intersectionPoint, Enums.EventType.Intersection, S2upper, currentEvent.seg1); if (!Q.Contains(newEvent)) { Q.Add(newEvent); } } } L.Remove(currentEvent.seg1); L.Remove(currentEvent.seg2); //currentEvent._point.X++; L.Add(currentEvent.seg1); L.Add(currentEvent.seg2); //currentEvent._point.X--; // L.Remove(currentEvent.seg1); // L.Remove(currentEvent.seg2); // L.Add(new Line(currentEvent._point,currentEvent.seg1.End)); // L.Add(new Line(currentEvent._point, currentEvent.seg2.End)); } }
public void HandleEvent(Event CurrentPoint, List <Line> lines, List <Line> lines2) { if (CurrentPoint.type == "s") { Event CurrentPointL = new Event(null, null, CurrentPoint.LineIndex, 0, lines[CurrentPoint.LineIndex], null); L.Add(CurrentPointL); Event tmp1 = L[0]; KeyValuePair <Event, Event> UpAndDown = L.DirectUpperAndLower(CurrentPointL); Point point; //upper with point if (UpAndDown.Key != null) { point = CheckIntersection(lines2[UpAndDown.Key.LineIndex], lines2[CurrentPoint.LineIndex]); if (point != null) { output.Add(point); E.Add(new Event(point, "i", CurrentPoint.LineIndex, UpAndDown.Key.LineIndex, lines[CurrentPoint.LineIndex], lines[UpAndDown.Key.LineIndex])); } } //lower with point if (UpAndDown.Value != null) { point = CheckIntersection(lines2[UpAndDown.Value.LineIndex], lines2[CurrentPoint.LineIndex]); if (point != null) { output.Add(point); E.Add(new Event(point, "i", CurrentPoint.LineIndex, UpAndDown.Value.LineIndex, lines[CurrentPoint.LineIndex], lines[UpAndDown.Value.LineIndex])); } } } else if (CurrentPoint.type == "e") { Event CurrentPointL = new Event(null, null, CurrentPoint.LineIndex, 0, lines[CurrentPoint.LineIndex], null); KeyValuePair <Event, Event> UpAndDown = L.DirectUpperAndLower(CurrentPointL); if (UpAndDown.Key != null && UpAndDown.Value != null) { Point point = CheckIntersection(lines2[UpAndDown.Key.LineIndex], lines2[UpAndDown.Value.LineIndex]); if (point != null) { output.Add(point); E.Add(new Event(point, "i", UpAndDown.Value.LineIndex, UpAndDown.Key.LineIndex, lines[UpAndDown.Value.LineIndex], lines[UpAndDown.Key.LineIndex])); } } L.Remove(CurrentPointL); } else { Line s1 = lines[CurrentPoint.LineIndex]; Line s2 = lines[CurrentPoint.OtherIndex]; int indexS1 = L.IndexOf(new Event(null, null, CurrentPoint.LineIndex, 0, lines[CurrentPoint.LineIndex], null)); int indexS2 = L.IndexOf(new Event(null, null, CurrentPoint.OtherIndex, 0, lines[CurrentPoint.OtherIndex], null)); if (indexS1 > indexS2) { Line tmp = s2; s2 = s1; s1 = tmp; int tmpi = CurrentPoint.LineIndex; CurrentPoint.LineIndex = CurrentPoint.OtherIndex; CurrentPoint.OtherIndex = tmpi; } KeyValuePair <Event, Event> UpAndDownS1 = L.DirectUpperAndLower(new Event(null, null, CurrentPoint.LineIndex, 0, s1, null)); KeyValuePair <Event, Event> UpAndDownS2 = L.DirectUpperAndLower(new Event(null, null, CurrentPoint.OtherIndex, 0, s2, null)); //s1 with upper of s2 if (UpAndDownS2.Key != null) { Point point1 = CheckIntersection(lines2[CurrentPoint.LineIndex], lines2[UpAndDownS2.Key.LineIndex]); if (point1 != null) { output.Add(point1); E.Add(new Event(point1, "i", CurrentPoint.LineIndex, UpAndDownS2.Key.LineIndex, s1, lines[UpAndDownS2.Key.LineIndex])); } } //s2 with lower s1 if (UpAndDownS1.Value != null) { Point point2 = CheckIntersection(lines2[CurrentPoint.OtherIndex], lines2[UpAndDownS1.Value.LineIndex]); if (point2 != null) { output.Add(point2); E.Add(new Event(point2, "i", CurrentPoint.OtherIndex, UpAndDownS1.Value.LineIndex, s2, lines[UpAndDownS1.Value.LineIndex])); } } //swap L.Remove(new Event(null, null, CurrentPoint.LineIndex, 0, s1, null)); L.Remove(new Event(null, null, CurrentPoint.OtherIndex, 0, s2, null)); L.Add(new Event(null, null, CurrentPoint.LineIndex, 0, new Line(CurrentPoint.point, s1.End), null)); L.Add(new Event(null, null, CurrentPoint.OtherIndex, 0, new Line(CurrentPoint.point, s2.End), null)); lines[CurrentPoint.LineIndex].Start = CurrentPoint.point; lines[CurrentPoint.OtherIndex].Start = CurrentPoint.point; } }
public override void Run(List <CGUtilities.Point> points, List <CGUtilities.Line> lines, List <CGUtilities.Polygon> polygons, ref List <CGUtilities.Point> outPoints, ref List <CGUtilities.Line> outLines, ref List <CGUtilities.Polygon> outPolygons) { var Q = new OrderedSet <Event>(Comparer <Event> .Create((Event a, Event b) => { if (a.point.X != b.point.X) { return(a.point.X.CompareTo(b.point.X)); } if (a.point.Y != b.point.Y) { return(a.point.Y.CompareTo(b.point.Y)); } return(lines[a.index].End.X.CompareTo(lines[b.index].End.X)); })); var L = new OrderedSet <Event>(Comparer <Event> .Create((Event a, Event b) => { if (a.point.Y != b.point.Y) { return(a.point.Y.CompareTo(b.point.Y)); } if (a.point.X != b.point.X) { return(a.point.X.CompareTo(b.point.X)); } return(lines[a.index].End.Y.CompareTo(lines[b.index].End.Y)); })); lines.Enumerate((l, i) => { if (l.Start.X > l.End.X) { var tmp = l.Start; l.Start = l.End; l.Start = tmp; } Q.Add(new Event(l.Start, i, EventType.START)); Q.Add(new Event(l.End, i, EventType.END)); }); while (Q.Count > 0) { var curEvent = Q.GetFirst(); Q.Remove(curEvent); if (curEvent.eventType == EventType.START) { L.Add(curEvent); var(prevEvent, nextEvent) = L.DirectUpperAndLower(curEvent); if (prevEvent != null) { var(prevLine, curLine) = (lines[prevEvent.index], lines[curEvent.index]); if (HelperMethods.CheckSegmentsIntersections(prevLine, curLine)) { var interPoint = HelperMethods.GetIntersectionPoint(prevLine, curLine); Q.Add(new Event(interPoint, prevEvent, curEvent, EventType.INTERS)); outPoints.Add(interPoint); } } if (nextEvent != null) { var(nextLine, curLine) = (lines[nextEvent.index], lines[curEvent.index]); if (HelperMethods.CheckSegmentsIntersections(nextLine, curLine)) { var interPoint = HelperMethods.GetIntersectionPoint(nextLine, curLine); Q.Add(new Event(interPoint, curEvent, nextEvent, EventType.INTERS)); outPoints.Add(interPoint); } } } if (curEvent.eventType == EventType.END) { var(prevEvent, nextEvent) = L.DirectUpperAndLower(curEvent); if (prevEvent != null && nextEvent != null) { var(prevLine, nextLine) = (lines[prevEvent.index], lines[nextEvent.index]); if (HelperMethods.CheckSegmentsIntersections(prevLine, nextLine)) { var interPoint = HelperMethods.GetIntersectionPoint(prevLine, nextLine); Q.Add(new Event(interPoint, prevEvent, nextEvent, EventType.INTERS)); outPoints.Add(interPoint); } L.Remove(curEvent); } } if (curEvent.eventType == EventType.INTERS) { var(pEvent, nEvent) = (curEvent.prev, curEvent.next); var ppEvent = L.DirectUpperAndLower(pEvent).prev; if (ppEvent != null) { var(prevLine, nextLine) = (lines[ppEvent.index], lines[nEvent.index]); if (HelperMethods.CheckSegmentsIntersections(prevLine, nextLine)) { var interPoint = HelperMethods.GetIntersectionPoint(prevLine, nextLine); Q.Add(new Event(interPoint, ppEvent, nEvent, EventType.INTERS)); outPoints.Add(interPoint); } } var nnEvent = L.DirectUpperAndLower(nEvent).next; if (nnEvent != null) { var(prevLine, nextLine) = (lines[pEvent.index], lines[nnEvent.index]); if (HelperMethods.CheckSegmentsIntersections(prevLine, nextLine)) { var interPoint = HelperMethods.GetIntersectionPoint(prevLine, nextLine); Q.Add(new Event(interPoint, pEvent, nnEvent, EventType.INTERS)); outPoints.Add(interPoint); } } pEvent.point = nEvent.point = curEvent.point; L.RemoveAll(p => p.index == pEvent.index || p.index == nEvent.index); L.Add(nEvent); L.Add(pEvent); } } }
public override void Run(List <CGUtilities.Point> points, List <CGUtilities.Line> lines, List <CGUtilities.Polygon> polygons, ref List <CGUtilities.Point> outPoints, ref List <CGUtilities.Line> outLines, ref List <CGUtilities.Polygon> outPolygons) { OrderedSet <Event> sweep_line = new OrderedSet <Event>(new Comparison <Event>(sweep_line_compare)); OrderedSet <Event> events = new OrderedSet <Event>(); // get the events for (int i = 0; i < lines.Count; i++) { Point start = lines[i].Start; Point end = lines[i].End; if (start.CompareTo(end) == 1) { // swap ends of the line lines[i].Start = end; lines[i].End = start; } // what if we have a degenerate line Event beginp = new Event(lines[i].Start, lines[i].End, 0, i, -1); // begin Event endp = new Event(lines[i].End, lines[i].Start, 1, i, -1); // end events.Add(beginp); events.Add(endp); } // sweep left to right OrderedSet <Point> inter_points = new OrderedSet <Point>(); while (events.Count != 0) { Event tevent = events.GetFirst(); events.RemoveFirst(); int line_index1 = tevent.line_index1; int line_index2 = tevent.line_index2; double current_x = lines[line_index1].Start.X; if (tevent.event_type == 0) // start { sweep_line.Add(tevent); KeyValuePair <Event, Event> UL = sweep_line.DirectUpperAndLower(tevent); // intersection between the smaller , bigger if (UL.Key != null) { get_inter(tevent, UL.Key, ref inter_points, ref events, current_x); } if (UL.Value != null) { get_inter(UL.Value, tevent, ref inter_points, ref events, current_x); } } else if (tevent.event_type == 1) // end { // edit the event so we can match // potional bug Point tpoint = tevent.start; tevent.start = tevent.end; tevent.end = tpoint; tevent.event_type = 0; KeyValuePair <Event, Event> UL = sweep_line.DirectUpperAndLower(tevent); sweep_line.Remove(tevent); // potional bug // smaller - bigger if (UL.Key != null && UL.Value != null) { get_inter(UL.Value, UL.Key, ref inter_points, ref events, current_x); } } else // intersection { // don't change the original line // smaller, bigger Line line1 = lines[line_index1].Clone() as Line; Line line2 = lines[line_index2].Clone() as Line; // get events Event event1 = new Event(line1.Start, line1.End, 0, line_index1, -1); Event event2 = new Event(line2.Start, line2.End, 0, line_index2, -1); // remove them from the sweep line tree sweep_line.Remove(event1); sweep_line.Remove(event2); // put the intersecction point as the start point = swap them in order event1.start = tevent.start; event2.start = tevent.start; // insert them back again sweep_line.Add(event1); sweep_line.Add(event2); // ****** potional bug ****** // get the upper and lower for line 1 , line 2 respectivally KeyValuePair <Event, Event> ULE1 = sweep_line.DirectUpperAndLower(event1); KeyValuePair <Event, Event> ULE2 = sweep_line.DirectUpperAndLower(event2); // check event 1 with it's upper if (ULE1.Key != null) { get_inter(event1, ULE1.Key, ref inter_points, ref events, current_x); //get_inter(event2, ULE1.Key, ref inter_points, ref events, current_x); } // check event2 with it's lower if (ULE2.Value != null) { get_inter(event2, ULE2.Value, ref inter_points, ref events, current_x); //get_inter(ULE2.Value, event1,ref inter_points, ref events, current_x); } } } // get points while (inter_points.Count != 0) { outPoints.Add(inter_points.GetFirst()); inter_points.RemoveFirst(); } }