Ejemplo n.º 1
0
/*
 *  NearestPointOnCurve :
 *  	Compute the parameter value of the point on a Bezier
 *		curve segment closest to some arbtitrary, user-input point.
 *		Return the point on the curve at that parameter value.
 *
 Geom::Point 	P;			The user-supplied point
 Geom::Point 	*V;			Control points of cubic Bezier
*/
double NearestPointOnCurve(Geom::Point P, Geom::Point *V)
{
    double 	t_candidate[W_DEGREE];	/* Possible roots		*/     

    /*  Convert problem to 5th-degree Bezier form	*/
    Geom::Point	*w = ConvertToBezierForm(P, V);
    
    /* Find all possible roots of 5th-degree equation */
    int n_solutions = FindRoots(w, W_DEGREE, t_candidate, 0);
    std::free((char *)w);
    
    /* Check distance to end of the curve, where t = 1 */
    double dist = SquaredLength(P - V[DEGREE]);
    double t = 1.0;

    /* Find distances for candidate points	*/
    for (int i = 0; i < n_solutions; i++) {
        Geom::Point p = Bez(V, DEGREE, t_candidate[i], NULL, NULL);
        double new_dist = SquaredLength(P - p);
        if (new_dist < dist) {
            dist = new_dist;
            t = t_candidate[i];
        }
    }

    /*  Return the parameter value t */
    return t;
}
Ejemplo n.º 2
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);

}
Ejemplo n.º 3
0
// 计算一点到三次贝塞尔曲线段上的最近点
// Parameters :
//      pt: The user-supplied point
//      pts: Control points of cubic Bezier
//      nearpt: output the point on the curve at that parameter value
//
GEOMAPI void mgNearestOnBezier(
    const Point2d& pt, const Point2d* pts, Point2d& nearpt)
{
    Point2d w[W_DEGREE+1];          // Ctl pts for 5th-degree eqn
    float  t_candidate[W_DEGREE];  // Possible roots
    int     n_solutions;            // Number of roots found
    float  t;                      // Parameter value of closest pt

    // Convert problem to 5th-degree Bezier form
    ConvertToBezierForm(pt, pts, w);

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

    // Compare distances of pt to all candidates, and to t=0, and t=1
    {
        float  dist, new_dist;
        Point2d p;
        int     i;


        // Check distance to beginning of curve, where t = 0
        dist = (pt - pts[0]).lengthSqrd();
        t = 0.0;

        // Find distances for candidate points
        for (i = 0; i < n_solutions; i++) {
            p = BezierPoint(pts, DEGREE, t_candidate[i],
                (Point2d *)NULL, (Point2d *)NULL);
            new_dist = (pt - p).lengthSqrd();
            if (new_dist < dist) {
                dist = new_dist;
                t = t_candidate[i];
            }
        }

        // Finally, look at distance to end point, where t = 1.0
        new_dist = (pt - pts[DEGREE]).lengthSqrd();
        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);
    nearpt = (BezierPoint(pts, DEGREE, t, (Point2d *)NULL, (Point2d *)NULL));
}