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)
        {
            B = new Point(((points[0].X + points[1].X + points[2].X) / 3), ((points[0].Y + points[1].Y + points[2].Y) / 3));

            Point NB = new Point(B.X + 5, B.Y);

            Base_Line = new Line(B, NB);


            /*
             * // step 1 :: find minimum point in Y Axis
             * minimumY = points[0]; ; // any intial value
             * for (int i = 0; i < points.Count(); i++)
             * {
             *  if (points[i].Y < minimumY.Y)
             *  {
             *      minimumY = points[i];
             *      index_of_mini_Y = i;
             *  }
             *
             *  else if (points[i].Y == minimumY.Y)
             *  {
             *      if (points[i].X < minimumY.X)
             *      {
             *          minimumY = points[i];
             *          index_of_mini_Y = i;
             *      }
             *  }
             * }
             *
             * // Get Base_line
             * Base_Line.Start = minimumY;
             * Point End = new Point(minimumY.X + 5, minimumY.Y);
             * Base_Line.End = End;
             *
             *
             */

            // Comparison<Point> comp = new Comparison<Point>(compare_angle);
            OrderedSet <Point> CH = new OrderedSet <Point>(compare_angle);


            // CH.add(Points[0], Points[1], Points[2]);
            CH.Add(points[0]);
            CH.Add(points[1]);
            CH.Add(points[2]);

            Point p = points[0];                       // any intial value
            Point p_Prev, p_next;
            Line  l1 = new Line(points[0], points[1]); // any intial value

            for (int i = 3; i < points.Count(); i++)
            {
                p = points[i];
                //KeyValuePair<Point, Point> prevANDnext = CH.DirectRightAndLeftRotational(p);
                p_Prev = CH.DirectRightAndLeftRotational(p).Value;
                p_next = CH.DirectRightAndLeftRotational(p).Key;


                l1.Start = p_Prev;
                l1.End   = p_next;
                if (HelperMethods.CheckTurn(l1, p) == Enums.TurnType.Right) // Outside the polygon
                {
                    //KeyValuePair<Point, Point> prevANDnext_2 = CH.DirectRightAndLeftRotational(p_Prev);
                    Point New_pre = CH.DirectRightAndLeftRotational(p_Prev).Value;


                    l1.Start = p;
                    l1.End   = p_Prev;
                    while (HelperMethods.CheckTurn(l1, New_pre) == Enums.TurnType.Left)
                    {
                        CH.Remove(p_Prev);
                        //left support part
                        p_Prev  = New_pre;
                        New_pre = CH.DirectRightAndLeftRotational(p_Prev).Value;

                        l1.Start = p;
                        l1.End   = p_Prev;
                    } // end of while Left   Supporting Line

                    Point New_next = CH.DirectRightAndLeftRotational(p_next).Key;

                    l1.Start = p;
                    l1.End   = p_next;
                    while (HelperMethods.CheckTurn(l1, New_next) == Enums.TurnType.Right)
                    {
                        CH.Remove(p_next);
                        p_next   = New_next;
                        New_next = CH.DirectRightAndLeftRotational(p_next).Key;


                        l1.Start = p;
                        l1.End   = p_next;
                    } // // end of while Right  Supporting Line
                    // leave Pre and Next but delete the points between them
                    CH.Add(p);
                } // end of ( if condtion :: --->> point outside the triangle
            }     // end of for loop
            outPoints = CH.ToList();
        }
