.2 Введенные типы данных и их предназначениеПри реализации программы были определены некоторые специализированные типы данных (таблица 1).Таблица 1 - Типы данных.|
Тип | Значение | Предназначение | | T3DPoint | record | Содержит 3 координаты точки в трехмерном пространстве, координаты точки на экране, номер точки и нормаль к этой точке имеющая три координаты. | | TPolygon | record | Содержит указатели на вершины полигона, то есть содержит переменные типа P3DPoint. нормаль к полигону, номер полигона, цвет и среднюю точку. | | | 3.3 Введенные основные переменные и их предназначениеПри реализации программы были определены некоторые переменные (таблица 2).Таблица 1 - Переменные|
Переменная | Значение | Предназначение | | w,v1 | array [1.. nPoint] of T3DPoint | мировые, видовые координаты вершин | | v | array [1.. nPoint] of TPoint | экранные координаты точек | | polygons | array [1.. nTPolygon] of TPolygon | массив объектов фигуры | | teta | extended | Отвечает за угол поворота относительно оси Y. Имеет фиксированное значение teta:=pi/9. | | phi | extended | Отвечает за угол поворота относительно оси X. Имеет фиксированное значение phi:=pi*4/3. | | buf | TBitmap | Вспомогательная поверхность в ней создается движение сферы | | blink_buf | TBitmap | Вспомогательная поверхность для быстрого закрашивания фоном (хранит в себе фон изображения) | | A, B, C, D | переменные типа word типа TPolygon (record) | Определяют номера вершин четырехугольника в полигоне. Диапазон значений - 0.. nTPolygon | | ro | real | Определяет расстояние от объекта наблюдения до фигуры. Имеет фиксированное значение | | | 3.4 Текстовое описание основных процедур и функций и их блок-схемыПроцедура FormCreateЗадаются углы поворота, радиусы паралеллей, их количество и высота вазы. Вычисляются видовые координаты вершин вазы (пересечения параллелей и меридианов). Рассчитывается количество полигонов. Создаётся фон типа TBitmap, на котором будет рисоваться фигура (рисунок 4).Процедура FormKeyDown В этой процедуре отслеживаются нажатые клавиши с последующим выполнений соответствующих команд. При помощи процедуры KeyDown задается угол поворота объекта. При нажатии клавиш Up, Down, Left, Right объект поворачивается в заданном направлении (рисунок 5). Рисунок 5 - Блок-схема процедуры FormKeyDown Процедура Sort Для каждого полигона высчитывается вектор нормали и приводится к единичной форме; сортировка массива полигонов по минимальным значениям средних координат (рисунок6). Рисунок 6 - Блок-схема процедуры Sort Процедура ViewTransformation В этой процедуре вычисляются видовые и экранные координаты точек, задаются полигоны. В процедуре мировые координаты переводятся в видовые, в свою очередь которые преобразовываются в экранные координаты точек (рисунок7). Рисунок 7 - Блок-схема процедуры ViewTransformation Процедура Draw Поочередная прорисовка полигонов, то есть который грань дальше от нас прорисовывается первой и т.д (рисунок 8). Рисунок 8 - Блок-схема процедуры Draw Функция tone Функция, задающая плоскость цвета. В зависимости от угла между направлением взгляда и нормалью цвет должен изменяться. Значение координаты nz нормали для видимой грани изменяется в диапазоне [-1, 0), цвет грани задан в виде RGB компонентов. И, следовательно, для получения цвета грани нужно умножить каждую компоненту на абсолютное значение nz. Для получения компонент цвета воспользовались функциями GetRValue, GetGValue, GetBValue. 3.5 Алгоритм взаимодействия процедур Рисунок 9 - Алгоритм взаимодействия процедур 4. Тестирование программы Интерфейс программы представляет собой форму, на которой представлена ваза. Форма имеет фон, для лучшего восприятия. После запуска программы на экране не наблюдается ничего. Для наблюдения эффектов предлагается использовать следующие кнопки клавиатуры: ВНИЗ: Поворот вокруг оси x вниз; ВЛЕВО: Поворот вокруг оси y влево; ВВЕРХ: Поворот вокруг оси x вверх; ВПРАВО: Поворот вокруг оси y вправо. Вид окна программы представлен на рисунке 10. При нажатии на клавиши "влево", "вправо", "вверх", "вниз" происходит соответствующее перемещение фигуры. Рисунок 10 - Вид окна программы В ходе тестирования программа работала стабильно, не вызывала появления сообщений об ошибках. Список литературы 1. Порев В.Н. Компьютерная графика - СПб.: БХВ - Петербург, 2002. - 432 с.: ил. 2. Шикин А.В., Боресков А.В. Компьютерная графика. Полигональные модели. - М.: ДИАЛОГ - МИФИ, 2001. - 464с. 3. Л. Аммерал Принципы программирования в машинной графике. Пер. с англ. - М.: "Сол Систем", 1992. - 224 с.: ил. Приложение Листинг программы unit prog; interface uses Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms, Dialogs,StdCtrls,Math; type TForm1 = class(TForm) procedure KeyDown(Sender:TObject;var Key:Word;Shift:TShiftState); procedure FormCreate(Sender:TObject); procedure FormPaint(Sender:TObject); private { Private declarations } public { Public declarations } end; T3DPoint=record x,y,z:extended end; TPolygon=record A,B,C,D:word; clr:TColor; end; const step=30;//количество точек на одной параллели nPOINT=step*10+1; nPOLYGON=step*10+step; col1=255+255*$100+204*$10000; //цвет стенок(полигонов) вазы col2=209+154*$100+65*$10000; //цвет дна вазы var Form1:TForm1; Buf,Blinc_Buf:TBitMap; polygons:array[1..nPolygon] of Tpolygon; w,v1:array[1..nPOINT] of T3DPoint;//мировые (world),видовые (view) координаты вершин v:array[1..nPOINT] of TPoint;//экранные (screen) координаты вершин S:array[1..nPOLYGON] of extended; n:array[1..nPOLYGON] of T3DPoint; //массив нормалей teta,phi,d,ro,r:real; implementation {$R *.dfm} function tone(clr:TColor;nz:extended):TColor; //плоскость цвета begin tone:=rgb(round(nz*GetRValue(clr)), round(nz*GetGValue(clr)), round(nz*GetBValue(clr))) end; procedure ViewTransformation; var i: integer; begin for i:=1 to nPOINT Do begin v1[i].x:=Round(w[i].x*(-sin(teta))+w[i].y*(cos(teta))); v1[i].y:=Round(w[i].x*(-cos(phi)*cos(teta))-w[i].y*(cos(phi)*sin(teta))+ w[i].z*( sin(phi))); v1[i].z:=Round(w[i].x*(-sin(phi)*cos(teta))-w[i].y*( sin(phi)*sin(teta))- w[i].z*(cos(phi)))+ro; v[i].x:=Round(Form1.ClientWidth div 2+v1[i].x ); v[i].y:=Round(Form1.ClientHeight div 2+v1[i].y); end; end; procedure Sort; var i:integer; begin for i:=1 to nPOLYGON do begin s[i]:=(v1[polygons[i].a].z+v1[polygons[i].b].z+v1[polygons[i].c].z)/3; //координаты вектора нормали n[i].x:=v1[polygons[i].a].y*(v1[polygons[i].b].z-v1[polygons[i].c].z)+ v1[polygons[i].b].y*(v1[polygons[i].c].z-v1[polygons[i].a].z)+ v1[polygons[i].c].y*(v1[polygons[i].a].z-v1[polygons[i].b].z); n[i].y:=v1[polygons[i].a].z*(v1[polygons[i].b].x-v1[polygons[i].c].x)+ v1[polygons[i].b].z*(v1[polygons[i].c].x-v1[polygons[i].a].x)+ v1[polygons[i].c].z*(v1[polygons[i].a].x-v1[polygons[i].b].x); n[i].z:=v1[polygons[i].a].x*(v1[polygons[i].b].y-v1[polygons[i].c].y)+ v1[polygons[i].b].x*(v1[polygons[i].c].y-v1[polygons[i].a].y)+ v1[polygons[i].c].x*(v1[polygons[i].a].y-v1[polygons[i].b].y); if (sqrt(sqr(n[i].x)+sqr(n[i].y)+sqr(n[i].z)))<>0 then n[i].z:=n[i].z/(sqrt(sqr(n[i].x)+sqr(n[i].y)+sqr(n[i].z))) else n[i].z:=0; end; end; procedure Draw; var j,i1,i:integer; f: real; begin Sort; f:=0; buf.Canvas.Draw(0,0,blinc_buf); //рисуем в основном буфере фон for i1:=1 to nPOLYGON do begin //Опред.невидимости грани (слегка затеняем внутреннюю поверхность) if (n[i1].z>0) then n[i1].z:=n[i1].z*0.60; end; for i1:=1 to nPOLYGON do begin for i := 1 to nPOLYGON do if s[i]>f then begin j:=i;f:=s[i];end; with polygons[j] do begin Buf.Canvas.Brush.Color:=tone(clr,ABS(n[j].z)); //цвет полигона Buf.Canvas.Pen.Color:=tone(clr,ABS(n[j].z*0.96));//цвет границ полигонов Buf.Canvas.Polygon([v[A],v[B],v[C],v[D]]); //прорисовка полигона end; s[j]:=0; f:=0; end; Form1.Canvas.Draw(0,0,buf); //прорисовываем буфер на экране(форме) end; procedure TForm1.KeyDown(Sender:TObject;var Key:Word;Shift:TShiftState); begin CASE KEY of VK_UP: phi:=phi+pi*0.05; VK_DOWN: phi:=phi-pi*0.05; VK_LEFT: teta:=teta+pi*0.03; VK_RIGHT: teta:=teta-pi*0.03; end; ViewTransformation; Draw; end; procedure TForm1.FormCreate(Sender: TObject); var B,L,H,nn:integer; dL:Real; const Rz:array[0..9] of integer = (50,75,90,94,88,74,54,42,40,46);//радиусы параллелей begin H:=250; // высота вазы d:=200; //масштаб ro:=500; //перспектива teta:=pi/9; //угол поворота phi:=pi*4/3; //угол поворота // вершины вазы for B:=0 to 9 do begin for L:=0 to step-1 do begin dL:=L*Pi*(360/step)/180; w[B*step+L+1].x:=Rz[B]*sin(dL); //Вычисление мировых координат w[B*step+L+1].y:=Rz[B]*cos(dL); w[B*step+L+1].z:=H/10*B-H/2; end; end; // полигоны вазы nn:=1; for B:=1 to 9 do begin for L:=0 to step-2 do begin polygons[nn].A:=(B-1)*step+L+1; polygons[nn].B:=(B-1)*step+L+2; polygons[nn].C:=B*step+L+2; polygons[nn].D:=B*step+L+1; polygons[nn].clr:=col1; nn:=nn+1; end; polygons[nn].A:=B*step; polygons[nn].B:=(B-1)*step+1; polygons[nn].C:=B*step+1; polygons[nn].D:=(B+1)*step; polygons[nn].clr:=col1; nn:=nn+1; end; // вершина дна вазы w[nPOINT].x:=0;w[nPOINT].y:=0;w[nPOINT].z:=-H/2; // полигоны дна вазы for L:=0 to step-2 do begin polygons[L+nPOINT].A:=L+2; polygons[L+nPOINT].B:=L+1; polygons[L+nPOINT].C:=nPOINT; polygons[L+nPOINT].D:=nPOINT; polygons[L+nPOINT].clr:=col2; end; polygons[nPOLYGON].A:=1; polygons[nPOLYGON].B:=step; polygons[nPOLYGON].C:=nPOINT; polygons[nPOLYGON].D:=nPOINT; polygons[nPOLYGON].clr:=col2; // буфер buf:=TBitmap.Create; buf.Width:=Form1.ClientWidth; buf.Height:=Form1.ClientHeight; // фон blinc_buf:=TBitmap.Create; blinc_buf.Width:=Form1.ClientWidth; blinc_buf.Height:= Form1.ClientHeight; blinc_buf.Canvas.Rectangle(0,0,Form1.ClientWidth,Form1.ClientHeight); blinc_buf.LoadFromFile('./background.bmp'); end; procedure TForm1.FormPaint(Sender: TObject); begin // ViewTransformation; // Draw; end; end. Размещено на Allbest.ru
Страницы: 1, 2
|