Каковы жесткие границы для рисования координат в GDI +? - PullRequest
10 голосов
/ 12 августа 2010

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

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

Ответы [ 3 ]

9 голосов
/ 12 августа 2010

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

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

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

4 голосов
/ 24 апреля 2014

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

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

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

1 голос
/ 12 августа 2010

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

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

...