Опубликован: 20.10.2007 | Доступ: свободный | Студентов: 3830 / 892 | Оценка: 4.38 / 3.99 | Длительность: 12:07:00
ISBN: 978-5-94774-654-9
Специальности: Программист
Лекция 5:

Отсечение (клиппирование) геометрических примитивов

< Лекция 4 || Лекция 5: 123 || Лекция 6 >

В приведенном алгоритме теперь остается только детализовать функции Intersec0 и Intersec, эффективность работы которых является ключевым моментом. Рассмотрим один из методов поиска пересечений, который использует параметрическое уравнение прямой, проходящей через точки \overrightarrow{r}_1=(x_1,y_1), \; \overrightarrow{r}_2=(x_2,y_2):

\overrightarrow{r}=\overrightarrow{r}_1+s(\overrightarrow{r}_2-\overrightarrow{r_1}), \quad s\in[-\infty,+\infty],
или в координатном виде
x=x_1+sl_x, \quad y=y_1+sl_y, \quad l_x=x_2-x_1, \quad l_y=y_2-y_1.
Попробуем определить точку пересечения отрезка с верхней границей окна. Поскольку эта граница описывается соотношениями
L\le x\le R, \quad y=T,
то условие пересечения с ней клиппируемого отрезка выглядит следующим образом:
s_T=\frac{T-y_1}{l_y}, \quad L\le x_1+s_T l_x \le R.

Аналогично выглядят формулы и для остальных границ окна. Если точка \overrightarrow{r}_1 расположена внутри окна, то, в зависимости от знака l_y, следует искать пересечение либо с верхней, либо с нижней границей окна. При отсутствии таковых отыскиваются пересечения с левой или правой стороной окна. Но прежде чем перебирать эти варианты, необходимо исключить случаи горизонтальных (l_y=0) и вертикальных (l_x=0) направлений отрезка. В первом случае точками пересечения с правой или левой границей (в зависимости от знака l_x ) могут быть (L,y_1) или (R,y_1), а во втором - (x_1, B) или (x_1,T).

Этот алгоритм реализован в виде функции Intersec, блок-схема которой приведена на рис. 5.3.

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

Затем последовательно рассматриваются четыре случая расположения точки \overrightarrow{r}_1 относительно прямых, ограничивающих окно. Если в каком-то из вариантов будет найдена точка пересечения, то анализ прекращается, точка \overrightarrow{r}_1 заменяется новой точкой и вызывается функция Intersec. В случае же, когда все четыре варианта не дали положительного результата, переменной IsVisible присваивается значение 0. Алгоритм реализуется функцией Intersec0 (блок-схема на рис. 5.5).

Предложенная реализация алгоритма отсечения не является единственной в своем роде. Существуют и другие подходы, в частности использование метода деления отрезка пополам для поиска точек пересечения и выявления видимой части отрезка. Такой вариант алгоритма был предложен Сазерлендом и Спрулом для аппаратной реализации, но он может быть реализован и на программном уровне, хотя при этом эффективность его будет ниже, чем у предыдущего. В нем нет прямого вычисления координат новой точки по явным алгебраическим соотношениям. Поиск осуществляется итерационным методом, в котором на каждом шаге для отрезка, "подозреваемого" в частичной видимости, находится его средняя точка, определяется ее код, затем из двух отрезков оставляются либо оба (если они оба не окажутся полностью невидимыми), либо только один, после чего операции продолжаются с новыми отрезками. Ситуация, когда дальнейшему дроблению подвергаются сразу два вновь полученных отрезка, может возникнуть только на первом итерационном шаге в тех случаях, когда исходный отрезок имеет две точки пересечения с границами окна. На последующих итерационных шагах количество анализируемых отрезков уже не будет увеличиваться. Процесс продолжается до тех пор, пока длина очередного отрезка не станет меньше наперед заданной точности. После этого найденная точка проверяется на предмет пересечения со стороной окна. На рис. 5.6 приведены три варианта отрезков, предварительный анализ которых не классифицирует их как полностью невидимые, и показан первый итерационный шаг. Отрезок a после первого деления дает два частично видимых отрезка, после чего ищутся две точки пересечения. В остальных случаях остается лишь один из двух отрезков, причем в случае отрезка c точка пересечения со стороной окна отсутствует, т.е. обнаруживается полная невидимость отрезка. По сути дела общий алгоритм, показанный на рис. 5.3, сохраняется, изменяется лишь метод поиска точки пересечения.

Блок-схема функции Intersec

Рис. 5.3. Блок-схема функции Intersec
Отрезки параллельны сторонам окна

Рис. 5.4. Отрезки параллельны сторонам окна
Блок-схема функции Intrsec0

увеличить изображение
Рис. 5.5. Блок-схема функции Intrsec0
Произвольное расположение отрезков

Рис. 5.6. Произвольное расположение отрезков
< Лекция 4 || Лекция 5: 123 || Лекция 6 >
Сабина Бахриддинова
Сабина Бахриддинова
Дмитрий Трефилов
Дмитрий Трефилов

Семен Дядькин
Семен Дядькин
Беларусь, Минск, БГУ, 2003
Андрей Скурихин
Андрей Скурихин
Россия, Санкт-Петербург, Санкт-Петербургский государственный электротехнический университет (ЛЭТИ), 1997