public static SegmentIntersectionType SegmentIntersection(SegRat1 s, SegRat1 t, ref Rational pointIntersection, ref SegRat1 segmentIntersection) { //This check is important for handling degenerate cases like s = [x, x). if (s.IsEmpty() || t.IsEmpty()) { return(SegmentIntersectionType.None); } s.NormalizeOrientation(); t.NormalizeOrientation(); if (s.A > t.A) { MathAid.Swap(ref s, ref t); } if (s.B < t.A) { return(SegmentIntersectionType.None); } if (s.B == t.A) { if (s.BClosed && t.AClosed) { pointIntersection = s.B; return(SegmentIntersectionType.Point); } else { return(SegmentIntersectionType.None); } } Rational b = Rational.Min(s.B, t.B); segmentIntersection.A = t.A; segmentIntersection.B = b; segmentIntersection.AClosed = (t.AClosed && (s.A < t.A || (s.AClosed && s.A == t.A))); segmentIntersection.BClosed = ((s.BClosed && t.BClosed) || (s.BClosed && b < t.B) || (t.BClosed && b < s.B)); return(SegmentIntersectionType.Segment); }
public static int TurnTest(VecRat2 a, VecRat2 b, VecRat2 c) { return(Rational.Sign(TriangleTwiceSignedArea(a, b, c))); }
public static Rational TriangleTwiceArea(VecRat2 a, VecRat2 b, VecRat2 c) { return(Rational.Abs(TriangleTwiceSignedArea(a, b, c))); }
public int CompareTo(OA_Segment other) { if (!(this.IntersectsSweepline && other.IntersectsSweepline)) { throw new InvalidOperationException(); } if (this == other) { return(0); } Rational thisX = this.SweeplineIntersectionX; Rational otherX = other.SweeplineIntersectionX; int comp = thisX.CompareTo(otherX); if (comp != 0) { return(comp); } //The downward ordering Turn turn = MathAid.TurnTestDiscrete(this.Upper.Position, new VecRat2(thisX, Sweepline.Y), other.Upper.Position); if (turn == Turn.Linear) { turn = MathAid.TurnTestDiscrete(this.Lower.Position, new VecRat2(thisX, Sweepline.Y), other.Lower.Position); } if (turn == Turn.Right) { comp = -1; } else if (turn == Turn.Left) { comp = 1; } else { //Two segments overlapping at more than a single point comp = 0; } //We know thisX==otherX //We want the downward ordering if these segments cross to the left of the current event point //However, if: // a) the sweepline is before the event point and these segements pass through the event point // or b) these segments cross to the right of the current event point //Then we want to reverse this ordering! if ((Sweepline.BeforeEventPoint && thisX == Sweepline.IncidentEventPoint.Position.X) || thisX > Sweepline.IncidentEventPoint.Position.X) { comp *= -1; } if (comp != 0) { return(comp); } comp = this.Upper.CompareTo(other.Upper); if (comp != 0) { return(comp); } comp = this.Lower.CompareTo(other.Lower); return(comp); //comp = this.Upper.Position.Y.CompareTo(other.Upper.Position.Y); //if (comp != 0) // return comp; //comp = this.Upper.Position.X.CompareTo(other.Upper.Position.X); //if (comp != 0) // return comp; //comp = other.Lower.Position.Y.CompareTo(this.Lower.Position.Y); //if (comp != 0) // return comp; //comp = other.Lower.Position.X.CompareTo(this.Lower.Position.X); //return comp; }