Exemplo n.º 1
0
static inline SplineStore qwtSplinePathX(
    const QwtSplineC1 *spline, const QPolygonF &points )
{
    SplineStore store;

    const int n = points.size();

    const QVector<double> m = spline->slopesX( points );
    if ( m.size() != n )
        return store;

    const QPointF *pd = points.constData();
    const double *md = m.constData();

    store.init( m.size() - 1 );
    store.start( pd[0].x(), pd[0].y() );

    for ( int i = 0; i < n - 1; i++ )
    {
        const double dx3 = ( pd[i+1].x() - pd[i].x() ) / 3.0;

        store.addCubic( pd[i].x() + dx3, pd[i].y() + md[i] * dx3,
            pd[i+1].x() - dx3, pd[i+1].y() - md[i+1] * dx3,
            pd[i+1].x(), pd[i+1].y() );
    }

    return store;
}
static SplineStore qwtSplinePathPleasing( const QPolygonF &points, 
    bool isClosed, Param param )
{
    const int size = points.size();

    const QPointF *p = points.constData();

    SplineStore store;
    store.init( isClosed ? size : size - 1 );
    store.start( p[0] );

    const QPointF &p0 = isClosed ? p[size-1] : p[0];
    double d13 = param(p[0], p[2]);

    const QwtSplineCardinalG1::Tension t0 = qwtTension( 
        param(p0, p[1]), param(p[0], p[1]), d13, p0, p[0], p[1], p[2] );

    const QPointF vec0 = ( p[1] - p0 ) * 0.5;
    QPointF vec1 = ( p[2] - p[0] ) * 0.5;

    store.addCubic( p[0] + vec0 * t0.t1, p[1] - vec1 * t0.t2, p[1] );

    for ( int i = 1; i < size - 2; i++ )
    {
        const double d23 = param(p[i], p[i+1]);
        const double d24 = param(p[i], p[i+2]);
        const QPointF vec2 = ( p[i+2] - p[i] ) * 0.5;

        const QwtSplineCardinalG1::Tension t =
            qwtTension( d13, d23, d24, p[i-1], p[i], p[i+1], p[i+2] );

        store.addCubic( p[i] + vec1 * t.t1, p[i+1] - vec2 * t.t2, p[i+1] );

        d13 = d24;
        vec1 = vec2;
    }

    const QPointF &pn = isClosed ? p[0] : p[size-1];
    const double d24 = param( p[size-2], pn );

    const QwtSplineCardinalG1::Tension tn = qwtTension( 
        d13, param( p[size-2], p[size-1] ), d24, p[size-3], p[size-2], p[size-1], pn );

    const QPointF vec2 = 0.5 * ( pn - p[size-2] );
    store.addCubic( p[size-2] + vec1 * tn.t1, p[size-1] - vec2 * tn.t2, p[size-1] );

    if ( isClosed )
    {
        const double d34 = param( p[size-1], p[0] );
        const double d35 = param( p[size-1], p[1] );

        const QPointF vec3 = 0.5 * ( p[1] - p[size-1] );

        const QwtSplineCardinalG1::Tension tn = 
            qwtTension( d24, d34, d35, p[size-2], p[size-1], p[0], p[1] );
        store.addCubic( p[size-1] + vec2 * tn.t1, p[0] - vec3 * tn.t2, p[0] );
    }

    return store;
}
Exemplo n.º 3
0
static inline SplineStore qwtSplinePathParam( 
    const QwtSplineC1 *spline, const QPolygonF &points, Param param )
{
    const int n = points.size();

    QPolygonF px, py;

    px += QPointF( 0.0, points[0].x() );
    py += QPointF( 0.0, points[0].y() );

    double t = 0.0;
    for ( int i = 1; i < n; i++ )
    {
        t += param( points[i-1], points[i] );

        px += QPointF( t, points[i].x() );
        py += QPointF( t, points[i].y() );
    }

    const QVector<double> mx = spline->slopesX( px );
    const QVector<double> my = spline->slopesX( py );

    SplineStore store;
    store.init( n - 1 );
    store.start( points[0].x(), points[0].y() );

    for ( int i = 1; i < n; i++ )
    {
        const double t3 = param( points[i-1], points[i] ) / 3.0;

        const double cx1 = points[i-1].x() + mx[i-1] * t3;
        const double cy1 = points[i-1].y() + my[i-1] * t3;

        const double cx2 = points[i].x() - mx[i] * t3;
        const double cy2 = points[i].y() - my[i] * t3;

        store.addCubic( cx1, cy1, cx2, cy2, points[i].x(), points[i].y() );
    }

    if ( spline->isClosing() )
    {
        const double t3 = param( points[n-1], points[0] ) / 3.0;

        const double cx1 = points[n-1].x() + mx[n-1] * t3;
        const double cy1 = points[n-1].y() + my[n-1] * t3;

        const double cx2 = points[0].x() - mx[0] * t3;
        const double cy2 = points[0].y() - my[0] * t3;

        store.addCubic( cx1, cy1, cx2, cy2, points[0].x(), points[0].y() );
        store.end();
    }

    return store;
}
static SplineStore qwtSplinePathG1( 
    const QwtSplineCardinalG1 *spline, const QPolygonF &points ) 
{
    const int size = points.size();
    const int numTensions = spline->isClosing() ? size : size - 1;

    const QVector<QwtSplineCardinalG1::Tension> tensions2 = spline->tensions( points );
    if ( tensions2.size() != numTensions )
        return SplineStore();

    const QPointF *p = points.constData();
    const QwtSplineCardinalG1::Tension *t = tensions2.constData();

    SplineStore store;
    store.init( numTensions );
    store.start( p[0] );
    
    const QPointF &p0 = spline->isClosing() ? p[size-1] : p[0];
    QPointF vec1 = ( p[1] - p0 ) * 0.5;

    for ( int i = 0; i < size - 2; i++ )
    {
        const QPointF vec2 = ( p[i+2] - p[i] ) * 0.5;
        store.addCubic( p[i] + vec1 * t[i].t1, 
            p[i+1] - vec2 * t[i].t2, p[i+1] );
        
        vec1 = vec2;
    }   
    
    const QPointF &pn = spline->isClosing() ? p[0] : p[size-1];
    const QPointF vec2 = 0.5 * ( pn - p[size - 2] );

    store.addCubic( p[size - 2] + vec1 * t[size-2].t1,
        p[size - 1] - vec2 * t[size-2].t2, p[size - 1] );

    if ( spline->isClosing() )
    {
        const QPointF vec3 = 0.5 * ( p[1] - p[size-1] );
        store.addCubic( p[size-1] + vec2 * t[size-1].t1, 
            p[0] - vec3 * t[size-1].t2, p[0] );
    }

    return store;
}
static SplineStore qwtSplinePathPleasing( const QPolygonF &points, 
    bool isClosed, Param param )
{
    using namespace QwtSplinePleasingP;

    const int size = points.size();

    const QPointF *p = points.constData();

    SplineStore store;
    store.init( isClosed ? size : size - 1 );
    store.start( p[0] );

    double d13;
    QPointF vec1;

    if ( isClosed )
    {
        d13 = qwtChordalLength(p[0], p[2]);

        const Tension t0 = qwtTensionPleasing( 
            qwtChordalLength( p[size-1], p[1]), qwtChordalLength(p[0], p[1]),
            d13, p[size-1], p[0], p[1], p[2] );

        const QPointF vec0 = qwtVectorCardinal<Param>( param, p[size-1], p[0], p[1] );
        vec1 = qwtVectorCardinal<Param>( param, p[0], p[1], p[2] );

        store.addCubic( p[0] + vec0 * t0.t1, p[1] - vec1 * t0.t2, p[1] );
    }
    else
    {
        d13 = qwtChordalLength(p[0], p[2]);

        const Tension t0 = qwtTensionPleasing( 
            qwtChordalLength( p[0], p[1]), qwtChordalLength(p[0], p[1]),
            d13,  p[0], p[0], p[1], p[2] );

        const QPointF vec0 = 0.5 * qwtVector<Param>( param, p[0], p[1] );
        vec1 = qwtVectorCardinal<Param>( param, p[0], p[1], p[2] );

        store.addCubic( p[0] + vec0 * t0.t1, p[1] - vec1 * t0.t2, p[1] );
    }

    for ( int i = 1; i < size - 2; i++ )
    {
        const double d23 = qwtChordalLength( p[i], p[i+1] );
        const double d24 = qwtChordalLength( p[i], p[i+2] );

        const QPointF vec2 = qwtVectorCardinal<Param>( param, p[i], p[i+1], p[i+2] );

        const Tension t = qwtTensionPleasing( 
            d13, d23, d24, p[i-1], p[i], p[i+1], p[i+2] );

        store.addCubic( p[i] + vec1 * t.t1, p[i+1] - vec2 * t.t2, p[i+1] );

        d13 = d24;
        vec1 = vec2;
    }

    if ( isClosed )
    {
        const double d24 = qwtChordalLength( p[size-2], p[0] );

        const Tension tn = qwtTensionPleasing( 
            d13, qwtChordalLength( p[size-2], p[size-1] ), d24, 
            p[size-3], p[size-2], p[size-1], p[0] );

        const QPointF vec2 = qwtVectorCardinal<Param>( param, p[size-2], p[size-1], p[0] );
        store.addCubic( p[size-2] + vec1 * tn.t1, p[size-1] - vec2 * tn.t2, p[size-1] );

        const double d34 = qwtChordalLength( p[size-1], p[0] );
        const double d35 = qwtChordalLength( p[size-1], p[1] );

        const Tension tc = qwtTensionPleasing( d24, d34, d35, p[size-2], p[size-1], p[0], p[1] );

        const QPointF vec3 = qwtVectorCardinal<Param>( param, p[size-1], p[0], p[1] );

        store.addCubic( p[size-1] + vec2 * tc.t1, p[0] - vec3 * tc.t2, p[0] );
    }
    else
    {
        const double d24 = qwtChordalLength( p[size-2], p[size-1] );

        const Tension tn = qwtTensionPleasing( 
            d13, qwtChordalLength( p[size-2], p[size-1] ), d24, 
            p[size-3], p[size-2], p[size-1], p[size-1] );

        const QPointF vec2 = 0.5 * qwtVector<Param>( param, p[size-2], p[size-1] );
        store.addCubic( p[size-2] + vec1 * tn.t1, p[size-1] - vec2 * tn.t2, p[size-1] );
    }

    return store;
}