Results 1 to 16 of 16

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

Hybrid View

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

    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
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanked 1 Time in 1 Post

    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
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows
    Thanks
    21
    Thanked 418 Times in 411 Posts

    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
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanked 1 Time in 1 Post

    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
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows
    Thanks
    21
    Thanked 418 Times in 411 Posts

    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
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanked 1 Time in 1 Post

    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,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    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
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanked 1 Time in 1 Post

    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,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    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
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows
    Thanked 1 Time in 1 Post

    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,373
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Thanks
    4
    Thanked 5,019 Times in 4,795 Posts
    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.


Similar Threads

  1. Max and min from QVector<QPoint>
    By awpitt13 in forum Newbie
    Replies: 4
    Last Post: 14th February 2012, 02:18
  2. Getting widget from Qpoint
    By codeman in forum Qt Programming
    Replies: 1
    Last Post: 22nd June 2010, 16:39
  3. QtScript QPoint
    By bunjee in forum Qt Programming
    Replies: 2
    Last Post: 27th May 2009, 10:33
  4. QPoint Limitation
    By archanasubodh in forum Qt Programming
    Replies: 1
    Last Post: 5th August 2008, 11:22
  5. Confusion with QPoint
    By therealjag in forum Qt Programming
    Replies: 9
    Last Post: 14th February 2006, 18: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
  •  
Qt is a trademark of The Qt Company.