многоугольника, то решение задачи тривиально – точка лежит внутри, если количество
точек пересечения нечетно, и снаружи, если четно.
Ясно, что для любого многоугольника можно построить луч, не проходящий ни
через одну из вершин. Однако построение луча связано с определенными трудностями и,
кроме того, проверка пересечения с произвольным лучом сложнее, чем с фиксированным,
например горизонтальным.
Возьмем луч, выходящий из точки A, и рассмотрим к чему может привести
прохождение луча через вершину. Основные возможные случаи изображены на рисунке
4.3.1. В простейших случаях а и в, когда ребра, выходящие из соответствующей вершины,
лежат либо по разные стороны от луча, либо по одну сторону от луча, можно
договориться, что четность количества пересечений меняется в первом случае и не
меняется во втором. К случаям б и г такой подход непосредственно не годится. Несколько
изменим его, заметив, что в случаях а и б вершины, лежащие на луче являются
экстремальными значениями в тройке вершин треугольника. В других случаях экстремума
нет.
В результате приходим к следующему алгоритму. Все отрезки, кроме
горизонтальных, проверяются на пересечение с горизонтальным лучом, выходящим из
точки A. При попадании луча в вершину пересечение засчитывается только с теми
отрезками, выходящими из вершины, для которых она является верхней.
4.4 Закраска области, заданной цветом границы
Рассмотрим область, ограниченную набором пикселей заданного цвета, и точку (x,
y), лежащую внутри этой области.
Задача заполнения области заданным цветом в случае, когда область не является
выпуклой, может оказаться довольно сложной.
//File fill1.cpp
void PixelFill(int x, int y, int BorderColor, int color)
{
int c=getpixel(x,y);
if((c!=BorderColor) && (c!=color))
{
putpixel(x,y,color);
PixelFill(x-1,y,BorderColor,color);
PixelFill(x+1,y,BorderColor,color);
PixelFill(x,y-1,BorderColor,color);
PixelFill(x,y+1,BorderColor,color);
}
}
Простейший алгоритм, показанный выше, хотя и абсолютно корректно
заполняющий даже самые сложные области, является слишком неэффективным, так как
уже для отрисованного пикселя функция вызывается еще три раза, и, кроме того, требует
слишком большого стека из-за большой глубины рекурсии.
Поэтому для решения задачи закраски области
предпочтительнее алгоритмы, способные
обрабатывать сразу целые группы пикселей.
Рассмотрим версию одного из самых
популярных алгоритмов подобного типа, когда для
заданной точки (x, y) определяется и заполняется
максимальный отрезок