Unprecise rendering of huge WPF visuals - any solutions?
When rendering huge visuals in WPF, the visual gets distorted and more distorted with increasing coordinates. I assume that it has something to do with the floating point data types used in the render pipeline, but I'm not completely sure. Either way, I'm searching for a practical solution to solve the problem.
To demonstrate what I'm talking about, I created a sample application which just contains a custom control embedded in a ScrollViewer that draws a sine curve.
You can see here that the drawing is alright for double values <= 2^24 (in this case the horizontal coordinate value), but from that point 开发者_StackOverflowon it gets distorted.
The distortion gets worse at 2^25 and so the distortion continues to increase with every additional bit until it just draws some vertical lines.
For performance reasons I'm just drawing the visible part of the graph, but for layouting reasons I cannot "virtualize" the control which would make this problem obsolete. The only solution I could come up with is to draw the visible part of the graph to a bitmap, and then render the bitmap at the appropriate point - but there I have again the precision problem with big values, as I cannot accurately place the bitmap at the position where I need it.
Does anybody have an idea how to solve this?
It is not WPF's fault.
Floating point numbers get less and less precise the farther from zero they are - it is a cost of stuffing enormous data range (-Inf, +Inf) into 32 (float) / 64 (double) bits of data space. Floats actually become less precise than integer at around 2^30.
64bit integers have constant spacing (1), but have limited range of −9,223,372,036,854,775,808 to +9,223,372,036,854,775,807.
You may also consider using Decimal type (which however has also limited value range).
(update: oh didnt see how old this post was... i guess i clicked the wrong filter button in stack overflow...)
The relative precision is relevant here. So just saying "look 2^24 is fine and 2^25 is not" is not enough information. You said it is a sin, thus I guess y-axis max and min never changes between those pictures. So y-axis doesnt matter. Furthermore the x-step size stays the same, i guess? But you did not tell us the sin period length or the x-step size, you chose. That is relevant here. The relative precision of the x-size steps becomes worse when you go to higher x-values, because the x-step-size becomes too small relativly to the x-value itself.
precision of c# floating point types: https://learn.microsoft.com/de-de/dotnet/csharp/language-reference/builtin-types/floating-point-numeric-types
example:
x-step size = 1.
x = 1 (no problem)
x = 1000 (no problem)
x = >2^23 (32 bit starts to get problems with step size = 1; 64 bit no problems yet)
x = >2^52 (64 bit starts to get problems with step size = 1)
精彩评论