/* * ComputeMaxError : * Find the maximum squared distance of digitized points * to fitted curve. */ static double ComputeMaxError( Point2 *d, /* Array of digitized points */ int first, int last, /* Indices defining region */ BezierCurve bezCurve, /* Fitted Bezier curve */ double *u, /* Parameterization of points */ int *splitPoint) /* Point of maximum error */ { int i; double maxDist; /* Maximum error */ double dist; /* Current error */ Point2 P; /* Point on curve */ Vector2 v; /* Vector from point to curve */ *splitPoint = (last - first + 1)/2; maxDist = 0.0; for (i = first + 1; i < last; i++) { P = BezierII(3, bezCurve, u[i-first]); v = V2SubII(P, d[i]); dist = V2SquaredLength(&v); if (dist >= maxDist) { maxDist = dist; *splitPoint = i; } } return (maxDist); }
/* * NewtonRaphsonRootFind : * Use Newton-Raphson iteration to find better root. */ static qreal NewtonRaphsonRootFind(QPointF *Q, QPointF P, qreal u) { qreal numerator, denominator; QPointF Q1[3], Q2[2]; /* Q' and Q'' */ QPointF Q_u, Q1_u, Q2_u; /*u evaluated at Q, Q', & Q'' */ qreal uPrime; /* Improved u */ int i; /* Compute Q(u) */ Q_u = BezierII(3, Q, u); /* Generate control vertices for Q' */ for (i = 0; i <= 2; ++i) { Q1[i].setX((Q[i+1].x() - Q[i].x()) * 3.0); Q1[i].setY((Q[i+1].y() - Q[i].y()) * 3.0); } /* Generate control vertices for Q'' */ for (i = 0; i <= 1; ++i) { Q2[i].setX((Q1[i+1].x() - Q1[i].x()) * 2.0); Q2[i].setY((Q1[i+1].y() - Q1[i].y()) * 2.0); } /* Compute Q'(u) and Q''(u) */ Q1_u = BezierII(2, Q1, u); Q2_u = BezierII(1, Q2, u); /* Compute f(u)/f'(u) */ numerator = (Q_u.x() - P.x()) * (Q1_u.x()) + (Q_u.y() - P.y()) * (Q1_u.y()); denominator = (Q1_u.x()) * (Q1_u.x()) + (Q1_u.y()) * (Q1_u.y()) + (Q_u.x() - P.x()) * (Q2_u.x()) + (Q_u.y() - P.y()) * (Q2_u.y()); if (qFuzzyCompare(denominator, qreal(0.0))) { denominator = Zero; } /* u = u - f(u)/f'(u) */ uPrime = u - (numerator / denominator); return (uPrime); }
/* * NewtonRaphsonRootFind : * Use Newton-Raphson iteration to find better root. */ static double NewtonRaphsonRootFind( BezierCurve Q, /* Current fitted curve */ Point2 P, /* Digitized point */ double u) /* Parameter value for "P" */ { double numerator, denominator; Point2 Q1[3], Q2[2]; /* Q' and Q'' */ Point2 Q_u, Q1_u, Q2_u; /*u evaluated at Q, Q', & Q'' */ double uPrime; /* Improved u */ int i; /* Compute Q(u) */ Q_u = BezierII(3, Q, u); /* Generate control vertices for Q' */ for (i = 0; i <= 2; i++) { Q1[i].x = (Q[i+1].x - Q[i].x) * 3.0; Q1[i].y = (Q[i+1].y - Q[i].y) * 3.0; } /* Generate control vertices for Q'' */ for (i = 0; i <= 1; i++) { Q2[i].x = (Q1[i+1].x - Q1[i].x) * 2.0; Q2[i].y = (Q1[i+1].y - Q1[i].y) * 2.0; } /* Compute Q'(u) and Q''(u) */ Q1_u = BezierII(2, Q1, u); Q2_u = BezierII(1, Q2, u); /* Compute f(u)/f'(u) */ numerator = (Q_u.x - P.x) * (Q1_u.x) + (Q_u.y - P.y) * (Q1_u.y); denominator = (Q1_u.x) * (Q1_u.x) + (Q1_u.y) * (Q1_u.y) + (Q_u.x - P.x) * (Q2_u.x) + (Q_u.y - P.y) * (Q2_u.y); /* u = u - f(u)/f'(u) */ uPrime = u - (numerator/denominator); return (uPrime); }
/* * ComputeMaxError : * Find the maximum squared distance of digitized points * to fitted curve. */ static qreal ComputeMaxError(const QList<QPointF> &points, int first, int last, QPointF *curve, qreal *u, int *splitPoint) { int i; qreal maxDist; /* Maximum error */ qreal dist; /* Current error */ QPointF P; /* Point on curve */ FitVector v; /* Vector from point to curve */ *splitPoint = (last - first + 1) / 2; maxDist = 0.0; for (i = first + 1; i < last; ++i) { P = BezierII(3, curve, u[i-first]); v = VectorSub(P, points.at(i)); dist = v.length(); if (dist >= maxDist) { maxDist = dist; *splitPoint = i; } } return (maxDist); }
/* * ComputeMaxError : * Find the maximum squared distance of digitized points * to fitted curve. */ static double ComputeMaxError(Point2 *d, int first, int last, BezierCurve bezCurve, double *u, int *splitPoint) { int i; double maxDist; /* Maximum error */ double dist; /* Current error */ Point2 P; /* Point on curve */ Vector2 v; /* Vector from point to curve */ *splitPoint = (last - first + 1)/2; maxDist = 0.0; for (i = first + 1; i < last; i++) { P = BezierII(3, bezCurve, u[i-first]); v = V2SubII(P, d[i]); dist = V2SquaredLength(&v); if (dist >= maxDist) { maxDist = dist; *splitPoint = i; } } return (maxDist); }