예제 #1
0
		private void Tock (Object state)
		{
			List<IMinion> toDo = new List<IMinion> ();
			lock (this.capsules) {
				long t = tick++;
				if (capsules.Count == 0)
					return;
				ICapsule c = capsules.GetFirst ();
				IMinion m = c.GetReadiedMinion (t);
				while (m != null) {
					Console.WriteLine ("{0}\t Playing: {1}", t, m);
					capsules.Remove (c);
					if (t == 24) {
						Console.WriteLine ("----- Popped: {0} {1}", c.GetTicksToStart (), capsules);

					}
					if (!c.CanDispose ()) {
						// Sorted to the new start tick
						capsules.Add (c);
					}

					if (t == 24) {
						Console.WriteLine ("------ Reorg: {0} {1}", c.GetTicksToStart (), capsules);

					}
					toDo.Add (m);
					if (capsules.Count == 0)
						break;
					c = capsules.GetFirst ();
					m = c.GetReadiedMinion (t);
				}
			}
			//taskMaster.Invoke (toDo);
		}
예제 #2
0
        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)
        {
            P = polygons[0];
            Q = new OrderedSet <Event>(new Comparison <Event>(PriorityQueueComp));
            T = new OrderedSet <Event>(new Comparison <Event>(T_mode));


            for (int i = 0; i < P.lines.Count; i++)
            {
                Event ev = new Event(P.lines[i].Start, getVertexType(i), i);
                Q.Add(ev);
            }

            SweepLinePositionY = Q.GetFirst().vertix.Y;

            while (Q.Count > 0)
            {
                Event ev = Q.GetFirst();
                SweepLinePositionY = Q.GetFirst().vertix.Y;
                Q.RemoveFirst(); //pop

                if (ev.type == vertexType.Start)
                {
                    HandleStart(ev);
                }
                else if (ev.type == vertexType.End)
                {
                    HandleEnd(ev);
                }
                else if (ev.type == vertexType.Split)
                {
                    HandleSplit(ev);
                }
                else if (ev.type == vertexType.Merge)
                {
                    HandleMerge(ev);
                }
                else if (ev.type == vertexType.Regular)
                {
                    HandleRegular(ev);
                }
            }

            foreach (Line l in output)
            {
                outLines.Add(l);
            }
        }
예제 #3
0
    public List <Node> AStarPath(Node _start, Node _goal)
    {
        start = _start;
        goal  = _goal;

        while (open.Count != 0)
        {
            current = open.GetFirst();
            if (current == goal)
            {
                return(RecoverPath(current));
            }
            open.RemoveFirst();
            closed.Add(current);

            foreach (Node neighbor in current.neighbors)
            {
                if (neighbor == null)
                {
                    continue;
                }
                if (closed.Contains(neighbor)) //evaluated
                {
                    continue;
                }
                float new_g = current.g + DistCost(current, neighbor);
                if (new_g < neighbor.g)
                {
                    neighbor.parent = current;
                    neighbor.g      = new_g;
                    neighbor.CalcF();
                }
                if (!open.Contains(neighbor))   //not added
                {
                    if (neighbor == goal)
                    {
                        Debug.Log(neighbor.parent);
                    }
                    open.Add(neighbor);
                }
            }
        }
        Debug.LogError("No path found.");
        return(null);
    }
예제 #4
0
    private static long FindMinSpanningTreeSum(Node<char> startingNode, int nodesCount)
    {
        HashSet<char> visitedNodes = new HashSet<char>();
        OrderedSet<Connection<char>> connections = new OrderedSet<Connection<char>>();
        long currentSum = 0;
        visitedNodes.Add(startingNode.Symbol);

        foreach (var connection in startingNode.Connections)
        {
            if (!visitedNodes.Contains(connection.toNode.Symbol))
            {
                connections.Add(connection);
            }
        }

        while (connections.Count > 0)
        {
            Connection<char> currentConnection = connections.GetFirst();
            connections.RemoveFirst();
            Node<char> currentNode = currentConnection.toNode;

            if (!visitedNodes.Contains(currentNode.Symbol))
            {
                currentSum += currentConnection.Distance;
            }

            visitedNodes.Add(currentNode.Symbol);
            if (visitedNodes.Count == nodesCount)
            {
                break;
            }

            foreach (var connection in currentNode.Connections)
            {
                if (!visitedNodes.Contains(connection.toNode.Symbol))
                {
                    connections.Add(connection);
                }
            }
        }

        return currentSum;
    }
