public static double DistanceFromSegment(this Point pnt, Point segStart, Point segEnd) { Contract.Ensures(Contract.Result <double>() >= 0); return((pnt - pnt.ProjectOnSegment(segStart, segEnd)).Length); }
public static Tuple <Point, double, int> ProjectionOnCurve(this Point point, IEnumerable <Point> curve) { Contract.Requires(curve != null); Contract.Requires(curve.Count() >= 2); Contract.Ensures(Contract.Result <Tuple <Point, double, int> >().Item2 >= 0); // distance is greater than zero Contract.Ensures(Contract.Result <Tuple <Point, double, int> >().Item3 >= 0); // index is greater than zero Contract.Ensures(Contract.Result <Tuple <Point, double, int> >().Item3 < curve.Count() - 1); // segment index is less than num of segments // The projected point is closer to "point" than any other point on the curve. Contract.Ensures(Contract.ForAll(curve, curvePoint => (curvePoint - point).Length >= Contract.Result <Tuple <Point, double, int> >().Item2)); var count = curve.Count(); var projectedPoints = from indexedSegment in curve.SeqPairs().ZipIndex() let index = indexedSegment.Index let segment = indexedSegment.Value let segStart = segment.Item1 let segEnd = segment.Item2 let projectedPoint = point.ProjectOnSegment(segStart, segEnd) let distance = (point - projectedPoint).Length select Tuple.Create(projectedPoint, distance, index); return(projectedPoints.Minimizer(pair => pair.Item2)); // Item2 is the distance }