Подтвердить что ты не робот

Каковы жесткие рамки для рисования координат в GDI +?

Я рисую кривую интерполяции следующим образом:

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 и остановки процесса. (float mix/max не работает кстати. Я все еще получаю исключение.)

4b9b3361

Ответ 1

ОК, мне нужно было знать, что я тестировал постепенно и придумывал эти ограничения:

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, но у меня еще не было возможности изучить это.

Кроме того, после завершения этого эксперимента, а затем Googling для значения 1073741951, я столкнулся с этой статьей, которая коррелирует мои выводы. Я также нашел это в некотором некотическом архиве кода, который упоминает приблизительную, хотя и не точную корреляцию с ограничениями по платам.

Ответ 2

FYI - я столкнулся с этой ситуацией с простой реализацией 2D-графика. Когда я увеличил изображение слишком далеко, соответствующие местоположения пикселей были ПУТЕМ от области отображения и заставили Graphics.DrawLine выбросить исключение OverflowException. Поэтому, естественно, я добавил чек, чтобы убедиться, что значения, которые указаны в пределах, определенных выше. Интересно, что, когда значение Y стало слишком большим (но меньше предполагаемого положительного значения 1 073 741 951), результирующая строка была оттянута, как ожидалось (до местоположения пикселя Y, превышающего мой последний разумный момент), к составлению (вверху) окна).

После дальнейшего исследования я обнаружил, что значение 8,388,607 (0x7FFFFF) правильно рисует линию, а значение 8 388 608 (0x800000) инвертирует строку.

Похоже, что здесь используются подписанные 24-битные значения.

Ответ 3

Я не слышал о конкретных ограничениях для DrawLines() или любой другой функции рисования GDI. Почему вы не используете e.ClipRectangle в качестве ограничения?

В любом случае точки рисования вне видимой области не нужны. Просто убедитесь, что только строки отбрасываются, у которых есть обе точки снаружи.