Skip to content

Avoid some numerical errors

Patrick Storz requested to merge ede123/lib2geom:numerical_errrors into master

While trying to figure out why some of the Inkscape CLI tests produced different output in 64-bit builds compared to 32-bit builds I noticed some issues related to limited numeric precision.

While I couldn't solve the rendering differences (I guess they're in cario after all...) I was able to apply two fixes that particularly improve handling of circles and ellipses in Inkscape.

  • The first commit implements a special case for scaling of unrotated ellipses. As every circle / ellipse in Inkscape is represented as an un-rotated 2Geom::Ellipse this should have a positive effect on overall accuracy and performance while handling these shapes.
  • The second commit addresses the issue that std::sin(M_PI/2) != 1, which resulted in all circles / ellipses in Inkscape having inexact internal representations (as they use elliptical paths with nodes at polar coordinates 0, pi/2, pi, 3pi/2 and 2pi which were not represented exactly due to the numerical errors.

Result: Before these changes a circle like

<circle cx="100" cy="100" r="93"/>

would end up in Inkscape with an internal representation of (you can see that directly in Inkscape when setting numeric precision to 20 digits or similar and using "Object to path"):

M 193,100 A 93.00000000000001,93.00000000000001 0 0 1 100,193 93.00000000000001,93.00000000000001 0 0 1 7,100 93.00000000000001,93.00000000000001 0 0 1 100,7 93.00000000000001,93.00000000000001 0 0 1 193,99.99999999999997

With this MR applied:

M 193,100 A 93,93 0 0 1 100,193 93,93 0 0 1 7,100 93,93 0 0 1 100,7 93,93 0 0 1 193,100

Merge request reports