Программирование в Pascal. Моделирование 3D-объектов

Курсовой проект - Компьютеры, программирование

Другие курсовые по предмету Компьютеры, программирование

о умолчанию и отчистка экрана;

поворот фигуры на заданный угол, в случае если он задан;

отрисовка текущей проекции фигуры;

проверка действий пользователя.

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

ErrCode = grOk then{если инициализация графического режима успешна, то }(0); {установка цвета}

clrscr;; {процедура отрисовки фигуры}(4000);; {поворот фигур}keypressed then {обработка нажатия клавиши пользователем}:=readkey;;codekey of {были нажаты клавиши отвечающие за вращение}

w:a1:=4.0; {укажем соответствующие углы поворота}

a:a2:=4.0;

s:a3:=4.0;

d:a2:=-4.0;

1:figura:=1;

2:figura:=2;;CodeKey=#27; {выход из цикла по нажатию Esc}

 

Проанализируем и реализуем процедуру отрисовки объекта в целом. Здесь для каждой фигуры будет свой участок кода, состоящий из процедур отрисовки конкретных граней. У пирамиды имеем 4 грани, у куба 6. Чтобы четко видеть грани объекта, каждой назначаем свой индивидуальный цвет. Но для того чтобы построить грань нужно знать, является ли она видимой, и впоследствии расположить ее по центру экрана.

Для проверки видимости введем небольшую функцию проверки грани:

TestGran(a, b, c: d3d): boolean;v1, w2, v2, w1, n: real; :=a.x-c.x;

v2:=a.y-c.y;:=b.x-c.x;:=b.y-c.y;:=v1*w2-v2*w1; n>0 then:=true {грань видна}:=false; {грань не видна};

 

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

Далее если грань видна, остается вывести ее на экран. Для этих целей применима встроенная в модуль языка Паскаль процедура FillPoly, которой можно передать заранее подготовленные координаты на экране и формат заливки. Процедура FillPoly вычисляет все горизонтальные пересечения, а затем закрашивает многоугольник, используя текущий стиль и цвет закраски, определенные с помощью сопутствующих процедур SetFillStyle и SetFillPattern. Контур многоугольника выделяется текущим цветом и типом линии, установленными при обращении к процедурам SetLineStyle и SetColor. Так как изначально координаты заданы относительно начала координат, необходимо задать некоторое приращение для расположения объекта в видимой части экрана. В данном случае объект будет отображен строго по центру экрана, учитывая что установленная разрешающая способность составляет 640х480 пикселей:

(1, col); {определяем тип заполнения }[1].x:=round(p1.x+320);[1].y:=round(p1.y+240);[2].x:=round(p2.x+320);[2].y:=round(p2.y+240);[3].x:=round(p3.x+320);[3].y:=round(p3.y+240);[4].x:=round(p4.x+320);[4].y:=round(p4.y+240);

 

Так как плоскость отображения двухмерная, для воссоздания проекции на экране достаточно воспользоваться только двумя координатами - х и у, z нам нужна только для определения положения грани - выходит она на передний план или нет. Рассчитывать и отрисовывать программно ее имело смысл только при построении проволочной модели. Впоследствии остается проверить является ли полученная грань треугольником или четырехугольником и отобразить ее:

if (zar[1].x=zar[4].x) and (zar[1].y=zar[4].y)fillpoly(3, zar)fillpoly(4, zar);

 

Так как алгоритм проверки и рисования граней довольно универсален, его можно применить для прочих фигур. Данный участок кода в дальнейшем будет применим не раз, соответственно имеет смысл вывести его как некоторую отдельную процедуру (DrawGran).

Теперь вызывая процедуру рисования граней и передавая в качестве параметров координаты точек, обходим их по часовой стрелке:

(tet[1],tet[2], tet[3],tet[1], 1);(tet[1],tet[3], tet[4],tet[1], 2);(tet[1],tet[4], tet[2],tet[1], 3);(tet[4],tet[3], tet[2],tet[4], 4);

 

И для куба:

(cub[4],cub[3], cub[2],cub[1], 11);(cub[5],cub[6], cub[7],cub[8], 12);(cub[1],cub[2], cub[6],cub[5], 13);(cub[3],cub[4], cub[8],cub[7], 14);(cub[2],cub[3], cub[7],cub[6], 15);(cub[5],cub[8], cub[4],cub[1], 16);

 

Построение сложных моделей

 

Используя данную методику можно построить более сложные полигональные модели, состоящие из большего числа граней. Рядом трудностей, с которыми можно столкнуться на данном этапе в условиях выбранной среды программирования может являться отсутствие большей палитры цветов и градиентов для выделения каждой грани выбранным методом, а так же отсутствие нормальных средств работы с динамической памятью среды. К тому же среда MS-DOS накладывает ограничение на размер выделяемого участка памяти. Грань ограничена определенным числом точек, относительно которых строится. Используя большее число граней (а соответственно и точек) возможна организация более сложных объектов, т