From 5314ac924bd216769c90b2e3c5c338016cd7fe6c Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Sat, 29 Aug 2020 11:09:21 +0200 Subject: [PATCH] try to smooth out curves --- examples/iot-dashboard/Diagram.cpp | 142 ++++++++++++++++++++++++----- 1 file changed, 118 insertions(+), 24 deletions(-) diff --git a/examples/iot-dashboard/Diagram.cpp b/examples/iot-dashboard/Diagram.cpp index baf26f3b..26dc1a82 100644 --- a/examples/iot-dashboard/Diagram.cpp +++ b/examples/iot-dashboard/Diagram.cpp @@ -2,6 +2,83 @@ #include +#include + +namespace +{ + float distance( const QPointF& pt1, const QPointF& pt2 ) + { + float hd = ( pt1.x() - pt2.x() ) * ( pt1.x() - pt2.x() ); + float vd = ( pt1.y() - pt2.y() ) * ( pt1.y() - pt2.y() ); + return std::sqrt( hd + vd ); + } + + QPointF getLineStart( const QPointF& pt1, const QPointF& pt2 ) + { + QPointF pt; + float rat = 10.0 / distance( pt1, pt2 ); + + if( rat > 0.5 ) + { + rat = 0.5; + } + + pt.setX( ( 1.0 - rat ) * pt1.x() + rat * pt2.x() ); + pt.setY( ( 1.0 - rat ) * pt1.y() + rat * pt2.y() ); + return pt; + } + + QPointF getLineEnd( const QPointF& pt1, const QPointF& pt2 ) + { + QPointF pt; + float rat = 10.0 / distance( pt1, pt2 ); + + if( rat > 0.5 ) + { + rat = 0.5; + } + + pt.setX( rat * pt1.x() + ( 1.0 - rat )*pt2.x() ); + pt.setY( rat * pt1.y() + ( 1.0 - rat )*pt2.y() ); + return pt; + } + + QPainterPath smoothOut( const QPainterPath& path ) + { + QList points; + QPointF p; + + for( int i = 0; i < path.elementCount() - 1; i++ ) + { + p = QPointF( path.elementAt( i ).x, path.elementAt( i ).y ); + points.append( p ); + } + + QPointF pt1; + QPointF pt2; + QPainterPath newPath; + + for( int i = 0; i < points.count() - 1; i++ ) + { + pt1 = getLineStart( points[i], points[i + 1] ); + + if( i == 0 ) + { + newPath.moveTo( points[0] ); + } + else + { + newPath.quadTo( points[i], pt1 ); + } + + pt2 = getLineEnd( points[i], points[i + 1] ); + newPath.lineTo( pt2 ); + } + + return newPath; + } +} + static constexpr int segments = 7; Diagram::Diagram( QQuickItem* parent ) @@ -23,32 +100,49 @@ DiagramContent::DiagramContent( QQuickItem* parent ) : QQuickPaintedItem( parent void DiagramContent::paint( QPainter* painter ) { -// auto size = contentsSize(); -// QRectF outerRect( {0, 0}, size ); - painter->setRenderHint( QPainter::Antialiasing, true ); - qreal stepSize = width() / segments; - - QLinearGradient myGradient( {width() / 2, 0}, {width() / 2, height()} ); - myGradient.setColorAt( 0, "#996776FF" ); - myGradient.setColorAt( 1, "#116776FF" ); - QPen myPen( Qt::transparent ); - - QPainterPath myPath; - myPath.moveTo( 0, height() ); - - qreal ys[7] = {0.8, 0.85, 0.92, 0.5, 0.88, 0.7, 0.8}; - - for( int i = 0; i < stepSize; i++ ) + QPair colors[] = { - qreal x1 = i * stepSize + stepSize / 2; - qreal y = ys[i] * height(); - qreal x2 = x1; - myPath.cubicTo( x1, y, x2, height() * ( 1 - ys[i] ), stepSize * ( i + 1 ), height() * ( 1 - ys[i] ) ); - } + {"#996776FF", "#116776FF"}, + {"#aaFF3122", "#11FF3122"}, + {"#FF7D34", "#11FF7D34"} + }; - painter->setBrush( myGradient ); - painter->setPen( myPen ); - painter->drawPath( myPath ); + qreal yValues[][8] = + { + {0.8, 0.85, 0.92, 0.5, 0.88, 0.7, 0.8, 0.3}, + {0.2, 0.6, 0.5, 0.9, 0.3, 0.4, 0.8, 0.4}, + {0.5, 0.4, 0.7, 0.1, 0.6, 0.9, 0.3, 0.1} + }; + + for( int i = 0; i < 3; i++ ) + { + QLinearGradient myGradient( {width() / 2, 0}, {width() / 2, height()} ); + myGradient.setColorAt( 0, colors[i].first ); + myGradient.setColorAt( 1, colors[i].second ); + QPen myPen( Qt::transparent ); + + QPainterPath myPath; + myPath.moveTo( 0, height() ); + myPath.lineTo( 0, 50 ); + + qreal stepSize = width() / segments; + + for( int j = 1; j < segments; j++ ) + { + qreal x1 = j * stepSize + stepSize / 2; + qreal y = ( 1 - yValues[i][j] ) * height(); + myPath.lineTo( x1, y ); + } + + myPath.lineTo( width(), ( 1 - yValues[i][7] ) * height() ); + myPath.lineTo( width(), height() ); + + QPainterPath smoothPath = smoothOut( myPath ); + smoothPath.lineTo( width(), height() ); + painter->setBrush( myGradient ); + painter->setPen( myPen ); + painter->drawPath( smoothPath ); + } }