Results 1 to 3 of 3

Thread: QPainterPath::arcTo draws asymmertric "circle"

  1. #1
    Join Date
    Jun 2012
    Location
    Austria
    Posts
    22
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default QPainterPath::arcTo draws asymmertric "circle"

    I try to draw a "stadium-shape" (two half circles connected by straight lines) using QPainter on a QPainterPath. This basically works but the half circles are always slightly asymmetric. A casual viewer won't notice but for the trained eye this is really annoying.
    The details - I removed the straight lines so that it becomes clear what belongs to the arc.
    r is the radius of the (half)circles, d is the length of the straight line, a1 and a2 are the arc starting angles and a is always 180 deg for a semicircle.
    Qt Code:
    1. painter.setPen(colFont);
    2. painter.setBrush(colBack);
    3. QRectF lb(0, 0, 2*r, 2*r), rb(d, 0, 2*r, 2*r);
    4. qreal a1(90), a2(270), a(180);
    5. qDebug()<<"RBOX"<<r<<d<<lb<<rb<<a1<<a2<<a;
    6. p.moveTo(r, r);
    7. p.arcTo(lb, a1, a);
    8. p.moveTo(r+d, r);
    9. p.arcTo(rb, a2, a);
    10. painter.drawPath(p);
    To copy to clipboard, switch view to plain text mode 
    This yields
    RBOX 14 34 QRectF(0,0 28x28) QRectF(34,0 28x28) 90 270 180
    Screenshot from 2019-12-28 18-02-28.png
    Yellow and orange stuff belongs to other widgets. The gimp selection marker you see in the screenshot is 14x28 pixel - the bounding box I would expect for the half circle. As you may notice, the upper half and the lower half are not mirror images of each other - which they should be to my understanding.

    I also tried to make the width and height of the bounding box uneven integers, so that the circle has true "center pixels". Doesn't make a big difference, the asymmetry remains:
    Qt Code:
    1. painter.setPen(colFont);
    2. painter.setBrush(colBack);
    3. QRectF lb(0, 0, 2*r+1, 2*r+1), rb(d, 0, 2*r+1, 2*r+1);
    4. qreal a1(90), a2(270), a(180);
    5. qDebug()<<"RBOX"<<r<<d<<lb<<rb<<a1<<a2<<a;
    6. p.moveTo(r, r);
    7. p.arcTo(lb, a1, a);
    8. p.moveTo(r+d, r);
    9. p.arcTo(rb, a2, a);
    10. painter.drawPath(p);
    To copy to clipboard, switch view to plain text mode 
    RBOX 14 34 QRectF(0,0 29x29) QRectF(34,0 29x29) 90 270 180
    gimp box is now 15x29
    Screenshot from 2019-12-28 18-13-06.png
    Has anyone an idea why the upper half of the semicircle is not a mirror image of the lower half?

    Qt 5.7.0 open source on Ubuntu 18.04.3
    Last edited by stryga42; 28th December 2019 at 20:44.

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QPainterPath::arcTo draws asymmertric "circle"

    Your QPainterPath is not closed, so the outline is not complete, which more than likely explains the half-and-half colouring along the diameter. You need to call closeSubpath() as described here:
    https://doc.qt.io/qt-5/qpainterpath.html#arcTo

    I would guess that anti-aliasing combined with the coordinate system has something to do with the remaining asymmetry
    You could try it without the anti-aliasing render hint.
    There's quite a lot of detail here: https://doc.qt.io/qt-5/coordsys.html#rendering

    You are drawing full semicircles, so you could also use QPainter::drawPie() to see if that result is more to your liking. (The restrictions on angles in this function suggest it is relying heavily on symmetry for speed.)

  3. #3
    Join Date
    Jun 2012
    Location
    Austria
    Posts
    22
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QPainterPath::arcTo draws asymmertric "circle"

    Thank you for your suggestions!

    not closed path: that just happened because I removed the straight lines to make clear what belongs to the arc - not relevant to the problem, sorry for the confusion.

    rendering hints, especially QPainter::Antialiasing. Good input, that solved the issue. Although the pixel pattern is still not symmetrical in a mathematical sense it is good enough even for the most nitpicking viewer.

    QPainter::drawPie(): no change, gives identical pixel patterns to QPainter::arcTo(). Seems to use the same internal engine.

    For me it looks like the underlying draw engine does not draw pixels according to the distance (center of pixel)<->(mathematically ideal position) but (lower right corner of pixel)<->(mathematically ideal position) or something like this.
    Anyway, problem solved, many thanks!

Similar Threads

  1. Replies: 1
    Last Post: 20th November 2015, 11:02
  2. QSqlError("", "Parameter count mismatch", "")
    By Alberto7 in forum Newbie
    Replies: 2
    Last Post: 9th October 2015, 23:09
  3. Replies: 3
    Last Post: 16th March 2015, 08:31
  4. QPainterPath.arcTo
    By grellsworth in forum Qt Programming
    Replies: 1
    Last Post: 18th March 2008, 18:36
  5. Translation QFileDialog standart buttons ("Open"/"Save"/"Cancel")
    By victor.yacovlev in forum Qt Programming
    Replies: 4
    Last Post: 24th January 2008, 20:05

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.