Discussion:
GDI(+) scaling and precision problem
(too old to reply)
R.Wieser
2021-03-19 13:05:46 UTC
Permalink
Hello all,

I've written a small program using GDI / GDI+ to draw OpenStreetMap data
onto an image and save that. While doing that I thought I could use GDIs
scaling and translation to have draw the data at the 0,0 point and fitting
the image.

Alas, that did not quite want to work, as provided values where quite small
but with a largish offset, causing small changes to disappear into the
limited precision a 32-bit float has.

Question: is there a way I can tell GDI to use 64-bit numbers ? If not
another 2D drawing method available that will give me a better precision ?
I've just been looking at DirectDraw, but it looks to be carried by GDI(+),
meaning it likely also uses 32-bit floats ....

Regards,
Rudy Wieser
Christian Astor
2021-03-21 09:56:15 UTC
Permalink
In GDI+, you can change SmoothingMode
Otherwise, the best APIs to draw on Windows is Direct2D
But it is mainly for animations as it is hardware accelerated (they are
perfect on my Windows 10 OS even without real graphic card (Intel(R) HD
Graphics))
Post by R.Wieser
Hello all,
I've written a small program using GDI / GDI+ to draw OpenStreetMap data
onto an image and save that. While doing that I thought I could use GDIs
scaling and translation to have draw the data at the 0,0 point and fitting
the image.
Alas, that did not quite want to work, as provided values where quite small
but with a largish offset, causing small changes to disappear into the
limited precision a 32-bit float has.
Question: is there a way I can tell GDI to use 64-bit numbers ? If not
another 2D drawing method available that will give me a better precision ?
I've just been looking at DirectDraw, but it looks to be carried by GDI(+),
meaning it likely also uses 32-bit floats ....
Regards,
Rudy Wieser
R.Wieser
2021-03-21 16:08:31 UTC
Permalink
Christian,
Post by Christian Astor
In GDI+, you can change SmoothingMode
:-) what the line /looks/ when its drawn is not the problem (it looks fine
to me). The problem is that when I try to draw a line between two points
that are close together no line is drawn.

Take the below area :

<bounds minlat="48.1400000" minlon="11.5400000" maxlat="48.1450000"
maxlon="11.5430000"/>

The delta X (lon) is 0.003, the delta Y (lat) is 0.005. There can be
50.000 nodes (vertices) in that area. Some of them /very/ close together
(some used to indicate outlines of building, houses and even just garden
sheds).

As I'm drawing the result onto a 2000x2000 image the whole has to be
upscaled quite a bit - about 2,000 / 0.005 -> 400,000 times.

The precision of a 32-bit float is just shy of 7 digits. Lets say that the
precision is about 25 times larger (10mil / 0.4 mil) than the scaling value.
That means that all coordinates are "rounded" to a grid of 80 pixels (2000 /
25). And that simply won't do I'm afraid. :-|
Post by Christian Astor
Otherwise, the best APIs to draw on Windows is Direct2D
Grumble , grumble ... I see I forgot something rather important : I'm
trying to get it to work on XPsp3 (yeah old, I know :-) ), for which
Direct2D is not available. DirectDraw is is the best it offers.

I'm going to take a peek if DirectX9 in ortho (overlay) mode can do the
trick ...

Regards,
Rudy Wieser

Loading...