/// <summary> /// Finds the nearest point on the specified polyline. /// </summary> /// <param name="point">The point.</param> /// <param name="points">The points.</param> /// <returns>The nearest point.</returns> public static ScreenPoint FindNearestPointOnPolyline(ScreenPoint point, IList <ScreenPoint> points) { double minimumDistance = double.MaxValue; var nearestPoint = default(ScreenPoint); for (int i = 0; i + 1 < points.Count; i++) { var p1 = points[i]; var p2 = points[i + 1]; if (ScreenPoint.IsUndefined(p1) || ScreenPoint.IsUndefined(p2)) { continue; } // Find the nearest point on the line segment. var nearestPointOnSegment = FindPointOnLine(point, p1, p2); if (ScreenPoint.IsUndefined(nearestPointOnSegment)) { continue; } double l2 = (point - nearestPointOnSegment).LengthSquared; if (l2 < minimumDistance) { nearestPoint = nearestPointOnSegment; minimumDistance = l2; } } return(nearestPoint); }
/// <summary> /// Gets the point on the curve that is nearest the specified point. /// </summary> /// <param name="points"> /// The point list. /// </param> /// <param name="point"> /// The point. /// </param> /// <returns> /// A tracker hit result if a point was found. /// </returns> protected TrackerHitResult GetNearestInterpolatedPointInternal(IList <IDataPoint> points, ScreenPoint point) { if (points == null) { return(null); } var spn = default(ScreenPoint); var dpn = default(DataPoint); double index = -1; double minimumDistance = double.MaxValue; for (int i = 0; i + 1 < points.Count; i++) { var p1 = points[i]; var p2 = points[i + 1]; if (!this.IsValidPoint(p1, this.XAxis, this.YAxis) || !this.IsValidPoint(p2, this.XAxis, this.YAxis)) { continue; } var sp1 = this.Transform(p1); var sp2 = this.Transform(p2); // Find the nearest point on the line segment. var spl = ScreenPointHelper.FindPointOnLine(point, sp1, sp2); if (ScreenPoint.IsUndefined(spl)) { // P1 && P2 coincident continue; } double l2 = (point - spl).LengthSquared; if (l2 < minimumDistance) { double u = (spl - sp1).Length / (sp2 - sp1).Length; dpn = new DataPoint(p1.X + (u * (p2.X - p1.X)), p1.Y + (u * (p2.Y - p1.Y))); spn = spl; minimumDistance = l2; index = i + u; } } if (minimumDistance < double.MaxValue) { object item = this.GetItem((int)index); return(new TrackerHitResult(this, dpn, spn, item) { Index = index }); } return(null); }