/// <summary> /// Enumerates the times and places, if any, where a moving line crosses a point during a time step. /// The line's endpoints move at a constant rate along their linear paths. /// </summary> public static IEnumerable<Sweep> WhenLineSweepsPoint(LineSegment pathOfLineStartPoint, LineSegment pathOfLineEndPoint, Point point) { var a = point - pathOfLineStartPoint.Start; var b = -pathOfLineStartPoint.Delta; var c = pathOfLineEndPoint.Start - pathOfLineStartPoint.Start; var d = pathOfLineEndPoint.Delta - pathOfLineStartPoint.Delta; return from t in QuadraticRoots(b.Cross(d), a.Cross(d) + b.Cross(c), a.Cross(c)) where t >= 0 && t <= 1 let start = pathOfLineStartPoint.LerpAcross(t) let end = pathOfLineEndPoint.LerpAcross(t) let s = point.LerpProjectOnto(new LineSegment(start, end)) where s >= 0 && s <= 1 orderby t select new Sweep(timeProportion: t, acrossProportion: s); }
///<summary> ///The proportion that, when lerped across the given line, results in the given point. ///If the point is not on the line segment, the result is the closest point on the extended line. ///</summary> public static double LerpProjectOnto(this Point point, LineSegment line) { var b = point - line.Start; var d = line.Delta; return (b * d) / (d * d); }