绘制非常大的二维图的问题
problems with plotting very big 2d graph
它需要绘制一个由 10^3
(实际上可以达到 5*10^6
)点组成的二维图,这些点在文件中以非常高的精度给出
样本点:
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
...
可以注意到 x, and f(x)
处于非常不适合绘制的范围内,因此,
我编写了一个函数将它们从一个范围 [a, b]
转换为另一个 [c, d]
以便在具有特定尺寸的矩形区域中绘制整个图形(w=780
和 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);
但在这种转换之后,巨大的准确性丢失了......我得到了这种值,在绘图后产生了一条水平直线(而不是曲线)......
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
我知道某些实数无法在计算机中用 floating point
算术表示,但在这种情况下,y
值似乎失去了太多的准确性,不是吗??
我做错了什么导致这些值?
在这种情况下,我应该使用什么算法来保存数学运算之间的准确性?
至少找到了为什么 y
值
给出如此不准确的结果
它需要为 y
找到 minY
和 maxY
以将它们正确映射到范围 [0, h]
- 修复后此图看起来更像一个 2D一些函数的图形。
现在还有另一个问题:如果点数很高(100 万),渲染会变得很慢...
它需要绘制一个由 10^3
(实际上可以达到 5*10^6
)点组成的二维图,这些点在文件中以非常高的精度给出
样本点:
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
...
可以注意到 x, and f(x)
处于非常不适合绘制的范围内,因此,
我编写了一个函数将它们从一个范围 [a, b]
转换为另一个 [c, d]
以便在具有特定尺寸的矩形区域中绘制整个图形(w=780
和 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);
但在这种转换之后,巨大的准确性丢失了......我得到了这种值,在绘图后产生了一条水平直线(而不是曲线)......
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
我知道某些实数无法在计算机中用 floating point
算术表示,但在这种情况下,y
值似乎失去了太多的准确性,不是吗??
我做错了什么导致这些值?
在这种情况下,我应该使用什么算法来保存数学运算之间的准确性?
至少找到了为什么 y
值
它需要为 y
找到 minY
和 maxY
以将它们正确映射到范围 [0, h]
- 修复后此图看起来更像一个 2D一些函数的图形。
现在还有另一个问题:如果点数很高(100 万),渲染会变得很慢...