static element ComputeMaxError(vector[] d, int first, int last, cubicbezier bezCurve, element[] u, out int splitPoint) { var sp = (last - first + 1) / 2; element maxDist2 = 0; for (var i = first + 1; i < last; i++) { var dist2 = (bezCurve.Interpolate(u[i - first]) - d[i]).LengthSquare; if (maxDist2 <= dist2) { maxDist2 = dist2; sp = i; } } splitPoint = sp; return(maxDist2); }
/// <summary> /// Use Newton-Raphson iteration to find better root. /// </summary> /// <param name="Q">Current fitted curve</param> /// <param name="P">Digitized point</param> /// <param name="u">Parameter value for <see cref="P"/></param> /// <returns>パラメータ</returns> static element NewtonRaphsonRootFind(cubicbezier Q, vector P, element u) { /* Compute Q(u) */ var Q_u = Q.Interpolate(u); /* Generate control vertices for Q' */ var Q1 = new vector[3]; /* Q' and Q'' */ for (int i = 0; i <= 2; i++) { Q1[i] = (Q[i + 1] - Q[i]) * 3; } /* Generate control vertices for Q'' */ var Q2 = new vector[2]; for (int i = 0; i <= 1; i++) { Q2[i] = (Q1[i + 1] - Q1[i]) * 2; } /* Compute Q'(u) and Q''(u) */ var Q1_u = Interpolate2(u, Q1[0], Q1[1], Q1[2]); var Q2_u = Interpolate1(u, Q2[0], Q2[1]); /* Compute f(u)/f'(u) */ var Q_u_P = Q_u - P; var numerator = Q_u_P.Dot(Q1_u); var denominator = Q1_u.LengthSquare + Q_u_P.Dot(Q2_u); if (denominator == 0) { return(u); } /* u = u - f(u)/f'(u) */ return(u - numerator / denominator); }