- •Работа №1 Постановка задачи
- •Краткие теоретические сведения
- •Алгоритм работы программы
- •Работа №2 Постановка задачи
- •Краткие теоретические сведения
- •Работа №3 Постановка задачи
- •Обзор теории
- •Алгоритм работы программы
- •Простой алгоритм заполнения с затравкой
- •Работа №5 Задание
- •Обзор теории
- •Код программ
- •Работа №5 Задание
- •Обзор теории
- •Код программы
- •Работа №6 Задание
- •Обзор теории
- •Графика и случайные числа
- •Кривые Гильберта
- •Фракталы
- •Код программы
- •Кривая Безье
Работа №5 Задание
Реализовать в виде программы алгоритм двумерного внутреннего отсечения Сазерленда-Коэна
Обзор теории
Алгоритм отсечения Сазерленда - Коэна, основанный на разбиении отрезка.
Алгоритм, описанный в предыдущем разделе, аналогичен тому, который предложили Коэн и Сазерленд. В алгоритме двумерного отсечения отрезок отсекался поочередно каждой из сторон окна, а для полученных точек пересечения проверялась их принадлежность внутренней области окна, т. е. корректность пересечения. Эта процедура применялась сначала к отрезку P1P2 и получался отрезок P'1P2, а затем к отрезку P'1P2 и получался результирующий отрезокP'1P'2.
В алгоритме Сазерленда - Коэна отрезок тоже разбивается сторонами окна. Отличие состоит в том, что здесь не производятся проверки попадания точки пересечения внутрь окна, вместо этого каждая из пары получающихся частей отрезка сохраняется или отбрасывается в результате анализа кодов ее концевых точек. Рассмотрение отрезка P1P2 на рис. 3 показывает трудность реализации этой идеи. Если P1P2 разбивается левой стороной окна, то получается два новых отрезка P1P'1 и P'1P2. Коды концевых точек каждого из этих отрезков таковы, что оба они могут быть частично видимы. Следовательно, ни один из них нельзя отвергнуть как невидимый или оставить как видимый. Ключом к алгоритму Сазерленда - Коэна является информацию о том, что одна из концевых точек отрезка лежит вне окна. Поэтому тот отрезок, который заключен между этой точкой и точкой пересечения, можно отвергнуть как невидимый. Фактически это означает замену исходной концевой точки на точку пересечения.
Алгоритм Сазерленда - Коэна формулируется следующим образом:
Для каждой стороны окна выполнить:
Для каждого отрезка P1P2 определить, не является ли он полностью видимым или может быть тривиально отвергнут как невидимый.
Если P1 вне окна, то продолжить выполнение, иначе поменять P1 и P2 местами.
Заменить P1 на точку пересечения P1P2 со стороной окна.
Этот алгоритм иллюстрирует следующий пример.
Пример. Алгоритм отсечения Сазерленда - Коэна.
Рассмотрим отсечение отрезка P1P2 окном, показанным на рис. 3. Коды концевых точек P1 (- 3/2, 1/6) и P2 (1/2, 3/2) равны (0001) и (1000) соответственно. Этот отрезок не является ни полностью видимым, ни тривиально невидимым.
Отрезок пересекает левую сторону окна. P1 - вне окна.
Пересечение с левой стороны (x = -1) окна происходит в точке P'1 (-1, 1/2). Замена P1 на P'1 дает новый отрезок от P1 (-1, 1/2) до P2 (1/2, 3/2).
Коды концевых точек P1 и P2 теперь стали (0000) и (1000). Отрезок не является ни полностью видимым, ни тривиально невидимым.
Отрезок не пересекается с правой стороной окна. Перейти к нижней стороне.
Коды концевых точек P1 и P2 остаются по-прежнему равными (0000) и (1000). Отрезок не является ни полностью видимым, ни тривиально невидимым.
Отрезок не пересекается с нижней стороной окна. Перейти к верхней.
Коды концевых точек P1 и P2 остаются равными (0000) и (1000). Отрезок не является ни полностью видимым, ни тривиально невидимым.
Отрезок не пересекается с верхней стороной окна. P1 - не снаружи окна. Поменяв P1 на P2 местами, получили новый отрезок от P1 (1/2, 3/2) до P2 (-1, 1/2).
Точка пересечение с верхней стороной окна (y = -1) равна P'1 (-1/4, 1). Заменив P1 на P'1, получаем новый отрезок от P1 (-1/4, 1) до P2 (-1, 1/2).
Теперь коды концевых точек P1 и P2 равны (0000) и (0000). Отрезок полностью видим.
Процедура завершена.
Начертить отрезок.
Алгоритм двумерного отсечения Сазерленда — Коэна:
Окно — массив 1 х 4, содержащий координаты (хл, хп, ун, ув) сторон окна
Рр Р2 — концевые точки отрезка с координатами (PjX, P,y) и (Р2х, Р2у) соответственно
Т1код, Т2код — массивы 1 х 4, содержащие коды точек Р, и Р2
Флаг — индикатор координатной ориентации отрезка, равный' — 1, при вертикальности, 0, при горизонтальности инициализация Флаг
Флаг = 1 проверка вертикальности и горизонтальности отрезка
if Р2х - Р,х = 0 then
Флаг = - 1
else
вычисление наклона
Наклон = (Р2у - Р,у)/(Р2х - Р,х)
if Наклон = 0 then Флаг = 0
end if
для каждой стороны окна
for i = 1 to 4
call Коэн (Р,, Р2, Окно; Видимость)
if Видимость = да then 2
if Видимость = нет then 3
проверка пересечения отрезка и стороны окна
if Т1кодE - i) = Т2кодE - i) thenl
проверка нахождения Р, вне окна; если Р} внутри окна, то
поменять Р, /./ Р2 местами
if Т1кодE - i) = 0 then
Раб = Р;
Pi = р2
Р2 = Раб
end if
поиск пересечений отрезка со сторонами окна выбор соответствующей подпрограммы вычисления пересечения контроль вертикальности отрезка
if Флаг < > - 1 и i ^ 2 then
Р,у = Наклон * (OkhOj — Р,х) + Р,у
Р,х = j
else
if Флаг < > 0 then
if Флаг < > -1 then
PjX = A/Наклон) * (Okhoj - P,y) + P,x
end if
P,y = Окно{
end if
end if
1 next i
начертить видимый отрезок
2 Draw P,P2
3 finish
подпрограмма определения видимости отрезка
subroutine Коэн (Р,, Р2, Окно; Видимость)
Р,, Р2 — концевые точки отрезка с координатами (Р,х, Р,у) и
(Р2х, Р2у) соответственно.
Окно — массив 1 х 4, содержащий координаты (хл, хп, ун, ув)
сторон окна
Видимость — признак видимости отрезка равный: «нет»,
«частично», «да», если отрезок соответственно:
полностью невидим, видим частично или полностью видим
вычисление кодов концевых точек отрезка
call Конец (Р,, Окно; Т1код, Сумма1)
call Конец (Р2, Окно; Т2код, Сумма2)
предположим, что отрезок частично видим
Видимость = частично
проверка полной видимости отрезка
if Сумма 1 = 0 и Сумма 2 = 0 then
Видимость = да
else
проверка тривиальной невидимости отрезка
call Логическое (Т1код, Т2код, Произвел)
if Произвел < > 0 then Видимость = нет
end if
отрезок может оказаться частично видимым
return
подпрограмма вычисления кодов концевой точки отрезка
subroutine Конец (Р, Окно; Ткод, Сумма)
Рх, Ру — координаты точки Р
Окно — массив 1x4, содержащий координаты (хл, хп, ун, ув)
сторон окна
Ткод — массив 1 х 4, содержащий коды концевой точки
Сумма — сумма всех элементов массива Ткод
вычисление кодов концевой точки
if Рх < хл then ТкодD) = 1 else ТкодD) = 0
if Рх > хп then Ткод(З) = 1 else Ткод(З) = 0
if ру < Ун tnen ТкодB) = 1 else ТкодB) = 0
if Ру > Ув then ТкодA) = 1 else ТкодA) = 0
вычисление суммы
Сумма = 0
for i = I to 4
Сумма = Сумма + ТкодО)
next i
return
подпрограмма вычисления логического произведения
subroutine Логическое (Т1код, Т2код; Произвел)
Т1код, Т2код — массивы 1 х 4, содержащие коды первой и второй концевых точек соответственно
Произвел — сумма побитовых логических произведений
Произвел = О
for i = 1 to 4
Произвел = Произвел + Целая часть ((Т1код@ + Т2кодО))/2)
next i
return