PDA

View Full Version : Slow in drawing arraws



lni
1st July 2011, 08:35
Hi,

I need to draw 12,000 arrows pointing to different directions depending on data. It take very long time (about 1.5 seconds) to finish.

Following is the codes. If I comment out painter->drawPolyon(...), it only takes 0.037 seconds. Is there a way to speed it up? Thanks!




QRectF Rect( QPointF( 0, 0 ), QSizeF( 3, 3 ) );
Rect.moveCenter( QPointF( 0, 0 ) );

QPolygonF arrow( 3 );
arrow[ 0 ] = Rect.topLeft();
arrow[ 1 ] = QPointF( Rect.right(), 0 );
arrow[ 2 ] = Rect.bottomLeft();

painter->setBrush( Qt::black ); // fill with black on the arrow head

for ( int idx = 0; idx < dataSize; idx++ ) { // dataSize = 12,000

painter->save();

painter->translate( ... ) // translate to arrow location
painter->rotate( ... ) // rotate to angle degree depending on data

QLineF line( QPointF( 0, 0 ), QPointF( length, 0 ) ); // length is calculated from data
painter->drawLine( line );
painter->drawPolyon( arrow.translated( length, 0 ) );

painter->restore();
}

mvuori
1st July 2011, 09:46
You can obviously replace the polygon with three line segments, which should, based on your timings, be much faster. But you will get no fill in the arrow.

lni
1st July 2011, 10:06
You can obviously replace the polygon with three line segments, which should, based on your timings, be much faster. But you will get no fill in the arrow.

If I remove painter->setBrush( Qt::black ) and keep other the same, the drawing is also taking no time. So the problem is the fill, but I need to fill the arrow...

MarekR22
1st July 2011, 11:31
1. painter->save(); painter->restore(); - this is costly avoid this when it is possible.
2. Use QPixmap to draw arrow fast

high_flyer
1st July 2011, 15:53
As MArekR22 suggested:
If the head of the arrows is always the same, and you only need different lengths for the "root" of the arrow, than you can draw the head once on a QPixmap, and just translate the pixmap, and draw it.
This should get rid of the filling, which is costly.

stampede
1st July 2011, 16:03
I need to draw 12,000 arrows pointing to different directions
Sorry for offtopic, but I think it's more than too much for any human being ;)
To add to what's already been said, you can cache the root lengths (in fact cache the calculated data) and draw complete arrow pixmaps.

lni
4th July 2011, 08:12
As MArekR22 suggested:
If the head of the arrows is always the same, and you only need different lengths for the "root" of the arrow, than you can draw the head once on a QPixmap, and just translate the pixmap, and draw it.
This should get rid of the filling, which is costly.

I have tried using both pixmap and image, and it takes more time!

Now, I am using another way, which take 0.04 seconds! Obviously, drawing points with large pen and clip it using the arrow is fast!




painter->save();
painter->translate( pos );

painter->rotate( degreeAngle - 90 );

QLineF line( QPointF( 0, 0 ), QPointF( length, 0 ) );
painter->drawLine( line );

QPen pen = painter->pen();
pen.setWidth( d->penSize ); // here d->penSize = 100;
painter->setPen( pen );

QPainterPath path;
path.addPolygon( d->arrow.translated( length, 0 ) );
painter->setClipPath( path );
painter->drawPoint( QPointF( length, 0 ) );

painter->restore();