Example #1
0
double Measurement::NearestPointOnCurve(QPointF P, vector<QPointF> V)

{
    QPointF	*w;			/* Ctl pts for 5th-degree eqn	*/
    double 	t_candidate[W_DEGREE];	/* Possible roots		*/
    int 	n_solutions;		/* Number of roots found	*/
    double	t;			/* Parameter value of closest pt*/

    QPointF v_arr[4];

    for(int i=0; i<4; i++)
        v_arr[i]=V[i];


    /*  Convert problem to 5th-degree Bezier form	*/
    w = ConvertToBezierForm(P, v_arr);

    /* Find all possible roots of 5th-degree equation */
    n_solutions = FindRoots(w, W_DEGREE, t_candidate, 0);
    free((char *)w);

    /* Compare distances of P to all candidates, and to t=0, and t=1 */
    {
        double 	dist, new_dist;
        QPointF 	p;
        QPointF  v;
        int		i;


        /* Check distance to beginning of curve, where t = 0	*/
        dist = V2SquaredLength(V2Sub(&P, &v_arr[0], &v));
        t = 0.0;

        /* Find distances for candidate points	*/
        for (i = 0; i < n_solutions; i++) {
            p = Bezier(v_arr, DEGREE, t_candidate[i],
                       (QPointF *)NULL, (QPointF *)NULL);
            new_dist = V2SquaredLength(V2Sub(&P, &p, &v));
            if (new_dist < dist) {
                dist = new_dist;
                t = t_candidate[i];
            }
        }

        /* Finally, look at distance to end point, where t = 1.0 */
        new_dist = V2SquaredLength(V2Sub(&P, &V[DEGREE], &v));
        if (new_dist < dist) {
            dist = new_dist;
            t = 1.0;
        }
    }

    /*  Return the point on the curve at parameter value t */
//    printf("t : %4.12f\n", t);
    QPointF b=Bezier(v_arr, DEGREE, t, (QPointF *)NULL, (QPointF *)NULL);
    return V2DistanceBetween2Points(&P,&b);

}
Example #2
0
/*
 *  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);
}
/*
 *  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);
}
/* returns length of input vector */
double V2Length(Vector2 *a) {
    return(sqrt(V2SquaredLength(a)));
}