private static void FindNewEvent(Segment s1, Segment s2, EventPoint eventPoint, RBTreeMap <EventPoint, LinkedList <Segment> > eventQueue) { //If two segments intersect below the sweep line, or on it and //to the right of the current event point, and the intersection //is not yet present as an event in Q: //then insert a new event point in Q for this intersection VecRat2 pointIntersection = new VecRat2(); SegRat2 segmentIntersection = new SegRat2(); //bool intersectionExists = Segment.ComputeIntersection(s1, s2, out pointIntersection); //if (intersectionExists) SegmentIntersectionType result = GeomAid.SegmentIntersection(s1.ToSegRat2(), s2.ToSegRat2(), ref pointIntersection, ref segmentIntersection); if (result == SegmentIntersectionType.Point) { EventPoint newEventPoint = new EventPoint(null); newEventPoint.Position = pointIntersection; if (eventPoint.CompareTo(newEventPoint) < 0 && !eventQueue.ContainsKey(newEventPoint)) { LinkedList <Segment> upperList = new LinkedList <Segment>(); eventQueue.Add(new RBTreeMapNode <EventPoint, LinkedList <Segment> >(newEventPoint, upperList)); } } else if (result == SegmentIntersectionType.Segment) { throw new NotImplementedException("Didn't think this would ever happen?!"); } }
public LineProjectionTransform(SegRat2 s) { this.anchor = s.A; this.dir = s.AB(); this.dot_anchor = dir * anchor; this.inv_dir_len_sq = 1 / dir.LengthSquared(); }
public static SegmentIntersectionType ColinearSegmentIntersection(SegRat2 s, SegRat2 t, ref VecRat2 pointIntersection, ref SegRat2 segmentIntersection) { //This check is important for handling degenerate cases like s = [(x,y), (x,y)). if (s.IsEmpty() || t.IsEmpty()) { return(SegmentIntersectionType.None); } //This check is important because the LineProjectionTransform can only be formed with a non-point segment. if (s.IsPoint()) { if (ColinearPointInSegment(s.A, t)) { pointIntersection = s.A; return(SegmentIntersectionType.Point); } else { return(SegmentIntersectionType.None); } } LineProjectionTransform transform = new LineProjectionTransform(s); SegRat1 proj_s = transform.Project(s); SegRat1 proj_t = transform.Project(t); Rational proj_pointIntersection = new Rational(); SegRat1 proj_segmentIntersection = new SegRat1(); SegmentIntersectionType result = SegmentIntersection( proj_s, proj_t, ref proj_pointIntersection, ref proj_segmentIntersection); if (result == SegmentIntersectionType.Point) { pointIntersection = transform.Unproject(proj_pointIntersection); } else if (result == SegmentIntersectionType.Segment) { segmentIntersection = transform.Unproject(proj_segmentIntersection); } return(result); }
private void FindNewEventPoint(OA_Segment segment1, OA_Segment segment2, OA_EventPoint eventPoint) { VecRat2 pointIntersection = new VecRat2(); SegRat2 segmentIntersection = new SegRat2(); SegmentIntersectionType result = GeomAid.SegmentIntersection(segment1.ToSegRat2(), segment2.ToSegRat2(), ref pointIntersection, ref segmentIntersection); if (result == SegmentIntersectionType.Point) { OA_EventPoint newEventPoint = new OA_EventPoint(pointIntersection); if (eventPoint.CompareTo(newEventPoint) < 0) { //Add the new event point if it isn't already in the event queue eventQueue.Add(new RBTreeSetNode <OA_EventPoint>(newEventPoint)); } } else if (result == SegmentIntersectionType.Segment) { throw new NotImplementedException("Didn't think this would ever happen?!"); } }
public static bool PointInSegment(VecRat2 p, SegRat2 s) { return(TurnTest(s, p) == 0 && ColinearPointInSegment(p, s)); }
public static bool ColinearPointInSegment(VecRat2 p, SegRat2 s) { LineProjectionTransform transform = new LineProjectionTransform(s); return(PointInSegment(transform.Project(p), transform.Project(s))); }
public static int TurnTest(SegRat2 s, VecRat2 p) { return(TurnTest(s.A, s.B, p)); }
//If the two segments are disjoint, then None is returned. //Else, if the two segments are colinear, then either Segment is returned. //Else, if the two segments are not colinear, Point is returned. public static SegmentIntersectionType SegmentIntersection(SegRat2 s, SegRat2 t, ref VecRat2 pointIntersection, ref SegRat2 segmentIntersection) { //This check is important for handling degenerate cases like s = [(x,y), (x,y)). if (s.IsEmpty() || t.IsEmpty()) { return(SegmentIntersectionType.None); } //This check is important because the LineProjectionTransform can only be formed with a non-point segment. if (s.IsPoint()) { if (PointInSegment(s.A, t)) { segmentIntersection = s; return(SegmentIntersectionType.Segment); } else { return(SegmentIntersectionType.None); } } int turn_s_ta = TurnTest(s, t.A); int turn_s_tb = TurnTest(s, t.B); if (turn_s_ta == 0 && turn_s_tb == 0) { return(ColinearSegmentIntersection(s, t, ref pointIntersection, ref segmentIntersection)); } if (s.AClosed) { if (t.AClosed && s.A == t.A) { pointIntersection = s.A; return(SegmentIntersectionType.Point); } else if (t.BClosed && s.B == t.B) { pointIntersection = s.B; return(SegmentIntersectionType.Point); } } if (s.BClosed) { if (t.AClosed && s.B == t.A) { pointIntersection = s.B; return(SegmentIntersectionType.Point); } else if (t.BClosed && s.B == t.B) { pointIntersection = s.B; return(SegmentIntersectionType.Point); } } int turn_t_sa = TurnTest(t, s.A); int turn_t_sb = TurnTest(t, s.B); int val_s = turn_s_ta * turn_s_tb; int val_t = turn_t_sa * turn_t_sb; if (val_s < 0 && val_t < 0) { pointIntersection = LineIntersection(s, t); return(SegmentIntersectionType.Point); } else { return(SegmentIntersectionType.None); } }
/// <summary> /// Assumes the two lines u1-v1 and u2-v2 are not parallel. /// </summary> public static VecRat2 LineIntersection(SegRat2 s1, SegRat2 s2) { return(LineIntersection(s1.A, s1.B, s2.A, s2.B)); }
public SegRat1 Project(SegRat2 s) { return(new SegRat1(Project(s.A), Project(s.B), s.AClosed, s.BClosed)); }