예제 #5
0
        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 <Point> points, List <Line> lines, List <Polygon> polygons, ref List <Point> outPoints, ref List <Line> outLines, ref List <Polygon> outPolygons)
        {
            #region Sort_Polygon_CCW
            /// First at all we must check That polygon is sorted CCW
            List <Point> poly_input = new List <Point>();
            int          size       = polygons[0].lines.Count;
            for (int i = 0; i < size; i++)
            {
                Point p = polygons[0].lines[i].Start;
                if (p.X <= mini_x.X)
                {
                    if (p.X < mini_x.X)
                    {
                        mini_x          = p;
                        index_of_mini_x = i;
                    }

                    else if (p.Y < mini_x.Y)
                    {
                        mini_x          = p;
                        index_of_mini_x = i;
                    }
                }
                poly_input.Add(p);
            }

            bool Points_sorted_CCW = HelperMethods.IS_points_Sorted_CCW(mini_x, index_of_mini_x, poly_input);

            // if points were sorted CC then Resort them to be CCW
            if (Points_sorted_CCW == false)
            {
                /*    for (int i = 0; i < polygons[0].lines.Count; i++)
                 *  {
                 *      Point temp = polygons[0].lines[i].Start;
                 *
                 *      polygons[0].lines[i].Start = polygons[0].lines[i].End;
                 *      polygons[0].lines[i].End = temp;
                 *
                 *  }
                 */polygons[0].lines.Reverse();
                poly_input.Reverse();
            } // Now we have ploygon sorted CCW

            #endregion

            #region Sorted_AND_Calssified
            // Step 1 : Sort and Calssify each point , and fill list Sorted_AND_Calssified_points
            Comparison <smart_point_Monotone_Partion> comp = new Comparison <smart_point_Monotone_Partion>(Sort_Polygon);
            Sorted_AND_Calssified_points = new OrderedSet <smart_point_Monotone_Partion>(comp);



            // Step 1.1 :: sort points based on y_axis
            for (int i = 0; i < size; i++)
            {
                Point p    = polygons[0].lines[i].Start;
                Line  pre  = polygons[0].lines[getPrevIndex(i, size)];
                Line  next = polygons[0].lines[getNextIndex(i, size)];

                Sorted_AND_Calssified_points.Add(new smart_point_Monotone_Partion(i, p, "", pre, next));
            } //end of for loop

            int index = Sorted_AND_Calssified_points[0].id;
            // Step 1.2 :: classify each point
            for (int i = 0; i < size; i++)
            {
                Point p  = Sorted_AND_Calssified_points[i].current_point;
                int   id = Sorted_AND_Calssified_points[i].id;
                Sorted_AND_Calssified_points[i].Type = Classify_point(p, id, poly_input);
            }
            #endregion

            #region Monotone_partitioning_Algorithm

            OrderedSet <smart_edge> SweepLine = new OrderedSet <smart_edge>(new Comparison <smart_edge>(Sort_Sweep_line));
            for (int i = 0; i < size; i++)
            {
                smart_point_Monotone_Partion V = Sorted_AND_Calssified_points[i];
                #region HandleStartVertex
                if (V.Type == "start")
                {
                    SweepLine.Add(new smart_edge(V.next_line, V.id, V));
                }
                #endregion

                #region HandleEndVertex
                else if (V.Type == "end")
                {
                    Line prev = V.prev_line;

                    for (int e = 0; e < SweepLine.Count; e++)
                    {
                        if (SweepLine[e].edge_values.Equals(prev))
                        {
                            if (SweepLine[e].helper.Equals("merge"))
                            {
                                outLines.Add(new Line(SweepLine[e].helper.current_point, V.current_point));
                            }
                            SweepLine.Remove(SweepLine[e]);
                        }
                    }
                }

                #endregion

                #region HandleSplitVertex
                else if (V.Type.Equals("split"))
                {
                    smart_edge most_left_adge = SweepLine.GetFirst();
                    outLines.Add(new Line(V.current_point, most_left_adge.helper.current_point));
                    most_left_adge.helper = V;
                    SweepLine.Add(new smart_edge(V.next_line, V.id, V));
                }
                #endregion

                #region HandleMergeVertex
                else if (V.Type.Equals("merge"))
                {
                    Line prev = V.prev_line;
                    for (int e = 0; e < SweepLine.Count; e++)
                    {
                        if (SweepLine[e].edge_values.Equals(prev))
                        {
                            if (SweepLine[e].helper.Type.Equals("merge"))
                            {
                                outLines.Add(new Line(V.current_point, SweepLine[e].helper.current_point));
                            }
                            SweepLine.Remove(SweepLine[e]);
                        }
                    }

                    smart_edge most_left = SweepLine.GetFirst();
                    if (most_left.helper.Type.Equals("merge"))
                    {
                        outLines.Add(new Line(V.current_point, most_left.helper.current_point));
                    }
                    most_left.helper = V;
                }
                #endregion

                #region HandleRegularVertex
                else
                {
                    #region HandleRegularLeft
                    if (V.Type.Equals("regular_left"))
                    {
                        Line prev = V.prev_line;
                        for (int e = 0; e < SweepLine.Count; e++)
                        {
                            if (SweepLine[e].edge_values.Equals(prev))
                            {
                                if (SweepLine[e].helper.Type.Equals("merge"))
                                {
                                    outLines.Add(new Line(V.current_point, SweepLine[e].helper.current_point));
                                }
                                SweepLine.Remove(SweepLine[e]);
                                SweepLine.Add(new smart_edge(V.next_line, V.id, V));
                            }
                        }
                    }
                    #endregion

                    #region HnadleRegularRight
                    else if (V.Type.Equals("regular_right"))
                    {
                        smart_edge most_left = SweepLine.GetFirst();
                        if (most_left.helper.Type.Equals("merge"))
                        {
                            outLines.Add(new Line(V.current_point, most_left.helper.current_point));
                        }
                        most_left.helper = V;
                    }
                    #endregion
                }
                #endregion
            }
            #endregion
        } //end of run
예제 #7
0
        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 <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);
                }
            }
        }
예제 #9
0
        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();
            }
        }