Міністерство освіти і науки України
Національний університет «Львівська політехніка»
Інститут комп’ютерних наук та інформаційних технологій
Кафедра автоматизованих систем управління
Лабораторна робота №3
З курсу:
«Комп’ютерна графіка»
Тема:Параллельні та косокутні проекції.
Мета: Ознайомлення з елементарним математичним апаратом плоских геометричних проекцій
.
ТЕОРЕТИЧНІ ОСНОВИ
Паралельні проекції
Будемо вважати, що при центральному проектуванні картинна площина перпендикулярна oci z i збігається з площиною z = d, а при паралельному збігається з площиною z = 0. Проекції розглядаються в системі координат спостерігача, що є лівосторонньою. Система координат, в якій вicь х спрямована вправо, вісь у - вгору, а вісь z - усередину екрана, природньо погоджується з екраном дисплея.
На рис.3.1 наведені три зображення лівосторонньої системи координат, у яких точка Р проектується на проекційну площину, розташовану на відстані d від початку координат. Для обчислення координат Хp i Yp проекції точки (х, у, z) напишемо сшвввдношения, отримані з подібності трикутників.
Ці перетворення можна представити у вигляді матриці розміром 4х4.
Косокутні проекції
Тепер розглянемо довільну точку х, у, z i визначимо її косокутну проекцію (Хр,Ур) на площину ху. На рис. показані два зображення точки i проектор. Рівняння для х- і у -координат проектора як функцій z мають вигляд у=тz+b. Вирішуючи два рівняння відносно Хр i Yp, виззначених на рис одержуемо:
Текст программного коду:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls, ExtCtrls,Math;
type
TForm1 = class(TForm)
Button1: TButton;
RadioGroup1: TRadioGroup;
Image1: TImage;
Label1: TLabel;
Label2: TLabel;
Button2: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Label3: TLabel;
Edit5: TEdit;
Edit6: TEdit;
Label4: TLabel;
Edit7: TEdit;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
Label11: TLabel;
Label12: TLabel;
Label13: TLabel;
Label14: TLabel;
procedure Button1Click(Sender: TObject);
procedure koord();
procedure draw_P(x_p,y_p,z_p:double);
procedure Button2Click(Sender: TObject);
procedure RadioGroup1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
x0,y0,z0,delta,delta_zx,delta_zy,x1,y1:integer;
delta_yz,delta_yx:integer;
implementation
procedure TForm1.koord();
var delta_p,x1,x2,x3,x4,y1,y2,y3,y4,i,z:integer;
begin
x0:=round(image1.Width/2);
y0:=round((image1.Height)/2);
with image1.Canvas do
begin
if (image1.Width-x0)>(image1.Height-y0) then
delta:=round((image1.Height-y0)/10)
else
delta:=round((image1.Width-x0)/10);
x1:=x0;
x2:=x0;
x3:=x0;
x4:=x0;
y1:=y0;
y2:=y0;
y3:=y0;
y4:=y0;
for i:=0 to 10 do begin
delta_p:=delta;
MoveTo(x0,y1);
LineTo(x0,y1-delta_p);
moveto(x0-2,y1-delta_p);
LineTo (x0+2,y1-delta_p);
y1:=y1-delta_p;
MoveTo(x3,y0);
LineTo(x3+delta_p,y0);
moveto(x3+delta_p,y0-2);
LineTo (x3+delta_p,y0+2);
x3:= x3+delta_p;
///////////////////////*****************
z:=delta_p;
MoveTo(x4,y2);
LineTo(x4-round(z*cos(0.5)),y2+round(z*sin(0.5)));
moveto(x4-round(z*cos(0.5)),y2+round(z*sin(0.5))-2);
LineTo (x4-round(z*cos(0.5)),y2+round(z*sin(0.5))+2);
x4:= x4-round(z*cos(0.5));
y2:=y2+round(z*sin(0.5));
z:=z+delta_p;
if i=9 then begin
TextOut(x0+3,y1-delta_p+16,'x');
TextOut(x3+delta_p,y0,'z');
TextOut(x4-round(z*cos(0.5)),y2+round(z*sin(0.5)),'y');
end;
end;
end;
end;
procedure TForm1.draw_P(x_p,y_p,z_p:double);
var x1,y1,z1,x2,y2,i:integer;
begin
with image1.Canvas do
begin
pen.Width:=5;
delta_zx:=round(z_p*delta*cos(0.5));
delta_zy:=round(z_p*delta*sin(0.5));
x1:=round(x0+x_p*delta);
y1:=round(y0-y_p*delta);
MoveTo((x1-delta_zx),y1+delta_zy);
LineTo(x1-delta_zx,y1+delta_zy);
pen.Width:=1;
end;
end;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
x_p,y_p,z_p,d,l,alpha,beta:double;
del_x,del_y,del_z:double;
begin
image1.Canvas.FillRect(Rect(0,0,image1.Width,image1.Height));
image1.Transparent:=true;
koord();
if RadioGroup1.ItemIndex=0 then begin
x_p:=strtofloat(Edit2.Text);
y_p:=strtofloat(Edit3.Text);
z_p:=strtofloat(Edit4.Text);
with Image1.Canvas do begin
pen.Color:=clRed; ///poch tochka
draw_p(x_p,y_p,z_p);
pen.Color:=clBlack;
MoveTo((round((x0+x_p*delta)-z_p*delta*cos(0.5))),round((y0-y_p*delta)+z_p*delta*sin(0.5)));
LineTo(x0,y0);
d:=strtoint(Edit1.Text);
y_p:=(y_p*d)/x_p;
z_p:=(z_p*d)/x_p;
x_p:=d;
pen.Color:=clGreen;
draw_p(x_p,y_p,z_p);
pen.Color:=clBlack;
MoveTo((round((x0+x_p*delta)-z_p*delta*cos(0.5))),round((y0-y_p*delta)+z_p*delta*sin(0.5)));
LineTo(x0,y0);
end;
label1.Caption:=floattostr(x_p);
label6.Caption:=floattostr(y_p);
label7.Caption:=floattostr(z_p);
with Image1.Canvas do begin
MoveTo(round(x0+(x_p-1)*delta-(z_p*delta*cos(0.5))),round(y0-(y_p+5)*delta+(z_p*delta*sin(0.5)))); //t
LineTo(round(x0+(x_p-1)*delta-(z_p*delta*cos(0.5))),round(y0-(y_p-5)*delta+(z_p*delta*sin(0.5))));
MoveTo(round(x0+(x_p-1)*delta-(z_p*delta*cos(0.5))),round(y0-(y_p-5)*delta+(z_p*delta*sin(0.5))));
LineTo(round(x0+(x_p-1)*delta-((z_p-2)*delta*cos(0.5))),round(y0-(y_p-5)*delta+((z_p-2)*delta*sin(0.5))));
MoveTo(round(x0+(x_p-1)*delta-((z_p-2)*delta*cos(0.5))),round(y0-(y_p-5)*delta+((z_p-2)*delta*sin(0.5))));
LineTo(round(x0+(x_p-1)*delta-((z_p-2)*delta*cos(0.5))),round(y0-(y_p+5)*delta+((z_p-2)*delta*sin(0.5))));
Moveto(round(x0+(x_p-1)*delta-((z_p-2)*delta*cos(0.5))),round(y0-(y_p+5)*delta+((z_p-2)*delta*sin(0.5))));
LineTo(round(x0+(x_p-1)*delta-(z_p*delta*cos(0.5))),round(y0-(y_p+5)*delta+(z_p*delta*sin(0.5))));
end;
end else
begin with Image1.Canvas do begin
beta:=(3.141592654/180*strtofloat(Edit5.Text));
alpha:=(3.141592654/180*strtofloat(Edit6.Text));
l:= strtofloat(Edit7.Text);
draw_p(l,0,0);
z_p:=l*cos(alpha)*cotan(beta);
y_p:=l*sin(alpha)*cotan(beta);
x_p:=0;
draw_p(x_p,y_p,z_p);
label1.Caption:=floattostr(x_p);
label6.Caption:=floattostr(y_p);
label7.Caption:=floattostr(z_p);
moveto((round((x0+l*delta)-0*delta*cos(0.5))),y0);
lineto((round((x0+x_p*delta)-z_p*delta*cos(0.5))),round((y0-y_p*delta)+z_p*delta*sin(0.5)));
moveto((round((x0+x_p*delta)-z_p*delta*cos(0.5))),round((y0-y_p*delta)+z_p*delta*sin(0.5)));
lineto(x0,y0);
pen.Style:=psDot;
moveto((round((x0+x_p*delta)-z_p*delta*cos(0.5))),round((y0-y_p*delta)+z_p*delta*sin(0.5)));
lineto (round(x0+x_p*delta-((0)*delta*cos(0.5))),round(y0-(y_p)*delta+((0)*delta*sin(0.5))));
moveto((round((x0+x_p*delta)-z_p*delta*cos(0.5))),round((y0-y_p*delta)+z_p*delta*sin(0.5)));
LineTo(round(x0+0*delta-((z_p)*delta*cos(0.5))),round(y0-(0)*delta+((z_p)*delta*sin(0.5))));
pen.Style:=psSolid;
pen.Width:=2;
MoveTo(round(x0+(0)*delta-((z_p+2)*delta*cos(0.5))),round(y0-(y_p+3)*delta+((z_p+2)*delta*sin(0.5)))); //t
LineTo(round(x0+0*delta-((z_p+2)*delta*cos(0.5))),round(y0-0*delta+((z_p+2)*delta*sin(0.5))));
MoveTo(round(x0+0*delta-((z_p+2)*delta*cos(0.5))),round(y0-0*delta+((z_p+2)*delta*sin(0.5))));
LineTo(round(x0+0*delta-(0*delta*cos(0.5))),round(y0-0*delta+(0*delta*sin(0.5))));
MoveTo(round(x0+(0*delta-(0*delta*cos(0.5)))),round(y0-(0)*delta+((0)*delta*sin(0.5))));
LineTo(round(x0+(0)*delta-((0)*delta*cos(0.5))),round(y0-(y_p+3)*delta+((0)*delta*sin(0.5))));
Moveto(round(x0+(0)*delta-((0)*delta*cos(0.5))),round(y0-(y_p+3)*delta+((0)*delta*sin(0.5))));
LineTo(round(x0+(0)*delta-((z_p+2)*delta*cos(0.5))),round(y0-(y_p+3)*delta+((z_p+2)*delta*sin(0.5))));
pen.Width:=1;
end;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
image1.Canvas.FillRect(Rect(0,0,image1.Width,image1.Height));
image1.Transparent:=true;
koord();
end;
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
//clean;
case RadioGroup1.ItemIndex of
0: begin
Label2.Visible:=true;
Label3.Visible:=true;
Label10.Visible:=true;
Label11.Visible:=true;
Label12.Visible:=true;
Edit2.Visible:=true;
Edit3.Visible:=true;
Edit4.Visible:=true;
Edit1.Visible:=true;
Edit5.Visible:=false;
Edit6.Visible:=false;
Edit7.Visible:=false;
Label4.Visible:=false;
Label5.Visible:=false;
Label13.Visible:=false;
Label14.Visible:=false;
Label8.Visible:=false;
end;
1: begin
Edit1.Visible:=false;
Label2.Visible:=false;
Label3.Visible:=false;
Label10.Visible:=false;
Label11.Visible:=false;
Label12.Visible:=false;
Edit2.Visible:=false;
Edit3.Visible:=false;
Edit4.Visible:=false;
Edit5.Visible:=true;
Edit6.Visible:=true;
Edit7.Visible:=true;
Label4.Visible:=true;
Label5.Visible:=true;
Label13.Visible:=true;
Label14.Visible:=true;
Label8.Visible:=false;
end;
end;
end;
end.
Результати роботи програми:
Рис1. Паралельна проекція
Рис2. Косокутна проекція
Висновок: На даній лабораторній роботі я ознайомилась з елементарним математичним апаратом плоских геометричних проекцій і побудувала паралельну і косокутну проекції.
.