/// <summary> /// Assumes the two lines u1-v1 and u2-v2 are not parallel. /// </summary> public static VecRat2 LineIntersection(VecRat2 a1, VecRat2 b1, VecRat2 a2, VecRat2 b2) { Rational s1det = MathAid.Det2(a1, b1); Rational s2det = MathAid.Det2(a2, b2); VecRat2 diff1 = a1 - b1; VecRat2 diff2 = a2 - b2; return((s1det * diff2 - s2det * diff1) / MathAid.Det2(diff1, diff2)); }
/// <summary> /// Decay from 1 to 0. /// </summary> public static float Decay(float halfLife, float elapsedTime) { if (halfLife <= 0) { return(0); } else { return(MathAid.Pow(2, -elapsedTime / halfLife)); } }
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); }
/// <summary> /// Solve ax^2 + bx + c = 0. Returns number of real roots. If 1, x1 is set. If 2, x1 and x2 are set. /// </summary> public static int SolveQuadratic(float a, float b, float c, out float x1, out float x2) { float d = b * b - 4 * a * c; if (d < 0) { x1 = float.NaN; x2 = float.NaN; return(0); } else if (d == 0) { x1 = -0.5f * b / a; x2 = float.NaN; return(1); } else { float q = -0.5f * (b + Math.Sign(b) * MathAid.Sqrt(d)); x1 = q / a; x2 = c / q; return(2); } }
public static IEnumerable <float> LinSpace(float min, float max, float approximateSegmentSize, RoundingMode mode) { return(MathAid.LinSpace(min, max, CountSegments(min, max, approximateSegmentSize, mode))); }
//Flip the orientation of this segment public void Flip() { MathAid.Swap(ref A, ref B); MathAid.Swap(ref AClosed, ref BClosed); }
public static Rational TriangleTwiceSignedArea(VecRat2 a, VecRat2 b, VecRat2 c) { return(MathAid.Det2(b - a, c - a)); }
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; }
public int Clamp(int t) { return(MathAid.Clamp(t, Min, Max)); }
public static VecInt2 Clamp(VecInt2 value, VecInt2 lo, VecInt2 hi) { return(new VecInt2(MathAid.Clamp(value.X, lo.X, hi.X), MathAid.Clamp(value.Y, lo.Y, hi.Y))); }