/// <summary>Returns closest T value to point by binary search</summary> internal static float FindNearestApproachToPoint(PointF test, PointF[] P, float maximumError = 0.001f) { float lowT = 0; float hiT = 1; float lowDistance = Geometry.DistanceBetween(test, P[0]); float hiDistance = Geometry.DistanceBetween(test, P[3]); float half = 0; while (hiT - lowT > maximumError) { half = (lowT + hiT) / 2; PointF newPoint = Bezier.GetPoint(P, half); float testDistance = Geometry.DistanceBetween(test, newPoint); if (lowDistance > hiDistance) { lowDistance = testDistance; lowT = half; } else { hiDistance = testDistance; hiT = half; } } return(half); }
private float CalculateError(PointF[] P, PointF[] points) { // calculates the sum of the squares of the distances from the points to the line float error = 0; // the first and last points in points should be the endpoints of the curve itself, so we don't need to check how far these are from the line! Debug.Assert(P[0] == points[0] && P[3] == points[points.Length - 1]); for (int index = 1; index <= points.Length - 1 - 1; index++) { PointF pt = points[index]; float T = Bezier.FindNearestApproachToPoint(pt, P); PointF curve = Bezier.GetPoint(P, T); error += (pt.X - curve.X) * (pt.X - curve.X) + (pt.Y - curve.Y) * (pt.Y - curve.Y); } return(error); }
private PointF GetPoint(int vertex, float T) { // Like the above function, but using a given arc from this object return(Bezier.GetPoint(Vertices[vertex], Vertices[vertex + 1], m_ControlPoints[vertex * 2], m_ControlPoints[vertex * 2 + 1], T)); }