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