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; }
//! Wrapper for QPainter::drawPolyline() void QwtPainter::drawPolyline( QPainter *painter, const QPolygonF &polygon ) { QRectF clipRect; const bool deviceClipping = qwtIsClippingNeeded( painter, clipRect ); QPolygonF cpa = polygon; if ( deviceClipping ) cpa = QwtClipper::clipPolygonF( clipRect, cpa ); qwtDrawPolyline<QPointF>( painter, cpa.constData(), cpa.size(), d_polylineSplitting ); }
/*! \fn QPolygonF QMatrix::map(const QPolygonF &polygon) const \overload Creates and returns a QPolygonF object that is a copy of the given \a polygon, mapped into the coordinate system defined by this matrix. */ QPolygonF QMatrix::map(const QPolygonF &a) const { int size = a.size(); int i; QPolygonF p(size); const QPointF *da = a.constData(); QPointF *dp = p.data(); for(i = 0; i < size; i++) { MAPDOUBLE(da[i].xp, da[i].yp, dp[i].xp, dp[i].yp); } return p; }
void QgsCoordinateTransform::transformPolygon( QPolygonF &poly, TransformDirection direction ) const { if ( !d->mIsValid || d->mShortCircuit ) { return; } //create x, y arrays int nVertices = poly.size(); QVector<double> x( nVertices ); QVector<double> y( nVertices ); QVector<double> z( nVertices ); double *destX = x.data(); double *destY = y.data(); double *destZ = z.data(); const QPointF *polyData = poly.constData(); for ( int i = 0; i < nVertices; ++i ) { *destX++ = polyData->x(); *destY++ = polyData->y(); *destZ++ = 0; polyData++; } try { transformCoords( nVertices, x.data(), y.data(), z.data(), direction ); } catch ( const QgsCsException & ) { // rethrow the exception QgsDebugMsg( QStringLiteral( "rethrowing exception" ) ); throw; } QPointF *destPoint = poly.data(); const double *srcX = x.constData(); const double *srcY = y.constData(); for ( int i = 0; i < nVertices; ++i ) { destPoint->rx() = *srcX++; destPoint->ry() = *srcY++; destPoint++; } }
QPolygonF QwtSplineC1::polygonX( int numPoints, const QPolygonF &points ) const { if ( points.size() <= 2 ) return points; QPolygonF fittedPoints; const QVector<double> m = slopesX( points ); if ( m.size() != points.size() ) return fittedPoints; const QPointF *p = points.constData(); const double *s = m.constData(); const double x1 = points.first().x(); const double x2 = points.last().x(); const double delta = ( x2 - x1 ) / ( numPoints - 1 ); double x0, y0; QwtSplinePolynom polynom; for ( int i = 0, j = 0; i < numPoints; i++ ) { double x = x1 + i * delta; if ( x > x2 ) x = x2; if ( i == 0 || x > p[j + 1].x() ) { while ( x > p[j + 1].x() ) j++; polynom = QwtSplinePolynom::fromSlopes( p[j], s[j], p[j + 1], s[j + 1] ); x0 = p[j].x(); y0 = p[j].y(); } const double y = y0 + polynom.value( x - x0 ); fittedPoints += QPointF( x, y ); } return fittedPoints; }
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; }
void Renderer::drawMesh() { // render mesh as a wireframe QPainter p(&mImage); p.setRenderHint(QPainter::Antialiasing); p.setPen(QPen(QBrush(mCfg.mesh.mMeshColor),0.5)); p.setFont(QFont("")); const Mesh::Elements& elems = mMesh->elements(); for (int i=0; i < elems.count(); ++i) { const Element& elem = elems[i]; if( elem.isDummy() ) continue; // If the element is outside the view of the canvas, skip it if( elemOutsideView(i) ) continue; QPolygonF pts = elementPolygonPixel(elem); p.drawPolyline(pts.constData(), pts.size()); if (mCfg.mesh.mRenderMeshLabels) { double cx, cy; mMesh->elementCentroid(i, cx, cy); QString txt = QString::number(elem.id()); QRect bb = p.fontMetrics().boundingRect(txt); QPointF xy = mtp.realToPixel(cx, cy); bb.moveTo(xy.x() - bb.width()/2.0, xy.y() - bb.height()/2.0); if (pts.containsPoint(bb.bottomLeft(), Qt::WindingFill) && pts.containsPoint(bb.bottomRight(), Qt::WindingFill) && pts.containsPoint(bb.topLeft(), Qt::WindingFill) && pts.containsPoint(bb.topRight(), Qt::WindingFill)) { p.drawText(bb, Qt::AlignCenter, txt); } } } }
static inline QVector<QwtSplineCardinalG1::Tension> qwtTensions( const QPolygonF &points, bool isClosed, Param param ) { const int size = points.size(); QVector<QwtSplineCardinalG1::Tension> tensions2( isClosed ? size : size - 1 ); const QPointF *p = points.constData(); QwtSplineCardinalG1::Tension *t = tensions2.data(); const QPointF &p0 = isClosed ? p[size-1] : p[0]; double d13 = param(p[0], p[2]); t[0] = qwtTension( param(p0, p[1]), param(p[0], p[1]), d13, p0, p[0], p[1], p[2] ); 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] ); t[i] = qwtTension( d13, d23, d24, p[i-1], p[i], p[i+1], p[i+2] ); d13 = d24; } const QPointF &pn = isClosed ? p[0] : p[size-1]; const double d24 = param( p[size-2], pn ); t[size-2] = qwtTension( d13, param( p[size-2], p[size-1] ), d24, p[size - 3], p[size - 2], p[size - 1], pn ); if ( isClosed ) { const double d34 = param( p[size-1], p[0] ); const double d35 = param( p[size-1], p[1] ); t[size-1] = qwtTension( d24, d34, d35, p[size-2], p[size-1], p[0], p[1] ); } return tensions2; }
QPainterPath QwtSpline::pathP( const QPolygonF &points ) const { const int n = points.size(); QPainterPath path; if ( n == 0 ) return path; if ( n == 1 ) { path.moveTo( points[0] ); return path; } if ( n == 2 ) { path.addPolygon( points ); return path; } const QVector<QLineF> controlPoints = bezierControlPointsP( points ); if ( controlPoints.size() < n - 1 ) return path; const QPointF *p = points.constData(); const QLineF *l = controlPoints.constData(); path.moveTo( p[0] ); for ( int i = 0; i < n - 1; i++ ) path.cubicTo( l[i].p1(), l[i].p2(), p[i+1] ); if ( controlPoints.size() >= n ) { path.cubicTo( l[n-1].p1(), l[n-1].p2(), p[0] ); path.closeSubpath(); } return path; }
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; }