[Interest] Weird result with QPainterPath substraction

Ch'Gans chgans at gna.org
Fri Nov 25 02:45:35 CET 2016


Hi there,

I need to substract a shape from another using QPainterPath, if the 2
shapes don't intersect and the outer fully contains the inner, the
most effective way to do that is:
resultPath = solidPath.addPath(cutoutPath);

This works well and is fast, given that the path use the right fill
rule and that each cutout is fully contain in the solid to be cut.

My problem is that sometimes i don't know if the shapes intersect or
not, if the cutouts are fully contained in the solid or not, ....So i
rely on the more generic solution:
resultPath = solidPath - cutoutPath;

First this is CPU intensive, this is not desirable but i can live with
that if there's no alternatives.
Then, my main problem, is that the subtract operation on QPainterPath
gives me really weird results. If i subtract a small circle from a
big(ger) circle, I obtain an octogonal donut.

The QPainterPath documentation warns about
"Bezier curves may be flattened to line segments due to numerical
instability of doing bezier curve intersections."
And - if i'm not wrong - QPainterPath implements arcs using bezier curves.
So it seems that this is what is happening here.

Looking at what's inside my path:
path.addEllipse(-radius, -radius, diameter, diameter), will create 4
curves (4 90 deg arcs). Now if I call simplified() on this path, I get
an octogon, each of the 4 arcs have been converted to 2 lines...

So building on that surprise and on the fact that my coordinates were
quite small (0.001 to 1.x), I decided to first scale the path up, do
my operations and then scale the result down. Magic happened, now the
arcs are flattened into hundreds of lines.
Which is quite acceptable, but not as perfect as i would like.

So here are some questions for you list:
- Is it an expected behaviour? (flattening small circles gives octagon)
- Does any one know a way around this without relying on a specialised
library/toolkit?
- Any other tip, advice or examples that would help me improve my code
(CPU usage)?

Chris



More information about the Interest mailing list