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

Удаление невидимых поверхностей и линий

< Лекция 5 || Лекция 6: 12345 || Лекция 7 >

Методы приоритетов (художника, плавающего горизонта)

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

При изображении сцен со сплошным закрашиванием поверхностей можно воспользоваться методом художника: элементы сцены изображаются в последовательности от наиболее удаленных от наблюдателя к более близким. При экранировании одних участков сцены другими невидимые участки просто закрашиваются. Если вычислительная трудоемкость получения изображения для отдельных элементов достаточно высока, то такой алгоритм будет не самым лучшим по эффективности, но зато мы избежим анализа (и вполне возможно, тоже дорогостоящего), позволяющего установить, какие же из элементов изображать не надо в силу их невидимости. Например, при изображении правильного многогранника мы довольно легко можем упорядочить его грани по глубине, но такая сортировка для произвольного многогранника возможна далеко не всегда. Мы рассмотрим применение этого метода на примере изображения поверхности, заданной в виде однозначной функции двух переменных.

Пусть поверхность задана уравнением

z=f(x,y), \quad a\le x \le b, \quad c \le y \le d.
В качестве картинной плоскости выберем плоскость XOY. В области задания функции на осях координат построим сетку узлов:
a=x_0<x_1<\ldots<x_{n-1}=b, \quad c=y_0<y_1<\ldots<y_{m-1}<y_m=d.

Тогда z_{ij}=f(x_i,y_i) представляют собой набор "высот" для данной поверхности по отношению к плоскости XOY. Поверхность будем аппроксимировать треугольниками с вершинами в точках \overrightarrow{r}_{ij}=(x_i,y_i,z_{ij}) так, что каждому прямоугольнику сетки узлов будут соответствовать два треугольника: tr_{i_{j}\:j}^1=\{\overrightarrow{r}_{ij},\overrightarrow{r}_{i+1\:j},\overrightarrow{r}_{i+1\:j+1}\} и tr_{i_{j}\:j}^2=\{\overrightarrow{r}_{ij},\overrightarrow{r}_{i\:j+1},\overrightarrow{r}_{i+1\:j+1}\}. Для построения наглядного изображения поверхности повернем ее на некоторый угол сначала относительно оси OX, а затем относительно оси OY, причем направление вращения выберем таким образом, что точки, соответствующие углам координатной сетки, расположатся в следующем порядке по удаленности от картинной плоскости: \overrightarrow{r}_{nm},\overrightarrow{r}_{n0},\overrightarrow{r}_{0m},\overrightarrow{r}_{00}, т.е. точка \overrightarrow{r}_{nm} окажется наиболее близкой к картинной плоскости (и наиболее удаленной от наблюдателя). Предполагается, что способ закрашивания треугольников уже определен. Тогда процесс изображения поверхности можно коротко записать так:

\begin{aligned}
&\text{Для } i=n,\ldots,1 \\
&\qquad\qquad\text{Для } j=m,\ldots,1 \\
&\qquad\qquad\qquad\qquad\text{Нарисовать }tr_{i\:j}^1;\; \text{нарисовать }tr_{i\:j}^2.
\end{aligned}

При такой последовательности вывода изображения мы продвигаемся от самого удаленного треугольника к все более близким, частично закрашивая уже изображенные участки поверхности.

Простое каркасное изображение с поверхности

увеличить изображение
Рис. 6.4. Простое каркасное изображение с поверхности
Каркасное изображение диагональными ребрами

увеличить изображение
Рис. 6.5. Каркасное изображение диагональными ребрами

Алгоритм художника можно применять для полностью закрашенной сцены, а для каркасного изображения, когда объект представляется в виде набора кривых или ломаных линий, он непригоден. Для этого случая предложен еще один метод, весьма эффективный - метод плавающего горизонта. Вернемся к предыдущему примеру изображения поверхности. Каркасное изображение получается путем изображения кривых, получаемых при пересечении этой поверхности плоскостями x=x_i и y=y_i (рис. 6.4).

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

Функция segment в этом фрагменте предназначена для вывода на экран отрезка прямой, причем в момент инициализации очередного пикселя (i,j) она выполняет следующие действия:

\begin{aligned}
&\text{Если }(HHor[i]<j),\text{ то }HHor[i]=j;\text{ вывести пиксель}; \\
&\text{Иначе если }(LHor[i]>j),\text{ то }LHor[i]=j;\text{ вывести пиксель}.
\end{aligned}
Таким образом, пиксель выводится только в том случае, если он выше верхнего или ниже нижнего горизонта, после чего его координаты уже сами становятся одним из горизонтов. А в целом алгоритм будет выглядеть так:
\begin{aligned}
& \text{Для }i=0,\ldots,n-1 \\
& \qquad\text{Для }j=0,\ldots,m-1 \\
& \qquad\qquad segment(x_i,y_i,x_{i+1},y_j);segment(x_i,y_i,x_{i+1},y_{j+1});\\& \qquad \qquad \qquad segment(x_i,y_i,x_i,y_{j+1}).
\end{aligned}
На рис. 6.5 приведен пример изображения поверхности с использованием этого алгоритма.

< Лекция 5 || Лекция 6: 12345 || Лекция 7 >
Дмитрий Трефилов
Дмитрий Трефилов

Владислав Нагорный
Владислав Нагорный

Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки?

Спасибо!