Главная / Графические системы / Рисование отрезков и окружностей

Рисование отрезков и окружностей

Лабораторная работа №1.

1 Обобщенный целочисленный алгоритм Брезенхема для построения отрезков.

Брезенхем предложил подход, позволяющий разрабатывать так называемые инкрементные алгоритмы, основой которых является построение циклов вычисления координат на основе только целочисленных операций сложения/вычитания без использования умножения и деления. За счет этого достигается большее быстродействие алгоритма.

Алгоритм построения отрезка выполняется как последовательное вычисление координат соседних пикселов путем добавления приращений координат. Приращения расчитываются на основе анализа функции погрешности.

Предполагается, что концы отрезка (x1, y1) и (x2, y2) не совпадают, все переменные считаются целыми, функция Sign возвращает –1, 0, 1 для отрицательного, нулевого и положительного аргумента соответственно.

Инициализация переменных:

X = x1

Y = y1

DX = |x2 – x1|

DY = |y2 – y1|

S1 = sign(x2 – x1)

S2 = sign(y2 – y1)

Обмен значений DX и DY в зависимости от углового коэффициента наклона отрезка

If DY > DX then

tmp = DX

DX = DY

DY = tmp

obm = 1

Else

Obm = 0

End if

Инициализация e с поправкой на половину пиксела

E = 2 * DY – DX

Основной Цикл

For i = 1 to DX

Plot(x, y)

While e >= 0

If obm = 1 then x = x + s1

Else y = y + s2

End if

E = e – 2 * DX

End while

If obm = 1 then y = y + s2

Else x = x + s1

End if

E = e + 2 * DY

Next i

Finish

Рассмотрим пример работы приведенного выше алгоритма Брезенхема для отрезка (2, 3), (8, 6). Этот алгоритм восьмисвязный, т. е. при вычислении приращений координат для перехода к соседнему пикселу возможны восемь случаев.

Рис. 1.

2 Алгоритм Брезенхема для генерации окружности

Для начала заметим, что необходимо сгенерировать только одну восьмую часть окружности. Остальные ее части могут быть получены последовательными отражениями. Если сгенерирован первый октант (от 0 до 45° против часовой стрелки), то второй октант можно получить зеркальным отражением относительно прямой y = x, что дает в совокупности первый квадрант. Первый квадрант отражается относительно прямой x = 0 для получения соответствующей части окружности во втором квадранте. Верхняя полуокружность отражается относительно прямой y = 0 для завершения построения.

Рассмотрим первую четверть окружности с центром в начале координат. Заметим, что если работа алгоритма начинается в точке x = 0, y = R, то при генерации окружности по часовой стрелке в первом квадранте y является монотонно убывающей функцией аргумента x. Аналогично, если исходной точкой является y = 0, x = R, то при генерации окружности против часовой стрелки x будет монотонно убывающей функцией аргумента y.

Пошаговый алгоритм Брезенхема для генерации окружности в первом квадранте (все переменные – целые).

Инициализация переменных

x = 0

y = r

D = 2 * (1 – r)

Limit = 0

1 plot(x, y)

if y <= limit then 4

if D < 0 then 2

if D > 0 then 3

if D = 0 then 20

2 s = 2 * D + 2 * y – 1

if s <= 0 then 10

if s > 0 then 20

3 s = 2 * D – 2 * x – 1

if s <= 0 then 20

if s > 0 then 30

10 x = x +1

D = D + 2 * x + 1

goto 1

20 x = x + 1

y = y – 1

D = D + 2 * x – 2 * y + 2

goto 1

30 y = y – 1

D = D – 2 * y + 1

goto 1

4 finish

Переменная предела limit устанавливается в нуль для окончания работы алгоритма на горизонтальной оси, в результате генерируется окружность в первом квадранте. Если необходим лишь один из октантов, то второй октант можно получить с помощью установки limit = integer(R / Ö2), а первый – с помощью отражения второго октанта относительно прямой y = x.

3 Задания

На языке высокого уровня (С++) написать две функции DrawLine и DrawCircle для рисования отрезков и окружностей соответственно. С помощью функции DrawLine нарисовать в центре экрана координатные оси X и Y. Рисование следует производить относительно выбранной системы координат XY. Для этого необходимо преобразование относительных координат точек объектов в их абсолютные координаты внутри клиентской области окна. Например, центр системы координат – точка (0, 0) – будет иметь асолютные координаты (ширина_окна / 2, высота_окна / 2), а точка (-1, 2) – (ширина_окна / 2 — 1, высота_окна / 2 + 2).

Варианты:

Нарисовать в окне прямоугольник с закругленными углами;

Нарисовать в окне прямоугольник и описать вокруг него окружность;

Нарисовать в окне треугольник и описать вокруг него окружность.

4 Примечания

Для рисования понадобятся следующие функции Win32 API.

Функция SetPixel устанавливает пиксел в определенных координатах и определенного цвета.

COLORREF SetPixel (

HDC hDC, // дескриптор контекста устройства

Int X, // x-координата пиксела

Int Y, // y-координата пиксела

COLORREF crColor // цвет пиксела

);

Функция GetDC возвращает дескриптор контекста устройства отображения (DC) для клиентской области определенного окна.

HDC GetDC (

HWND hWnd // дескриптор окна

);

Макрокоманда RGB создает 32-разрядное значение цвета по значениям интенсивностей красного, зеленого и синего цветов (RGB).

COLORREF RGB(

BYTE bRed, // красный компонент цвета

BYTE bGreen, // зеленый компонент цвета

BYTE bBlue // синий компонент цвета

);

Функция GetClientRect восстанавливает координаты клиентской области окна. Клиентские координаты определяют левый верхний и нижний правый углы клиентской области.

BOOL GetClientRect (

HWND hWnd, //дескриптор окна

LPRECT lpRect //адрес структуры для клиентских

); //координат

LpRect – указатель на структуру

Typedef struct tagRECT {

LONG left; //x левого верхнего угла

LONG top; //y левого верхнего угла

LONG right; //x правого нижнего угла

LONG bottom //y правого нижнего угла

} RECT;

Которая получает клиентские координаты. Левые верхние элементы – нуль, правые нижние – содержат ширину и высоту окна.