Results 1 to 11 of 11

Thread: Need help in optimizing a drawing code ...

  1. #1
    Join Date
    Jun 2010
    Posts
    26
    Qt products
    Qt4
    Platforms
    Windows Symbian S60 Maemo/MeeGo

    Default Need help in optimizing a drawing code ...

    Hello all ... I needed some help in trying to optimize this code portion ... Basically here's the thing .. I'm making this 'calligraphy pen' which gives the calligraphy effect by simply drawing a lot of adjacent slanted lines ... The problem is this: When I update the draw region using update() after every single draw of a slanted line, the output is correct, in the sense that updates are done in a timely manner, so that everything 'drawn' using the pen is immediately 'seen' the drawing.. however, because a *lot* (100s of them) of updates are done, the program slows down a little when run on the N900 ...

    When I try to do a little optimization by running update after drawing *all* the slanted lines (so that all lines are updated onto the drawing board through a single update() ), the output is ... odd .... That is, immediately after drawing the lines, they lines seem broken (they have vacant patches where the drawing should have happened as well) ... however, if I trigger a redrawing of the form window (say, by changing the size of the form), the broken patches are immediately fixed !! When I run this program on my N900, it gets the initial broken output and stays like that, since I don't know how to enforce a redraw in this case ...

    Here is the first 'optimized' code and output (partially correct/incorrect)

    Qt Code:
    1. void Canvas::drawLineTo(const QPoint &endPoint)
    2. {
    3. QPainter painter(&image);
    4. painter.setPen(QPen(Qt::black,1,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
    5. int fx=0,fy=0,k=0;
    6. qPoints.clear();
    7. connectingPointsCalculator2(qPoints,lastPoint.x(),lastPoint.y(),endPoint.x(),endPoint.y());
    8. int i=0;
    9. int x,y;
    10. for(i=0;i<qPoints.size();i++)
    11. {
    12. x=qPoints.at(i).x();
    13. y=qPoints.at(i).y();
    14. painter.setPen(Qt::black);
    15. painter.drawLine(x-5,y-5,x+5,y+5); //Drawing slanted lines
    16. }
    17. //Updating only once after many draws:
    18. update (QRect(QPoint(lastPoint.x()-5,lastPoint.y()-5), QPoint(endPoint.x()+5,endPoint.y()+5)).normalized());
    19.  
    20. modified = true;
    21. lastPoint = endPoint;
    22. }
    To copy to clipboard, switch view to plain text mode 

    Image right after scribbling on screen:



    Image after slightly re-adjusting the window size:



    Here is the second un-optimized code (its output is correct right after drawing, just like in the second picture above):

    Qt Code:
    1. void Canvas::drawLineTo(const QPoint &endPoint)
    2. {
    3. QPainter painter(&image);
    4. painter.setPen(QPen(Qt::black,1,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
    5. int fx=0,fy=0,k=0;
    6. qPoints.clear();
    7. connectingPointsCalculator2(qPoints,lastPoint.x(),lastPoint.y(),endPoint.x(),endPoint.y());
    8. int i=0;
    9. int x,y;
    10. for(i=0;i<qPoints.size();i++)
    11. {
    12. x=qPoints.at(i).x();
    13. y=qPoints.at(i).y();
    14. painter.setPen(Qt::black);
    15. painter.drawLine(x-5,y-5,x+5,y+5); // Drawing slanted lines
    16. //Updating repeatedly during the for loop:
    17. update(QRect(QPoint(x-5,y-5), QPoint(x+5,y+5)).normalized());//.adjusted(-rad,-rad,rad,rad));
    18. }
    19. modified = true;
    20. int rad = (myPenWidth / 2) + 2;
    21. lastPoint = endPoint;
    22. }
    To copy to clipboard, switch view to plain text mode 


    Can anyone see what the issue might be ?
    Last edited by ahmadka; 14th June 2010 at 20:58.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Need help in optimizing a drawing code ...

    One thing I can say is that you are not clearing the image before drawing on it. Another is that it'd be nice to see the paintEvent() implementation as well. Finally I can tell you that QPainter::drawLines() is much faster than calling QPainter::drawLine() multiple times. The number of calls to update() shouldn't matter here, they should all be merged into one update anyway. I would also assume the rect passed to update() in the first case might be incorrect - consider a situation when you draw a counter-clockwise circle, what would the rect be then?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jun 2010
    Posts
    26
    Qt products
    Qt4
    Platforms
    Windows Symbian S60 Maemo/MeeGo

    Default Re: Need help in optimizing a drawing code ...

    What do you mean by 'clearing the image' .. ? I mean, I don't want to erase the stuff I have drawn before .. I thought about reimplementing the paintEvent() as well but that seems a little difficult for me right now, as I'm still learning Qt without a book :P .. I will try to look into the drawLines() function though ..

    The issue is somehow related to updating the display when drawing horizontal stuff ... When drawing vertical lines, no matter how fast, they're always solid, but horizontal lines are always broken, unless you are absolutely drawing at snail speed ..

    Here's a picture from my N900:


  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Need help in optimizing a drawing code ...

    Quote Originally Posted by ahmadka View Post
    What do you mean by 'clearing the image' .. ? I mean, I don't want to erase the stuff I have drawn before ..
    Ah... ok, I thought you were redrawing all the points at each update.

    I thought about reimplementing the paintEvent() as well but that seems a little difficult for me right now, as I'm still learning Qt without a book :P
    If you are not reimplementing the paintEvent then how do you draw the image?
    Here's a picture from my N900:
    Please don't use third party sites to link images from. This violates the rules of this site.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Jun 2010
    Posts
    26
    Qt products
    Qt4
    Platforms
    Windows Symbian S60 Maemo/MeeGo

    Default Re: Need help in optimizing a drawing code ...

    Well I'm painting directly on 'image' (which is a QImage object) using QPainter painter(&image) ... and then use update and everything ..

    The connectingPointsCalculator function gives me all the points between to coordinates .. about each of these the slanted lines are calculated .. I've checked the working for this function too, to see if it gives wrong results in horizontal cases or something .. but this is fine too .. Also, since the problem only exists when running the code on N900, it leads me to believe that maybe the updating/repainting procedure is different for the N900 than for PC ... Would double buffering help here ?

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Need help in optimizing a drawing code ...

    Well I'm painting directly on 'image' (which is a QImage object) using QPainter painter(&image) ... and then use update and everything ..
    What is the base class of your widget? How is "image" related to the widget?

    Would double buffering help here ?
    Qt widgets are double buffered by default. Save the image to disk and open it in an external viewer, check if the image is correct or not. At worst update the whole widget each time.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Jun 2010
    Posts
    26
    Qt products
    Qt4
    Platforms
    Windows Symbian S60 Maemo/MeeGo

    Default Re: Need help in optimizing a drawing code ...

    Alright here's the breakdown of my program ... There's a Main Window, which is just a main window .. Then there's another class I made called Canvas .. an object of Canvas is stored in Main Window and is initialized from Main Window's contructor .. Canvas is my main class where all the paint events and mouse events are handled .. 'image' is just a QImage object contained within the Canvas class .. Drawing is done on this image ..

    Here's a gist of my code ... Thought, only stuff relevant to this issue is presented here:

    Here's Canvas.h: (was previously called 'Board' .. by Canvas I mean the widget which contains the image on which drawing is done)


    Qt Code:
    1. class Canvas : public QWidget
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. Canvas(QWidget *parent = 0);
    7.  
    8. protected:
    9. void mousePressEvent(QMouseEvent *event);
    10. void mouseMoveEvent(QMouseEvent *event);
    11. void mouseReleaseEvent(QMouseEvent *event);
    12. void mouseDoubleClickEvent(QMouseEvent *);
    13. void paintEvent(QPaintEvent *event);
    14.  
    15. private:
    16. void drawLineTo(const QPoint &endPoint);
    17.  
    18. QImage image; [B]//this is the image on which drawing is done[/B]
    19. QPoint lastPoint;
    20. QVector<QPoint> qPoints;
    21. //MainWindow *mainWindow;
    22. int minX;
    23. int minY;
    24. int maxX;
    25. int maxY;
    26. void connectingPointsCalculator3( QVector<QPoint>& inputqPoints, int x0, int y0, int x1, int y1);
    27. };
    To copy to clipboard, switch view to plain text mode 

    ConnectingPointsCalculator3 function .. (used to output a QVector of all the points which need to be connected to make all those lines to give the slanted effect ... only the point coordinates are calculated in this function):

    Qt Code:
    1. void Canvas::connectingPointsCalculator3( QVector<QPoint>& inputqPoints, int x0, int y0, int x1, int y1)
    2. {
    3. inputqPoints.clear();
    4. bool steep;
    5.  
    6.  
    7. int i=2;
    8.  
    9. if( qAbs(y1-y0)>qAbs(x1-x0))
    10. {
    11. steep = true;
    12. }
    13. if(steep==true)
    14. {
    15. swap(x0,y0);
    16. swap(x1,y1);
    17. }
    18. if(x0>x1)
    19. {
    20. swap(x0,x1);
    21. swap(y0,y1);
    22. }
    23. int deltax = x1-x0;
    24. int deltay = qAbs(y1-y0);
    25. int error = deltax/2;
    26. int ystep=0;
    27. int y=y0;
    28. if(y0<y1)
    29. {
    30. ystep=1;
    31. }
    32. else
    33. {
    34. ystep=-1;
    35. }
    36. inputqPoints.resize(1);
    37. if(steep==true)
    38. {
    39. inputqPoints.insert(0,QPoint(y0-5,x0-5));
    40. inputqPoints.insert(1,QPoint(y0+5,x0+5));
    41. }
    42. else
    43. {
    44. inputqPoints.insert(0,QPoint(x0-5,y0-5));
    45. inputqPoints.insert(1,QPoint(x0+5,y0+5));
    46. }
    47. bool switchedLanes = false;
    48. int x= x0;
    49. while(x<(x1+1))
    50. {
    51. if(switchedLanes==false)
    52. {
    53. error = error - deltay;
    54. if(error<0)
    55. {
    56. y=y+ystep;
    57. error = error + deltax;
    58. switchedLanes = true;
    59. }
    60. }
    61. else
    62. {
    63. switchedLanes=false;
    64. }
    65.  
    66.  
    67. if(steep==true)
    68. {
    69. inputqPoints.insert(i,QPoint(y-5,x-5));
    70. inputqPoints.insert(i+1,QPoint(y+5,x+5));
    71. if((y-5)<minX)
    72. {
    73. minX=y-5;
    74. }
    75. if((x-5)<minY)
    76. {
    77. minY=x-5;
    78. }
    79. if((y+5)>maxX)
    80. {
    81. maxX=y+5;
    82. }
    83. if((x+5)>maxY)
    84. {
    85. maxY=x+5;
    86. }
    87. }
    88. else
    89. {
    90. inputqPoints.insert(i,QPoint(x-5,y-5));
    91. inputqPoints.insert(i+1,QPoint(x+5,y+5));
    92. if((x-5)<minX)
    93. {
    94. minX=x-5;
    95. }
    96. if((y-5)<minY)
    97. {
    98. minY=y-5;
    99. }
    100. if((x+5)>maxX)
    101. {
    102. maxX=x+5;
    103. }
    104. if((y+5)>maxY)
    105. {
    106. maxY=y+5;
    107. }
    108. }
    109. if(switchedLanes==false)
    110. {
    111. x++;
    112.  
    113. }
    114. i++;
    115. i++;
    116.  
    117. }
    118.  
    119. }
    To copy to clipboard, switch view to plain text mode 

    Function used to actually do all the drawing on the QImage object named 'image':

    Qt Code:
    1. void Canvas::drawLineTo(const QPoint &endPoint)
    2. {
    3. QPainter painter(&image);
    4.  
    5. painter.setPen(QPen(Qt::black,1,Qt::SolidLine,Qt::RoundCap,Qt::RoundJoin));
    6. qPoints.clear();
    7. minX =999999;
    8. minY =999999;
    9. maxX =-999999;
    10. maxY =-999999;
    11. painter.setPen(Qt::blue);
    12. painter.drawEllipse(lastPoint,8,8);
    13. painter.setPen(Qt::red);
    14. painter.drawEllipse(endPoint,4,4);
    15. connectingPointsCalculator3(qPoints,lastPoint.x(),lastPoint.y(),endPoint.x(),endPoint.y());
    16. painter.setPen(Qt::black);
    17. painter.drawLines(qPoints);
    18.  
    19. update (QRect(QPoint(minX,minY), QPoint(maxX,maxY)).normalized());
    20. //update();
    21. modified = true;
    22. lastPoint = endPoint;
    23. }
    To copy to clipboard, switch view to plain text mode 

    3 functions to do the initialization within the Canvas object:

    Qt Code:
    1. Canvas::Canvas(QWidget *parent)
    2. {
    3. setAttribute(Qt::WA_StaticContents);
    4. reset();
    5. qPoints.clear();
    6. }
    7.  
    8. void Canvas::reset()
    9. {
    10. resizeImage(&image,QSize(800,400));
    11. image.fill(qRgb(255, 255, 255));
    12. update();
    13. }
    14.  
    15. void Canvas::resizeImage(QImage *image, const QSize &newSize)
    16. {
    17. if (image->size() == newSize)
    18. return;
    19.  
    20. QImage newImage(newSize, QImage::Format_RGB32);
    21. QPainter painter(&newImage);
    22. painter.drawImage(QPoint(0, 0), *image);
    23. *image = newImage;
    24. }
    To copy to clipboard, switch view to plain text mode 

    Drawing event functions:

    Qt Code:
    1. void Canvas::mousePressEvent(QMouseEvent *event)
    2. {
    3. if(event->button() & Qt::LeftButton)
    4. {
    5. scribbling=true;
    6. lastPoint=event->pos();
    7. }
    8. }
    9.  
    10. void Canvas::mouseMoveEvent(QMouseEvent *event)
    11. {
    12. if((event->buttons() & Qt::LeftButton) && scribbling==true)
    13. {
    14. drawLineTo(event->pos());
    15. }
    16. }
    17.  
    18. void Canvas::mouseReleaseEvent(QMouseEvent *event)
    19. {
    20. if((event->button()&Qt::LeftButton)&&scribbling==true)
    21. {
    22. drawLineTo(event->pos());
    23. scribbling=false;
    24. }
    25. }
    To copy to clipboard, switch view to plain text mode 

    Canvas paintEvent():

    Qt Code:
    1. void Canvas::paintEvent(QPaintEvent *event)
    2. {
    3. QPainter painter(this);
    4. QRect dirtyRect = event->rect();
    5. painter.drawImage(dirtyRect, image, dirtyRect);
    6. }
    To copy to clipboard, switch view to plain text mode 

    if you need code for my Main Window as well, please let me know ... And please help me figure this silly bug out :P

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,368
    Thanks
    3
    Thanked 5,018 Times in 4,794 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Need help in optimizing a drawing code ...

    So you are implementing the paintEvent after all

    Please do the tests I asked you to do in the previous post.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. #9
    Join Date
    Jun 2010
    Posts
    26
    Qt products
    Qt4
    Platforms
    Windows Symbian S60 Maemo/MeeGo

    Default Re: Need help in optimizing a drawing code ...

    Alright I was busy for the past couple of days so I couldn't work on this problem before .. Anyways I implemented an image save feature, and have saved a PNG file directly from the N900 .. Bad news, the image is exactly like I see it on the N900: Broken horizontal lines ..

    Anyways, here's one picture saved through my program running on the N900 (the blue and red circles indicate the points between slanted lines need to be drawn):


  10. #10
    Join Date
    Sep 2009
    Location
    UK
    Posts
    2,447
    Thanks
    6
    Thanked 348 Times in 333 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Need help in optimizing a drawing code ...

    Firstly, forget drawing for a bit. Look the positions you are trying to draw, and then load them in afterwards and draw them. This will tell you what the problem is.

    Secondly, as Wysota says, please don't use imageshack (or any other third party image hosting site).

  11. #11
    Join Date
    Jun 2010
    Posts
    26
    Qt products
    Qt4
    Platforms
    Windows Symbian S60 Maemo/MeeGo

    Default Re: Need help in optimizing a drawing code ...

    Okay yeh, I figured out the problem .. problem was in my connecting points code .. fixed it now, and now there are no breaks ..

    Thanks for your help mate, and i apologize for uploading to imageshack .. forgot :P

Similar Threads

  1. Drawing 3d pie
    By toutarrive in forum Qt Programming
    Replies: 3
    Last Post: 5th September 2009, 16:21
  2. Optimizing polygon clipping in QGraphicsScene drawing
    By maverick_pol in forum Qt Programming
    Replies: 1
    Last Post: 28th September 2008, 20:41
  3. Optimizing redrawing in the scene
    By maverick_pol in forum Qt Programming
    Replies: 4
    Last Post: 28th November 2007, 17:00
  4. Pasting code from code tag in emacs
    By Gopala Krishna in forum General Discussion
    Replies: 0
    Last Post: 16th February 2007, 05:47
  5. Optimizing filterAcceptsRow() to filter a tree
    By vfernandez in forum Qt Programming
    Replies: 1
    Last Post: 4th January 2007, 12:50

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.