Search code examples
mathsvgprecisionarbitrary-precision

Is it possible to create an SVG that is precise to 1,000,000,000% zoom?


Split off from: https://stackoverflow.com/questions/31076846/is-it-possible-to-use-javascript-to-draw-an-svg-that-is-precise-to-1-000-000-000

The SVG spec states that SVGs use double-precision floats for all values.

Through testing, it's easy to verify this.

Affinity designer is a vector graphics program that allows zooms up to 1,000,000,000%, and it too uses double-precision floats to do all calculations.

I would like to know from someone who deeply understands double-precision floats: is it possible create an SVG that is visually correct at 1,000,000,000% zoom?

Honestly, I'm struggling with getting a grasp on the math of this:

9007199254740992 (The max value of a double-float according to https://stackoverflow.com/a/1848953/2328064 ) is larger than 1,000,000,000 so it seems to be reasonable that if something is 2 or even 2000 wide, that it would still be small when starting at 9007199254740992 and zooming 1,000,000,000%.

Hypothetical examples as ways to approach the question:

  • If we created an SVG of a 2D slice of the entire visible universe how far could we zoom in before floating point rounding started shifting things by 1 pixel?
  • If we start with an SVG that is 1024x1024, can we create a 'microscopic' grid that is both visible and visually correct at 1,000,000,000% zoom? (Like, say, we can see 20+ equidistant squares)

Edit:

Based on everything so far, the definitive answer is yes (with some important and interesting caveats for actually viewing this SVG).

  1. In order to get the most precision at high zoom, start at the centre.
  2. The SVG spec is not designed for this level of precision. This is especially true of the spec for SVG viewers.
  3. (Not mentioned below) Typically curves are represented in software as Bézier curves, and standard Bézier curve implementations do not draw mathematically perfect circles.

Solution

  • Of course it is. Floating point math deals with relative, not absolute, precision. If you created a regular polygon at the origin, with radius 1e-7, then zoomed it to 1e7X size, you would expect to see a regular polygon with the same size and precision as an unzoomed circle with radius 1.

    If you were to create the same regular polygon with vertices centered at (0, 1e9) or so, you'd expect to see some serious error. Doubles that large do not have enough absolute precision to accurately represent a shape that small.

    However, there's another way to express "shapes far from the origin" in SVG, using a node transformation. If you were to specify the polygon relative to the origin, but give it a translation of (0,1e9), and zoomed to that point, you'd expect to see the same precision as the origin-centered polygon.

    HOWEVER however, all this assumes that the SVG renderer in question is designed to do such things in the most precise possible manner (such as composing the shape and view transformations before applying them to the vertices, rather than applying one at a time). I'm not sure if any of the SVG renderers out there go to such lengths, given the unusualness (some might say, the wrong-headedness) of such a use case.