Я изучаю компьютерную графику и натолкнулся на алгоритм отсечения линии Коэна-Сазерленда. Где у нас есть сегмент линии, определяемый точками P1
и P2
, и мы пытаемся выяснить, будет ли он обрезаться внутри отсекающего прямоугольника (обычно определяемого шириной и высотой экрана, а верхний левый - [0, 0])Зачем нам нужно округлять при вычислении x-перехвата горизонтальной линии в алгоритме отсечения Коэна-Сазерленда?
алгоритм прост, мы просто проверяем каждую точку, чтобы увидеть, если х точки и у находятся вне границ:
if (y1 < min_clip_y)
p1_code |= CLIP_NORTH;
else if (y1 > max_clip_y)
p1_code |= CLIP_SOUTH;
if (x1 < min_clip_x)
p1_code |= CLIP_WEST;
else if (x1 > max_clip_x)
p1_code |= CLIP_EAST;
// Same deal with x2, y2
если оба p1_code
и p2_code
не равны нулю, мы отвергаем линию, если они оба равны нулю, мы принимаем его, в противном случае мы продолжаем тестирование, чтобы найти точку пересечения клипа с краем прямоугольника прямоугольника пересечения:
switch(p1_code)
{
case CLIP_NORTH:
{
yc1 = min_clip_y;
xc1 = x1 + 0.5f + (min_clip_y - y1) * (x2-x1)/(y2-y1);
} break;
// other cases...
}
Я прочитал это из книги. Я понимаю, как мы выводим уравнение х-перехвата, я просто не понимаю, почему мы добавляем 0.5f для округления до следующего целого числа. Зачем нам крутиться?
Спасибо!
Спасибо за ответ. Книга, которую я отношусь относительно старой, да, но она единственная в своем роде, по крайней мере, я не видел много книг, похожих на нее. Это Андре Ламоте, через создание средства визуализации программного обеспечения, но сначала вы создаете каркасный движок, в котором вы рисуете линии и треугольники через Bresenham и, следовательно, отсекаете линию. То, чего я не получаю, - это то, почему округляется до следующего целого, а не от текущего? т. е. если результат был «2,3», почему круглые до 3, а не до 2? – vexe
@vexe У вас это неправильно. (int) (x + 0,5) имеет эффект округления до ближайшего int, потому что преобразование в int делает усечение. (2,3 + 0,5) усечено 2, а не 3. Я хочу сказать, что это глупое место для преобразования в целое. Это делает алгоритм значительно менее точным. Сделайте обрезку полностью в поплавках, затем округлите до пиксельных координат. – Gene
«Сделайте обрезку полностью в поплавках, затем округлите до координат пикселей». Вы имеете в виду, что входные координаты находятся в поплавке, а затем округляют их в конце? «У вас это неправильно» - ОК 2.3 был плохим примером. Take 2.7, int (2.7) == 2, int (2.7 + 0.5) == 3, я думаю, глядя, что я знаю ответ сейчас, потому что 2.7 ближе к 3, чем к 2, поэтому причина, по которой мы должны приближаться целочисленное значение для фактического значения с плавающей запятой. – vexe