Changeset 8127 in ntrip for trunk/BNC/qwt/qwt_curve_fitter.cpp


Ignore:
Timestamp:
May 10, 2017, 3:20:54 PM (7 years ago)
Author:
stoecker
Message:

update qwt and qwtpolar, many QT5 fixes (unfinished)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/qwt/qwt_curve_fitter.cpp

    r4271 r8127  
    247247public:
    248248    PrivateData():
    249         tolerance( 1.0 )
     249        tolerance( 1.0 ),
     250        chunkSize( 0 )
    250251    {
    251252    }
    252253
    253254    double tolerance;
     255    uint chunkSize;
    254256};
    255257
     
    288290 Assign the tolerance
    289291
    290  The tolerance is the maximum distance, that is accaptable
     292 The tolerance is the maximum distance, that is acceptable
    291293 between the original curve and the smoothed curve.
    292294
     
    313315
    314316/*!
     317 Limit the number of points passed to a run of the algorithm
     318
     319 The runtime of the Douglas Peucker algorithm increases non linear
     320 with the number of points. For a chunk size > 0 the polygon
     321 is split into pieces passed to the algorithm one by one.
     322
     323 \param numPoints Maximum for the number of points passed to the algorithm
     324
     325 \sa chunkSize()
     326*/
     327void QwtWeedingCurveFitter::setChunkSize( uint numPoints )
     328{
     329    if ( numPoints > 0 )
     330        numPoints = qMax( numPoints, 3U );
     331
     332    d_data->chunkSize = numPoints;
     333}
     334
     335/*!
     336 
     337  \return Maximum for the number of points passed to a run
     338          of the algorithm - or 0, when unlimited
     339  \sa setChunkSize()
     340*/
     341uint QwtWeedingCurveFitter::chunkSize() const
     342{
     343    return d_data->chunkSize;
     344}
     345
     346/*!
    315347  \param points Series of data points
    316348  \return Curve points
     
    318350QPolygonF QwtWeedingCurveFitter::fitCurve( const QPolygonF &points ) const
    319351{
     352    QPolygonF fittedPoints;
     353
     354    if ( d_data->chunkSize == 0 )
     355    {
     356        fittedPoints = simplify( points );
     357    }
     358    else
     359    {
     360        for ( int i = 0; i < points.size(); i += d_data->chunkSize )
     361        {
     362            const QPolygonF p = points.mid( i, d_data->chunkSize );
     363            fittedPoints += simplify( p );
     364        }
     365    }
     366
     367    return fittedPoints;
     368}
     369
     370QPolygonF QwtWeedingCurveFitter::simplify( const QPolygonF &points ) const
     371{
     372    const double toleranceSqr = d_data->tolerance * d_data->tolerance;
     373
    320374    QStack<Line> stack;
    321375    stack.reserve( 500 );
     
    325379
    326380    QVector<bool> usePoint( nPoints, false );
    327 
    328     double distToSegment;
    329381
    330382    stack.push( Line( 0, nPoints - 1 ) );
     
    343395        const double unitVecY = ( vecLength != 0.0 ) ? vecY / vecLength : 0.0;
    344396
    345         double maxDist = 0.0;
     397        double maxDistSqr = 0.0;
    346398        int nVertexIndexMaxDistance = r.from + 1;
    347399        for ( int i = r.from + 1; i < r.to; i++ )
     
    350402            const double fromVecX = p[i].x() - p[r.from].x();
    351403            const double fromVecY = p[i].y() - p[r.from].y();
    352             const double fromVecLength =
    353                 qSqrt( fromVecX * fromVecX + fromVecY * fromVecY );
    354 
     404
     405            double distToSegmentSqr;
    355406            if ( fromVecX * unitVecX + fromVecY * unitVecY < 0.0 )
    356407            {
    357                 distToSegment = fromVecLength;
    358             }
    359             if ( fromVecX * unitVecX + fromVecY * unitVecY < 0.0 )
    360             {
    361                 distToSegment = fromVecLength;
     408                distToSegmentSqr = fromVecX * fromVecX + fromVecY * fromVecY;
    362409            }
    363410            else
     
    365412                const double toVecX = p[i].x() - p[r.to].x();
    366413                const double toVecY = p[i].y() - p[r.to].y();
    367                 const double toVecLength = qSqrt( toVecX * toVecX + toVecY * toVecY );
     414                const double toVecLength = toVecX * toVecX + toVecY * toVecY;
     415
    368416                const double s = toVecX * ( -unitVecX ) + toVecY * ( -unitVecY );
    369417                if ( s < 0.0 )
    370                     distToSegment = toVecLength;
     418                {
     419                    distToSegmentSqr = toVecLength;
     420                }
    371421                else
    372422                {
    373                     distToSegment = qSqrt( qFabs( toVecLength * toVecLength - s * s ) );
     423                    distToSegmentSqr = qFabs( toVecLength - s * s );
    374424                }
    375425            }
    376426
    377             if ( maxDist < distToSegment )
     427            if ( maxDistSqr < distToSegmentSqr )
    378428            {
    379                 maxDist = distToSegment;
     429                maxDistSqr = distToSegmentSqr;
    380430                nVertexIndexMaxDistance = i;
    381431            }
    382432        }
    383         if ( maxDist <= d_data->tolerance )
     433        if ( maxDistSqr <= toleranceSqr )
    384434        {
    385435            usePoint[r.from] = true;
     
    393443    }
    394444
    395     int cnt = 0;
    396 
    397     QPolygonF stripped( nPoints );
     445    QPolygonF stripped;
    398446    for ( int i = 0; i < nPoints; i++ )
    399447    {
    400448        if ( usePoint[i] )
    401             stripped[cnt++] = p[i];
    402     }
    403     stripped.resize( cnt );
     449            stripped += p[i];
     450    }
     451
    404452    return stripped;
    405453}
Note: See TracChangeset for help on using the changeset viewer.