I am rendering an interpolation curve thusly:
e.Graphics.DrawLines(new Pen(Color.Red), _interpolationPoints.ToArray());
which sometimes throws an OverflowException.
Examination of the _interpolationPoints array shows some very large values in scientific notation e.g. {X = 0.0 Y = -1.985174E+10}
I suspect that Y = -1.985174E+10 is a value that GDI+ cannot handle. That's fine but what are the max/min X and Y values into which I can draw and so constrain the data (and warn the user) rather than catching the overflow exception during paint? Are the limits documented?
For example, I would like to do something like this:
if (yVal < float.MinValue || yval > float.MaxValue)
throw new OverflowException("Interpolation value too large to be rendered.");
during the population of the _interpolationPoints array and stop the process. (float mix/max does not work btw. i still get the exception.)
OK, I needed to know so I tested incrementally and came up with these limits:
positive: 1,073,741,951
negative: -1,073,741,760
The code I used looked something like this:
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;
}
The loop above was the final test, stepping by 1, through a range of negative values established by earlier tests. As you can see, lastGoodVal holds the last successful painting iteration and therefore the real limit which I'll use as a constant.
I tried to correlate these numbers to a value in the .NET primitives but couldn't. Each limit is close to the value of 2^30 but is not exactly on it. Any other insight would be much appreciated.
I also only tested with the DrawLine method. It's possible that different limits exist for other functions in the API but I have not had a chance to explore that yet.
Also, after finishing this experiment and then Googling for the value 1073741951 I came across this article which correlates my findings. I also found this in a Mono code archive of some sort which mentions a near, though not exact correlation to float limits.
FYI - I ran into this situation with a simple implementation of a 2D plot. When I zoomed in too far on the image the corresponding pixel locations were WAY off the display area and caused Graphics.DrawLine to throw an OverflowException. So naturally I added a check to ensure that the values where within the limits defined by Paul above. Interestingly though when the Y value got too large (but less than suggested positive value of 1,073,741,951) the resulting line went from being drawn down as expected (to a Y pixel location greater than my last reasonable point) to being drawn up (to the top of the window).
After further investigation I discovered that a value of 8,388,607 (0x7FFFFF) draws the line correctly and a value of 8,388,608 (0x800000) inverts the line.
Looks like signed 24-bit values are used here.
I've not heard of specific limits for DrawLines() or any other GDI drawing function. Why don't you use e.ClipRectangle as a constraint?
Drawing points outside the visible region is not needed anyway. Just make sure that only lines are discarded that have both points outside.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With