Results 1 to 16 of 16

Thread: QPainter::drawLine(QPoint, QPoint) incorrect drawing

  1. #1
    Join Date
    Jun 2007
    Posts
    23
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Why drawing lines with integer coords is not correct:
    Qt Code:
    1. #include <QApplication>
    2. #include <QLabel>
    3. #include <QCheckBox>
    4. #include <QPainter>
    5. #include <QMouseEvent>
    6. #include <QLayout>
    7.  
    8. class DrawLine: public QWidget {
    9. Q_OBJECT
    10. public:
    11. DrawLine() : size(17), scale(40), radius(5), active(-1), hover(-1),
    12. image(size, size, QImage::Format_RGB32), round(false),
    13. antialiasing(false) {
    14. int sz = size*scale;
    15. setMinimumSize(sz, sz);
    16. int half = sz/2;
    17. pts[0] = QPoint(half/2, half);
    18. pts[1] = QPoint(half*3/2, half);
    19. renderLine();
    20. setMouseTracking(true);
    21. }
    22. void emitCoords() {
    23. QString str;
    24. if (round) {
    25. QPoint p0 = roundCoords(0);
    26. QPoint p1 = roundCoords(1);
    27. str.sprintf("P0: (%d, %d) P1: (%d, %d)", p0.x(), p0.y(), p1.x(), p1.y());
    28. } else {
    29. QPointF p0 = coords(0);
    30. QPointF p1 = coords(1);
    31. str.sprintf("P0: (%.2f, %.2f) P1: (%.2f, %.2f)", p0.x(), p0.y(), p1.x(), p1.y());
    32. }
    33. emit coordsUpdated(str);
    34. }
    35. public slots:
    36. void setRound(bool round) {
    37. this->round = round;
    38. renderLine();
    39. }
    40. void setAntialiasing(bool antialiasing) {
    41. this->antialiasing = antialiasing;
    42. renderLine();
    43. }
    44. signals:
    45. void coordsUpdated(QString coords);
    46. protected:
    47. virtual void paintEvent(QPaintEvent*) {
    48. QPainter p(this);
    49. for (int i = 0; i < size; ++i) {
    50. for (int j = 0; j < size; ++j) {
    51. QRgb cur = image.pixel(i, j);
    52. p.fillRect(i*scale, j*scale, scale, scale, QColor(cur));
    53. }
    54. }
    55. p.setPen(Qt::lightGray);
    56. int sz = size*scale;
    57. for (int i = 0; i < size; ++i) {
    58. int x = i*scale;
    59. p.drawLine(x, 0, x, sz);
    60. p.drawLine(0, x, sz, x);
    61. }
    62. p.setRenderHint(QPainter::Antialiasing);
    63. p.setPen(Qt::blue);
    64. p.drawLine(pts[0], pts[1]);
    65. p.setPen(Qt::NoPen);
    66. for (int i = 0; i < 2; ++i) {
    67. p.setBrush(i == hover ? Qt::yellow : Qt::blue);
    68. p.drawEllipse(pts[i], radius, radius);
    69. }
    70. }
    71. virtual void mousePressEvent(QMouseEvent *event) {
    72. if (active == -1 && event->button() == Qt::LeftButton) {
    73. int current = index(event->pos());
    74. if (current != -1)
    75. active = current;
    76. }
    77. }
    78. virtual void mouseReleaseEvent(QMouseEvent *event) {
    79. if (active != -1 && event->button() == Qt::LeftButton) {
    80. active = -1;
    81. }
    82. }
    83. virtual void mouseMoveEvent(QMouseEvent *event) {
    84. if (active != -1) {
    85. pts[active] = event->pos();
    86. renderLine();
    87. }
    88. int current = index(event->pos());
    89. if (current != hover) {
    90. hover = current;
    91. update();
    92. }
    93. }
    94. private:
    95. QPointF coords(int idx) {
    96. return QPointF(pts[idx])/scale;
    97. }
    98. QPoint roundCoords(int idx) {
    99. return (coords(idx) - QPointF(0.5, 0.5)).toPoint();
    100. }
    101. int index(QPoint p) {
    102. for (int i = 0; i < 2; ++i) {
    103. if (QLineF(p, pts[i]).length() <= radius)
    104. return i;
    105. }
    106. return -1;
    107. }
    108. void renderLine() {
    109. image.fill(qRgb(255, 255, 255));
    110. QPainter p(&image);
    111. p.setRenderHint(QPainter::Antialiasing, antialiasing);
    112. p.setPen(Qt::red);
    113. if (round) {
    114. p.drawLine(roundCoords(0), roundCoords(1));
    115. } else {
    116. p.drawLine(coords(0), coords(1));
    117. }
    118. emitCoords();
    119. update();
    120. }
    121. int size;
    122. int scale;
    123. int radius;
    124. int active;
    125. int hover;
    126. QImage image;
    127. QPoint pts[2];
    128. bool round;
    129. bool antialiasing;
    130. };
    131.  
    132. int main(int argc, char *argv[])
    133. {
    134. QApplication app(argc, argv);
    135. QWidget widget;
    136. QLabel label;
    137. QCheckBox round("Round coords");
    138. QCheckBox antialiasing("Antialiasing");
    139. DrawLine draw;
    140. QObject::connect(&draw, SIGNAL(coordsUpdated(QString)), &label, SLOT(setText(QString)));
    141. QObject::connect(&round, SIGNAL(toggled(bool)), &draw, SLOT(setRound(bool)));
    142. QObject::connect(&antialiasing, SIGNAL(toggled(bool)), &draw, SLOT(setAntialiasing(bool)));
    143. QGridLayout layout;
    144. layout.addWidget(&round, 0, 0);
    145. layout.addWidget(&antialiasing, 0, 1);
    146. layout.addWidget(&label, 0, 2);
    147. layout.addWidget(&draw, 1, 0, 1, 3);
    148. layout.setColumnStretch(2, 1);
    149. widget.setLayout(&layout);
    150. widget.show();
    151. draw.emitCoords();
    152. return app.exec();
    153. }
    154.  
    155. #include "main.moc"
    To copy to clipboard, switch view to plain text mode 

    QPainter-DrawLine.jpg

  2. #2
    Join Date
    Jun 2007
    Posts
    23
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Nobody uses QPainter::drawLine(QPoint, QPoint) or I am doing something wrong with this function?

  3. #3
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    What you are doing wrong is how you ask your question.
    http://www.catb.org/esr/faqs/smart-questions.html#code

    Specifically, it looks like the problem is in your position math - check it.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  4. #4
    Join Date
    Jun 2007
    Posts
    23
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Quote Originally Posted by high_flyer View Post
    What you are doing wrong is how you ask your question.
    Provided rather simple compilable example that reproduces the problem. What is wrong about it?

    Quote Originally Posted by high_flyer View Post
    Specifically, it looks like the problem is in your position math - check it.
    Ok, lets remove all user interaction and use hard coded values for the function:
    Qt Code:
    1. #include <QApplication>
    2. #include <QPainter>
    3. #include <QWidget>
    4.  
    5. class DrawLine: public QWidget {
    6. public:
    7. DrawLine() : size(15), scale(40), image(size, size, QImage::Format_RGB32) {
    8. int sz = size*scale;
    9. setMinimumSize(sz, sz);
    10. renderLine();
    11. }
    12. protected:
    13. virtual void paintEvent(QPaintEvent*) {
    14. QPainter p(this);
    15. for (int i = 0; i < size; ++i) {
    16. for (int j = 0; j < size; ++j) {
    17. QRgb cur = image.pixel(i, j);
    18. p.fillRect(i*scale, j*scale, scale, scale, QColor(cur));
    19. }
    20. }
    21. p.setPen(Qt::lightGray);
    22. int sz = size*scale;
    23. for (int i = 0; i < size; ++i) {
    24. int x = i*scale;
    25. p.drawLine(x, 0, x, sz);
    26. p.drawLine(0, x, sz, x);
    27. }
    28. }
    29. private:
    30. void renderLine() {
    31. image.fill(qRgb(255, 255, 255));
    32. QPainter p(&image);
    33. p.setPen(Qt::red);
    34. p.drawLine(QPoint(1, 4), QPoint(11, 2));
    35. }
    36. int size;
    37. int scale;
    38. QImage image;
    39. };
    40.  
    41. int main(int argc, char *argv[])
    42. {
    43. QApplication app(argc, argv);
    44. DrawLine draw;
    45. draw.show();
    46. return app.exec();
    47. }
    To copy to clipboard, switch view to plain text mode 
    Look at how y-coord is not respected.

  5. #5
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Provided rather simple compilable example that reproduces the problem. What is wrong about it?
    1. That you expect people to compile code for you.
    Many people, me included, do this along side their work - I have not time to compile your code and debug for you.
    I can help you narrow down the problem and offer potential problems - but you have to make it easy for me to focus on the problem - if you expect help.
    2. You have provided no hint to help any potential helper to the area of the problem, rather expect people to read all the code check all of it and tell you where the problem is.
    Nothing is wrong with doing that really, just don't act so surprised when you get no answers, that is all.

    Again, looks like a math problem - my guess its the rounding.
    What happens if you remove the rounding?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  6. #6
    Join Date
    Jun 2007
    Posts
    23
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Quote Originally Posted by high_flyer View Post
    Nothing is wrong with doing that really, just don't act so surprised when you get no answers, that is all.
    Ok, I see, thank you for your attention to my problem!

    Quote Originally Posted by high_flyer View Post
    Again, looks like a math problem - my guess its the rounding.
    What happens if you remove the rounding?
    Look at the small piece of code posted above:
    Qt Code:
    1. QPainter p(&image);
    2. p.setPen(Qt::red);
    3. p.drawLine(QPoint(1, 4), QPoint(11, 2));
    To copy to clipboard, switch view to plain text mode 
    No rounding at all, exact integer numbers are passed.

    Paint event also doesn't use any floating point calculations:
    Qt Code:
    1. virtual void paintEvent(QPaintEvent*) {
    2. QPainter p(this);
    3. for (int i = 0; i < size; ++i) {
    4. for (int j = 0; j < size; ++j) {
    5. QRgb cur = image.pixel(i, j);
    6. p.fillRect(i*scale, j*scale, scale, scale, QColor(cur));
    7. }
    8. }
    9. p.setPen(Qt::lightGray);
    10. int sz = size*scale;
    11. for (int i = 0; i < size; ++i) {
    12. int x = i*scale;
    13. p.drawLine(x, 0, x, sz);
    14. p.drawLine(0, x, sz, x);
    15. }
    16. }
    To copy to clipboard, switch view to plain text mode 
    Note that size and scale are integer values.

    Now lets look at the picture:
    Qt-5.1-DrawLine.png

    The question is: why points (1, 4) and (11, 2) are not painted at all even if they were passed to the call of QPainter::drawLine?

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

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Have you verified using the line drawing algorithm that they should be painted?
    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.


  8. #8
    Join Date
    Jun 2007
    Posts
    23
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Quote Originally Posted by wysota View Post
    Have you verified using the line drawing algorithm that they should be painted?
    Do you mean that drawing of line segment from pixel (x0, y0) to pixel (x1, y1) doesn't require filling these two pixels?

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

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Quote Originally Posted by kamre View Post
    Do you mean that drawing of line segment from pixel (x0, y0) to pixel (x1, y1) doesn't require filling these two pixels?
    I don't know, I haven't checked that using the line drawing algorithm. I'm asking whether you have done that since you claim something is wrong.
    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.


  10. #10
    Join Date
    Jun 2007
    Posts
    23
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Quote Originally Posted by wysota View Post
    I don't know, I haven't checked that using the line drawing algorithm. I'm asking whether you have done that since you claim something is wrong.
    I suppose you are joking, but lets look at the algorithms.

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

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    No, I'm not joking. You say something is wrong with the line so I'm asking whether this conclusion comes from your internal belief that the start and end points should be forced to be part of the line or whether you actually checked Qt's algorithm and found a flaw in it.
    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.


  12. #12
    Join Date
    Jun 2007
    Posts
    23
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Quote Originally Posted by wysota View Post
    I'm asking whether this conclusion comes from your internal belief that the start and end points should be forced to be part of the line
    This is the expected behavior of drawing line segment with pixel-based coords, is not it? It works so in other 2d drawing libraries like Cairo/Java2D.

    But in Qt I have the following inconsistent behavior:
    Qt Code:
    1. void renderLine() {
    2. image.fill(qRgb(255, 255, 255));
    3. QPainter p(&image);
    4. // these line segments with red color fill start/end points
    5. p.setPen(Qt::red);
    6. p.drawLine(QPoint(7, 2), QPoint(7, 5));
    7. p.drawLine(QPoint(9, 7), QPoint(12, 7));
    8. p.drawLine(QPoint(7, 9), QPoint(7, 12));
    9. p.drawLine(QPoint(2, 7), QPoint(5, 7));
    10. p.drawLine(QPoint(5, 5), QPoint(3, 3));
    11. p.drawLine(QPoint(9, 9), QPoint(11, 11));
    12. // these line segments with blue color doesn't fill start/end points
    13. // looks like y-coord is not respected
    14. p.setPen(Qt::blue);
    15. p.drawLine(QPoint(9, 5), QPoint(11, 3));
    16. p.drawLine(QPoint(5, 9), QPoint(3, 11));
    17. }
    To copy to clipboard, switch view to plain text mode 
    Qt-DrawLine-Inconsistent.png
    Quote Originally Posted by wysota View Post
    whether you actually checked Qt's algorithm and found a flaw in it
    Don't know about algorithm used in Qt and whether it has flaws, as user of the Qt I have just tried to draw something simple with QPainter::drawLine and it didn't work in expected and consistent way.

    My question is: why QPainter::drawLine works so inconsistent and what can I do to get expected results from it?

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

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Sorry, I don't understand what you mean. This is the result of your code on an image scaled up 10 times:

    star.png

    What is inconsistent here?

    The code used:

    Qt Code:
    1. #include <QtGui>
    2.  
    3. void renderLine(QImage &image ) {
    4. image.fill(qRgb(255, 255, 255));
    5. QPainter p(&image);
    6. // these line segments with red color fill start/end points
    7. p.setPen(Qt::red);
    8. p.drawLine(QPoint(7, 2), QPoint(7, 5));
    9. p.drawLine(QPoint(9, 7), QPoint(12, 7));
    10. p.drawLine(QPoint(7, 9), QPoint(7, 12));
    11. p.drawLine(QPoint(2, 7), QPoint(5, 7));
    12. p.drawLine(QPoint(5, 5), QPoint(3, 3));
    13. p.drawLine(QPoint(9, 9), QPoint(11, 11));
    14. // these line segments with blue color doesn't fill start/end points
    15. // looks like y-coord is not respected
    16. p.setPen(Qt::blue);
    17. p.drawLine(QPoint(9, 5), QPoint(11, 3));
    18. p.drawLine(QPoint(5, 9), QPoint(3, 11));
    19. }
    20.  
    21.  
    22. int main(int argc, char **argv) {
    23. QApplication app(argc, argv);
    24. QLabel l;
    25. QImage img(16, 16, QImage::Format_ARGB32_Premultiplied);
    26. renderLine(img);
    27. img = img.scaled(160, 160);
    28. l.setPixmap(QPixmap::fromImage(img));
    29. l.show();
    30. return app.exec();
    31. }
    To copy to clipboard, switch view to plain text mode 
    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.


  14. #14
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    I don't know what is different in the code you supplied here to the actual application you are coding.
    I just ran your example code from the first post (because I could not see anything wrong with it and got curious) and it works perfectly, see attachment.
    What ever it is which is going wrong its not in that code.
    ScreenHunter_56 Sep. 18 13.51.jpg

    EDIT: ah, wysota beat me to it :-)
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  15. #15
    Join Date
    Jun 2007
    Posts
    23
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    Quote Originally Posted by wysota View Post
    What is inconsistent here?
    This is perfectly fine result! And I also would like to obtain the same one.

    But running your code (changed include to "QtWidgets") with my Qt 5.1.1 MinGW-OpenGL on Windows 7 looks like this:
    Qt-DrawLine-Consistent.png
    Why do I have a different picture?

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

    Default Re: QPainter::drawLine(QPoint, QPoint) incorrect drawing

    I have the same error you have when using Qt5.1 beta on Linux. I don't know whether this is caused by Qt5 or OpenGL. Using OpenGL would explain it but I can hardly believe QImage uses OpenGL to draw a line. You could file a bug report on this or compare line drawing algorithms in Qt4 and Qt5.
    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.


Similar Threads

  1. Max and min from QVector<QPoint>
    By awpitt13 in forum Newbie
    Replies: 4
    Last Post: 14th February 2012, 01:18
  2. Getting widget from Qpoint
    By codeman in forum Qt Programming
    Replies: 1
    Last Post: 22nd June 2010, 15:39
  3. QtScript QPoint
    By bunjee in forum Qt Programming
    Replies: 2
    Last Post: 27th May 2009, 09:33
  4. QPoint Limitation
    By archanasubodh in forum Qt Programming
    Replies: 1
    Last Post: 5th August 2008, 10:22
  5. Confusion with QPoint
    By therealjag in forum Qt Programming
    Replies: 9
    Last Post: 14th February 2006, 17:31

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
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.