0

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.
Community
  • 1
  • 1
joshfindit
  • 611
  • 6
  • 27
  • possible duplicate of [How can Javascript be used to divide a circle equally so that it's correct to 1,000,000,000% zoom?](http://stackoverflow.com/questions/31079577/how-can-javascript-be-used-to-divide-a-circle-equally-so-that-its-correct-to-1) – tadman Jun 30 '15 at 17:44
  • 1
    Please stop asking the same question over and over. If you're unsatisfied with the previous answers, try and do more work yourself to come up with a partial solution. It's not clear what you're trying to ask here that differs from previous responses, nor what your ultimate objective is. Why can't you apply a transform prior to rendering your SVG that accounts for the magnification? – tadman Jun 30 '15 at 17:44
  • 1
    What the SVG specification says and what browsers implement (which is constrained by how graphics chips work amongst other things) are two different things. – Robert Longson Jun 30 '15 at 18:30
  • @tadman - Through asking the first question and doing research, it became clear that there was too many variables to get the answer. I then split it in to separate questions, each with a smaller scope than the first. – joshfindit Jul 01 '15 at 16:24

3 Answers3

3

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.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • This feels like the right answer, but I've been reading it for half an hour and am still not clear on this: floating point deals with relative precision. Is this also the case in the SVG spec? It seems that SVG uses pixels as the absolute. – joshfindit Jul 01 '15 at 15:33
  • @joshfindit That's incorrect. If SVG renderers didn't care about subpixel features, they couldn't do antialiasing. – Sneftel Jul 01 '15 at 15:35
  • I don't mean to say pixels are the smallest measurement, what I mean is, pixels being x^1. For example, if we use floating point math to draw the polygon you mentioned, and I'm understanding what you're saying the math itself doesn't seem to care whether 1e-7 is the size of an atom or the size of the universe; it still works the same. SVG does seem to care about the size, with 1e-7 being calculated as smaller than a pixel. I'm ready for this to also be incorrect, I'm still trying to understand. – joshfindit Jul 01 '15 at 16:46
  • @joshfindit The units don't matter. Obviously at the end of the transformation pipeline one pulls out pixel coordinates; but the scaling on the way there is merely a matter of linear algebra. The same thing is true of 3D rendering: the fact that eventually the numbers boil down to pixel row/column does not constrain the units in use for world coordinates. – Sneftel Jul 01 '15 at 17:37
  • Thank you. Not only did you answer the question, but you also lead to my understanding the associated questions. – joshfindit Jul 03 '15 at 15:22
1

TL;DR: It is possible to create such an SVG file, but it's impossible to know if a renderer or other tools that merely follow the spec will render/process it correctly.

This is a case of the SVG standard being too vague. Since the renderers, canvses, etc. only have to follow the spec, the realistic answer is: you can create it, but it won't be usable for what you intend to use it for.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
-1

Most likely no.

The double has around 53 bits precision, so when doing a multiplication of 1e9 percent you could get a small amount of, but there are no guarantees. Maybe not enough to not stay in the correct pixel, but I guess you should create your own solution working and have a look at rasterisation, because that's what you seem to need to know more about.

claj
  • 5,172
  • 2
  • 27
  • 30