Beispiel #1
0
/**
 * \return List of bezier spline segments which together represent this curve.
 */
QList<RSpline> RSpline::getBezierSegments() const {
    // spline is a single bezier segment:
    if (countControlPoints()==getDegree()+1) {
        return QList<RSpline>() << *this;
    }

    updateInternal();

    QList<RSpline> ret;
#ifndef R_NO_OPENNURBS
    ON_NurbsCurve* dup = dynamic_cast<ON_NurbsCurve*>(curve.DuplicateCurve());
    if (dup==NULL) {
        return ret;
    }

    dup->MakePiecewiseBezier();
    for (int i=0; i<=dup->CVCount() - dup->Order(); ++i) {
        ON_BezierCurve bc;
        if (!dup->ConvertSpanToBezier(i, bc)) {
            continue;
        }

        QList<RVector> ctrlPts;
        for (int cpi=0; cpi<bc.CVCount(); cpi++) {
            ON_3dPoint onp;
            bc.GetCV(cpi, onp);
            ctrlPts.append(RVector(onp.x, onp.y, onp.z));
        }
        ret.append(RSpline(ctrlPts, degree));
    }
    delete dup;
 #endif

    return ret;
}
Beispiel #2
0
/**
 *  Cubic bezier approximation of a circular arc centered at the origin,
 *  from (radians) a1 to a2, where a2-a1 < pi/2.  The arc's radius is r.
 *
 *  Returns an spline approximation.
 *
 *  This algorithm is based on the approach described in:
 *  A. Riškus, "Approximation of a Cubic Bezier Curve by Circular Arcs and Vice Versa,"
 *  Information Technology and Control, 35(4), 2006 pp. 371-378.
 */
RSpline RSpline::createBezierFromSmallArc(double r, double a1, double a2) {
    // Compute all four points for an arc that subtends the same total angle
    // but is centered on the X-axis

    double a = (a2 - a1) / 2.0; //

    double x4 = r * cos(a);
    double y4 = r * sin(a);
    double x1 = x4;
    double y1 = -y4;

    //double k = 0.552284749831;
    //double k = 4.0/3.0*(sqrt(2.0)-1.0);
    //double f = k * tan(a);

    double q1 = x1*x1 + y1*y1;
    double q2 = q1 + x1*x4 + y1*y4;
    double k2 = 4/3 * (sqrt(2 * q1 * q2) - q2) / (x1 * y4 - y1 * x4);

    double x2 = x1 - k2 * y1;
    double y2 = y1 + k2 * x1;
    //double x2 = x1 + f * y4;
    //double y2 = y1 + f * x4;
    double x3 = x2;
    double y3 = -y2;

    // Find the arc points actual locations by computing x1,y1 and x4,y4
    // and rotating the control points by a + a1
    double ar = a + a1;
    double cos_ar = cos(ar);
    double sin_ar = sin(ar);

    QList<RVector> ctrlPts;
    ctrlPts
        << RVector(
            r * cos(a1),
            r * sin(a1)
           )
        << RVector(
            x2 * cos_ar - y2 * sin_ar, 
            x2 * sin_ar + y2 * cos_ar
           )
        << RVector(
            x3 * cos_ar - y3 * sin_ar, 
            x3 * sin_ar + y3 * cos_ar
           )
        << RVector(
            r * cos(a2), 
            r * sin(a2)
           );

//    qDebug() << "ctrlPts: " << ctrlPts[0];
//    qDebug() << "ctrlPts: " << ctrlPts[1];
//    qDebug() << "ctrlPts: " << ctrlPts[2];
//    qDebug() << "ctrlPts: " << ctrlPts[3];

    return RSpline(ctrlPts, 2);
}