Search code examples
c++graphfloating-pointprecisionfloating-accuracy

problems with plotting very big 2d graph


its needed to plot a 2d graph consisting of 10^3 (practically can reach up to 5*10^6) points which are given in a file with a very high precision

sample points:

          x               y = f(x)
-----------------------------------------
0.0000000000000e+000 9.9453146383711e+006
1.0107375000000e-002 1.0053545400632e+007
2.0211374000000e-002 9.9475746573179e+006
3.0315250000000e-002 1.0051184341654e+007
4.0418752000000e-002 9.9500284997072e+006
5.0525375000000e-002 1.0048588691478e+007
6.0629874000000e-002 9.9527328766918e+006
7.0733748000000e-002 1.0045819834233e+007
8.0837503000000e-002 9.9556071710602e+006
...

As it can be noticed x, and f(x) are in a very non-comfortable range to plot, thus,

I wrote a function to convert them from one range [a, b] to another [c, d] in order to plot a whole graph in a rectangular area with certain dimensions (w=780 and h=550)

// mapping x from [a, b] to [c, d]
qreal Graph::mapTo(qreal x, qreal a, qreal b, qreal c, qreal d)
{
    qreal denom = b - a;

    if (denom != 0.0f)
    {
        return (x - a)*(d - c)/denom + c;
    }

    return 0.0f;
}
//...
qreal x1 = mapTo(points[i].x(), 0, maxX, 0, w);
qreal y1 = mapTo(points[i].y(), minY, maxY, 0, h);

qreal x2 = mapTo(points[i+1].x(), 0, maxX, 0, w);
qreal y2 = mapTo(points[i+1].y(), minY, maxY, 0, h);

But after this conversion huge accuracy was lost...and I got this kind of values which resulted in a straight horizontal line (instead of a curve) after plotting..

x = 0         y = 549.453
x = 0.762673  y = 549.447
x = 1.52509   y = 549.453
x = 2.2875    y = 549.447
x = 3.04988   y = 549.453
x = 3.8125    y = 549.447
x = 4.57496   y = 549.453
x = 5.33736   y = 549.447
x = 6.09976   y = 549.452

I know that some real numbers can't be represented with floating point arithmetics in computers but in this case it seems like y values lost too much accuracy isn't it ??

What Am I doing wrong that causes those values ?

What algorithms should I use to save accuracy between mathematical operations in this case ?


Solution

  • At least found why it was giving such innacurate results for y values

    Its needed to find minY and maxY for y s to correctly map them to the range [0, h] - after fixing this graph became looking more like a 2D graph of some function.

    Now there's another problem: if number of points is high (1 million) rendering gets very slow...