Beispiel #2
0
        public void HandleEvent(Event current_Event)
        {
            if (current_Event.status == 0) //StartEvent
            {
                /*
                 * 1- Insert currentEvent in L.
                 *    L.Add( new Event(null, type= StartPoint, currentSegment.segmentIndex)
                 *
                 * 2. CheckIntersection( L.prev(currentSegment), currentSegment).
                 *
                 * 3. CheckIntersection( currentSegment, L.next(currentSegment)).
                 */
                int index_of_current_Event_AS_line = current_Event.L1_index;
                //1- Insert currentEvent in L.   L.Add( new Event(null, type= StartPoint, currentSegment.segmentIndex)

                L_SweepLine_Ordered_SET.Add(new Event(current_Event.Current_Point, 0, index_of_current_Event_AS_line, 0));

                // 2. CheckIntersection( L.prev(currentSegment), currentSegment).
                //  int index_of_current_Event_AS_line = current_Event.L1_index;
                Line current_Event_AS_line = copy_OF_input_lines[index_of_current_Event_AS_line];

                int  index_Prev_of_currentEvent = L_SweepLine_Ordered_SET.DirectRightAndLeftRotational(current_Event).Value.L1_index;
                Line Prev_of_currentEvent       = copy_OF_input_lines[index_Prev_of_currentEvent];

                bool check_intersection_between_currEvnet_AND_prev = HelperMethods.doIntersect_between_2_Segments(Prev_of_currentEvent, current_Event_AS_line);
                if (check_intersection_between_currEvnet_AND_prev == true)
                {
                    // if ther is intersection between currEvnet AND previous then calculate the cordinates of point of intersection
                    // AND add this point to  the output points (( intersection_points_list )) so that they appear on the UI and the test cases.
                    // AND also add it to Q_Ordered_SET_EventPoints as these points will be future Events that need to be handled
                    bool  infinty_intersection_point = true;
                    Point intersection_point         = HelperMethods.Get_intersection_point_cordinates(Prev_of_currentEvent, current_Event_AS_line, ref infinty_intersection_point);
                    if (infinty_intersection_point == false)  //mean that the get_intersection function return an infinity
                    {
                        intersection_points_list.Add(intersection_point);

                        Event intersection_Event = new Event(intersection_point, 2, index_of_current_Event_AS_line, index_Prev_of_currentEvent);
                        Q_Ordered_SET_EventPoints.Add(intersection_Event);
                    }
                }
                // * 3. CheckIntersection( currentSegment, L.next(currentSegment)).
                int  index_Next_of_currentEvent = L_SweepLine_Ordered_SET.DirectRightAndLeftRotational(current_Event).Key.L1_index;
                Line Next_of_currentEvent       = copy_OF_input_lines[index_Next_of_currentEvent];

                bool check_intersection_between_currEvnet_AND_Next = HelperMethods.doIntersect_between_2_Segments(Next_of_currentEvent, current_Event_AS_line);
                if (check_intersection_between_currEvnet_AND_Next == true)
                {
                    // if ther is intersection between currEvnet AND Next then calculate the cordinates of point of intersection
                    // AND add this point to  the output points (( intersection_points_list )) so that they appear on the UI and the test cases.
                    // AND also add it to Q_Ordered_SET_EventPoints as these points will be future Events that need to be handled
                    bool  infinty_intersection_point = true;
                    Point intersection_point         = HelperMethods.Get_intersection_point_cordinates(Next_of_currentEvent, current_Event_AS_line, ref infinty_intersection_point);
                    if (infinty_intersection_point == false)    //mean that the get_intersection function return an infinity
                    {
                        intersection_points_list.Add(intersection_point);

                        Event intersection_Event = new Event(intersection_point, 2, index_of_current_Event_AS_line, index_Next_of_currentEvent);
                        Q_Ordered_SET_EventPoints.Add(intersection_Event);
                    }
                }
            } // end of StartEvent

            else if (current_Event.status == 1)
            {
                /*EndEvent:
                 *          1 . CheckIntersection( L.prev(currentSegment), L.next(currentSegment) ).
                 *          2. Delete currentEvent from L.
                 *          // 1) Add the intersection points (if exists) in the output points so that they appear on the
                 *          UI and the test cases.
                 *          // 2) Now L has passed over this segment and we are sure there is no more intersections
                 *          with this segment, so remove the current segment from L*/

                //            1 . CheckIntersection( L.prev(currentSegment), L.next(currentSegment) ).
                // 1) Add the intersection points (if exists) in the output points so that they appear on the UI and the test cases.


                int  index_Prev_of_currentEvent = L_SweepLine_Ordered_SET.DirectRightAndLeftRotational(current_Event).Value.L1_index;
                Line Prev_of_currentEvent       = copy_OF_input_lines[index_Prev_of_currentEvent];

                int  index_Next_of_currentEvent = L_SweepLine_Ordered_SET.DirectRightAndLeftRotational(current_Event).Key.L1_index;
                Line Next_of_currentEvent       = copy_OF_input_lines[index_Next_of_currentEvent];

                bool check_intersection_between_Next_AND_prev = HelperMethods.doIntersect_between_2_Segments(Prev_of_currentEvent, Next_of_currentEvent);
                if (check_intersection_between_Next_AND_prev == true)
                {
                    // if ther is intersection between currEvnet Next AND previous then calculate the cordinates of point of intersection
                    // AND add this point to  the output points (( intersection_points_list )) so that they appear on the UI and the test cases.
                    // and also add it to Q_Ordered_SET_EventPoints
                    bool  infinty_intersection_point = true;
                    Point intersection_point         = HelperMethods.Get_intersection_point_cordinates(Prev_of_currentEvent, Next_of_currentEvent, ref infinty_intersection_point);
                    if (infinty_intersection_point == false)  //mean that the get_intersection function return an infinity
                    {
                        intersection_points_list.Add(intersection_point);

                        Event intersection_Event = new Event(intersection_point, 2, index_Prev_of_currentEvent, index_Next_of_currentEvent);
                        Q_Ordered_SET_EventPoints.Add(intersection_Event);
                    }
                }

                // 2. Delete currentEvent from L.
                // 2) Now L has passed over this segment and we are sure there is no more intersections with this segment, so remove the current segment from L

                L_SweepLine_Ordered_SET.Remove(current_Event);
            }//end of EndEvent

            else if (current_Event.status == 2)
            {
                /*1 . Find s1 & s2 are the segment intersecting together (s1 below s2).
                 *      2. CheckIntersection( L.prev(s1), s2 )).
                 *      3. CheckIntersection( L.next(s2), s1))
                 *      4. Swap s1 and s2 in L.
                 *      // 1) Store another index in the class of Event that refer to the other segment
                 *      intersecting with the point.
                 *      // 2) To swap 2 events, e1 and e2, remove them from the sweepLine and assign the
                 *      start of each segment of them to the intersection point and reinsert them in the
                 *      sweepLine. The comparison passed to the sweepLine function will find them having
                 *      the same x and the same y in their start point, and will check their ends and return the
                 *      end with the higher Y (and lower X in case of a tie))
                 *      //3) Add the intersection points (if exists) in the output points so that they appear on
                 *      the UI and the test cases.
                 */

                //1 . Find s1 & s2 are the segment intersecting together (s1 below s2).
                // 1) Store another index in the class of Event that refer to the other segment intersecting with the point.

                Line S1 = copy_OF_input_lines[current_Event.L1_index];
                Line S2 = copy_OF_input_lines[current_Event.L2_index];


                //        2. CheckIntersection( L.prev(s1), s2 )).

                Event New_S1  = new Event(current_Event.Current_Point, 0, current_Event.L1_index, 0);
                Event Prev_S1 = L_SweepLine_Ordered_SET.DirectRightAndLeftRotational(New_S1).Value;


                Line Prev_S1_AS_line = copy_OF_input_lines[Prev_S1.L1_index];
                bool intersection_between_PrevS1_AND_S2 = HelperMethods.doIntersect_between_2_Segments(Prev_S1_AS_line, S2);
                if (intersection_between_PrevS1_AND_S2 == true)
                {
                    // add this point to  the output points (( intersection_points_list )) so that they appear on the UI and the test cases.
                    // and also add it to Q_Ordered_SET_EventPoints
                    bool  infinty_intersection_point = true;
                    Point intersection_point         = HelperMethods.Get_intersection_point_cordinates(Prev_S1_AS_line, S2, ref infinty_intersection_point);
                    if (infinty_intersection_point == false) //mean that the get_intersection function return an infinity
                    {
                        if (intersection_point.X > current_Event.Current_Point.X)
                        {
                            intersection_points_list.Add(intersection_point);

                            Event intersection_Event = new Event(intersection_point, 2, Prev_S1.L1_index, current_Event.L2_index);
                            Q_Ordered_SET_EventPoints.Add(intersection_Event);
                        }
                    }
                }

                //        3. CheckIntersection( L.next(s2), s1))
                Event New_s2  = new Event(current_Event.Current_Point, 0, current_Event.L2_index, 0);
                Event Next_S2 = L_SweepLine_Ordered_SET.DirectRightAndLeftRotational(New_s2).Key;

                Line Next_s2_as_line = copy_OF_input_lines[Next_S2.L1_index];
                bool intersection_between_NextS2_AND_S1 = HelperMethods.doIntersect_between_2_Segments(Next_s2_as_line, S1);
                if (intersection_between_NextS2_AND_S1 == true)
                {
                    // add this point to  the output points (( intersection_points_list )) so that they appear on the UI and the test cases.
                    // and also add it to Q_Ordered_SET_EventPoints
                    bool  infinty_intersection_point = true;
                    Point intersection_point         = HelperMethods.Get_intersection_point_cordinates(Next_s2_as_line, S1, ref infinty_intersection_point);
                    if (infinty_intersection_point == false)  //mean that the get_intersection function return an infinity
                    {
                        if (intersection_point.X > current_Event.Current_Point.X)
                        {
                            intersection_points_list.Add(intersection_point);

                            Event intersection_Event = new Event(intersection_point, 2, Next_S2.L1_index, current_Event.L1_index);
                            Q_Ordered_SET_EventPoints.Add(intersection_Event);
                        }
                    }
                }

                //4. Swap s1 and s2 in L.

                /* To swap 2 events, e1 and e2, remove them from the sweepLine and assign the
                 *  start of each segment of them to the intersection point and reinsert them in the
                 *  sweepLine. The comparison passed to the sweepLine function will find them having
                 *  the same x and the same y in their start point, and will check their ends and return the
                 *  end with the higher Y (and lower X in case of a tie))*/



                L_SweepLine_Ordered_SET.Remove(New_S1);
                L_SweepLine_Ordered_SET.Remove(New_s2);

                New_S1.Current_Point = current_Event.Current_Point;
                //New_S1.L1_index = New_s2.L1_index;

                New_s2.Current_Point = current_Event.Current_Point;
                //  New_s2.L1_index = New_S1.L1_index;

                L_SweepLine_Ordered_SET.Add(New_S1);
                L_SweepLine_Ordered_SET.Add(New_s2);
            } //end of intersectionEvent
        }     // end of HandleEvent Function