我正在渲染插值曲线:
e.Graphics.DrawLines(new Pen(Color.Red), _interpolationPoints.ToArray());
有时会抛出OverflowException。
对_interpolationPoints数组的检查以科学记数法显示了一些非常大的值,例如: {X = 0.0 Y = -1.985174E + 10}
我怀疑Y = -1.985174E + 10是GDI +无法处理的值。那很好,但是我可以绘制的最大/最小X和Y值是什么,因此约束数据(并警告用户)而不是在绘画期间捕获溢出异常?是否记录了限制?
例如,我想做这样的事情:
if (yVal < float.MinValue || yval > float.MaxValue)
throw new OverflowException("Interpolation value too large to be rendered.");
在_interpolationPoints数组的填充期间停止进程。 (浮动混合/最大不能正常工作。我仍然得到例外。)
答案 0 :(得分:9)
好的,我需要知道,所以我逐步测试并提出了这些限制:
positive: 1,073,741,951
negative: -1,073,741,760
我使用的代码看起来像这样:
int lastGoodVal = 0;
for (int i = -1073000000; i > -1073832999; i -= 1)
{
g.DrawLine(Pens.Blue, new Point(0,0), new Point(0, i));
lastGoodVal = i;
}
上面的循环是最终测试,步长为1,通过早期测试建立的一系列负值。正如您所看到的,lastGoodVal保存了最后一次成功的绘制迭代,因此我将使用它作为常量的实际限制。
我试图将这些数字与.NET基元中的值相关联,但却无法。每个限制都接近2 ^ 30的值,但并不完全在其上。任何其他见解将不胜感激。
我也只用DrawLine方法测试过。 API中的其他功能可能存在不同的限制,但我还没有机会探索它。
此外,在完成此实验,然后谷歌搜索值1073741951后,我遇到了this article,这与我的发现相关。我还在某种单声道代码存档中found this提到了浮动限制的近似但不完全相关。
答案 1 :(得分:4)
仅供参考 - 我通过2D绘图的简单实现遇到了这种情况。当我在图像上放大太远时,相应的像素位置与显示区域不同,导致Graphics.DrawLine抛出OverflowException。所以我自然而然地添加了一个检查,以确保在上面保罗定义的限制范围内的值。有趣的是,当Y值太大(但小于建议的正值1,073,741,951)时,得到的线从按预期下拉(到大于我最后一个合理点的Y像素位置)被绘制(到顶部)窗口)。
经过进一步调查后,我发现值 8,388,607 (0x7FFFFF)正确绘制了该行,并且值为8,388,608(0x800000)使该行反转。
看起来在这里使用了带符号的24位值。
答案 2 :(得分:1)
我没有听说过DrawLines()或任何其他GDI绘图功能的特定限制。为什么不使用e.ClipRectangle作为约束?
无论如何都不需要在可见区域之外绘制点。只需确保只丢弃两个点都在外面的行。