Міністерство освіти та науки України
Національний університет «Львівська політехніка»
Кафедра автоматизованих систем управління
Лабораторна робота №3
з дисципліни
«Комп’ютерна графіка»
на тему:
“Паралельні та косокутні проекції”
Мета: Ознайомлення з елементарним математичним апаратом плоских геометричних проекцій.
ТЕОРЕТИЧНІ ОСНОВИ
Паралельні проекції.
Будемо вважати, що при центральному проектуванні картинна площина перпендикулярна осі z і збігається з площиною z = d, а при паралельному збігається з площиною z = 0. Проекції розглядаються в системі координат спостерігача, що є лівосторонньою. Система координат, в якій вісь x спрямована вправо, y – вгору, а вісь z – усередину екрана, природно погоджується з екраном дисплея.
Точка Р проектується на проекційну площину, розташовану на відстані d від початку координат. Для обчислення координат Xp і Yp проекції точки (x, y, z) напишемо співвідношення, отримані з подібності трикутників:
Перемножуючи обидві сторони кожного співвідношення на d, одержимо:
Відстань d є в даному випадку масштабним множником, застосованим до координат Xp і Yp. Фактором, що приводить до того, що на центральній проекції більш віддалені об’єкти виглядають дрібніше, ніж ближчі, є ділення на z. Відзначимо, що допустимі всі значення z, крім z = 0. Точки можуть розташовуватися як за центром проекції на від’ємній частині осі z, так і між центром проекції та проекційною площиною.
При іншому представленні центрального проектування, застосованого в деяких роботах, проекційна площина сполучається з площиною 2 = 0, а центр проекції розташовується в точці 2 = – с. З подібності трикутників випливає:
Звідси одержуємо:
Ортографічне проектування на площину z = 0 очевидне. Напрямок проектування збігається з нормаллю до площини проекції, тобто в нашому випадку з віссю z. Таким чином точка Р має координати:
Косокутні проекції.
Тепер розглянемо довільну точку (x, y, z) і визначимо її косокутну проекцію Xp і Yp на площину xy. Рівняння для x- і y-координат проектора як функцій z мають вид y = mz+b. Вирішуючи два рівняння відносно Xp і Yp, одержуємо:
ПОРЯДОК РОБОТИ
Побудувати декартову тривимірну систему координат. Побудувати точку з довільними координатами.
Побудувати паралельну проекцію точки. Для цього задати розміщення паралельної площини – відстань d. Вивести на екран спроектовану точку на площину та вказати, які вона матиме координати.
Побудувати косокутну проекцію точки. Для цього додатково потрібно задати, під яким кутом β будемо дивитися на площину xy та під яким кутом α відносно початку координат буде розміщена спроектована точка. Вивести на екран спроектовану точку на площину та вказати, які вона матиме координати.
Текст програми
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, Menus, StdCtrls, Buttons;
type
TForm1 = class(TForm)
Bevel1: TBevel;
PaintBox1: TPaintBox;
MainMenu1: TMainMenu;
N9,N10,N11,N12: TMenuItem;
Izo30,Izo45,Izo60: TMenuItem;
Dim30,Dim45,Dim60: TMenuItem;
Label1,Label2,Label3,Label4: TLabel;
Label5,Label6,Label7,Label8: TLabel;
Label9,Label10,Label11: TLabel;
ed,ex,ey,ez,ua,eb: TEdit;
BitBtn1: TBitBtn;
RadioGroup1: TRadioGroup;
procedure Chusto;
procedure MyLine(x1,y1,x2,y2: integer);
procedure Podilku;
procedure KoorOsi;
procedure Tochka(x,y,z: double; c: Tcolor);
procedure Plowuna(d: integer; c: Tcolor);
procedure PaintBox1Paint(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure N9Click(Sender: TObject);
procedure Izo30Click(Sender: TObject);
procedure Izo45Click(Sender: TObject);
procedure Izo60Click(Sender: TObject);
procedure Dim30Click(Sender: TObject);
procedure Dim45Click(Sender: TObject);
procedure Dim60Click(Sender: TObject);
procedure RadioGroup1Click(Sender: TObject);
procedure BitBtn1Click(Sender: TObject);
private
public
end;
type matrix= array[1..8,1..4] of double;
const CP=25;//ціна поділки
R=3;//радіус точки
dz=0.866;//похибка по Z для осі X (0.5; 0.866; 0.707)
dy=0.5;//похибка по Y для осі X (0.866; 0.5; 0.707)
var
Form1: TForm1;
x0,y0,w,h,x,y,z,d: integer;
xyz: matrix;
CPz,CPy,a,b,x1,y1,z1: double;
prjamokyt,pus: Boolean;
implementation
{$R *.DFM}
procedure TForm1.Chusto;
begin
PaintBox1.Refresh; KoorOsi;
end;
procedure TForm1.MyLine(x1,y1,x2,y2: integer);
const l=10;
var beta,a,b,d1,d2,e1,e2:double;
begin
b:=abs(x2-x1); a:=abs(y2-y1);
if b=0 then beta:=pi/2 else beta:=arctan(a/b);
d1:=l*cos(beta-pi/9); d2:=l*cos(beta+pi/9);
e1:=l*sin(beta-pi/9); e2:=l*sin(beta+pi/9);
with PaintBox1.Canvas do
begin
MoveTo(x1,y1); LineTo(x2,y2);
Brush.Color := clBlack; Pen.Color:=clBlack;
if (x2>x1)and(y2>y1) then
Polygon([Point(x2,y2),Point(Round(x2-d1),Round(y2-e1)),Point(Round(x2-d2),round(y2-e2)),Point(x2,y2)]);
if (x2>x1)and(y2<=y1) then
Polygon([Point(x2,y2),Point(Round(x2-d1),Round(y2+e1)),Point(Round(x2-d2),round(y2+e2)),Point(x2,y2)]);
if (x2<=x1)and(y2>y1) then
Polygon([Point(x2,y2),Point(Round(x2+d1),Round(y2-e1)),Point(Round(x2+d2),round(y2-e2)),Point(x2,y2)]);
if (x2<=x1)and(y2<=y1) then
Polygon([Point(x2,y2),Point(Round(x2+d1),Round(y2+e1)),Point(Round(x2+d2),round(y2+e2)),Point(x2,y2)]);
Brush.Color:=clBtnFace;
end;
end;
procedure TForm1.Podilku;
var i: byte;
begin
PaintBox1.Canvas.Brush.Color:=clBtnFace;
PaintBox1.Canvas.Pen.Color:=clBlack;
with PaintBox1.Canvas do
for i:=1 to 10 do
begin
{X}
MoveTo(x0+i*CP,y0-1); LineTo(x0+i*CP,y0+2);
if i<>10 then TextOut(x0+i*CP-3,y0+2,IntToStr(i));
MoveTo(x0-i*CP,y0-1); LineTo(x0-i*CP,y0+2);
{y}
MoveTo(x0-1,y0-i*CP); LineTo(x0+2,y0-i*CP);
if i<>10 then TextOut(x0-10,y0-i*CP-6,IntToStr(i));
MoveTo(x0-1,y0+i*CP); LineTo(x0+2,y0+i*CP);
{Z}
MoveTo(round(x0-i*CPz)-1,round(y0+i*CPy)-1); LineTo(round(x0-i*CPz)+2,round(y0+i*CPy)+2);
if i<>10 then TextOut(round(x0-i*CPz),round(y0+i*CPy)+3,IntToStr(i));
MoveTo(round(x0+i*CPz)-1,round(y0-i*CPy)-1); LineTo(round(x0+i*CPz)+2,round(y0-i*CPy)+2);
end;
end;
procedure TForm1.KoorOsi;
begin
with PaintBox1.Canvas do
begin
Brush.Color:=clBtnFace; Pen.Color:=clSilver;
MoveTo(x0,y0); LineTo(0,y0);
MoveTo(x0,y0); LineTo(x0,h);
MoveTo(x0,y0); LineTo(round(x0+11*CPz),round(y0-11*CPy));
Pen.Color:=clBlack;
MyLine(x0,y0,w,y0); TextOut(w-10,y0-16,'z');//Z
MyLine(x0,y0,x0,0); TextOut(x0+6,1,'y');//Y
MyLine(x0,y0,round(x0-11*CPz),round(y0+11*CPy));
TextOut(round(x0-11*CPz)+10,round(y0+11*CPy)-2,'x');//X
end;
Podilku;
end;
procedure TForm1.Tochka(x,y,z: double; c: Tcolor);
begin
with PaintBox1.Canvas do
begin
Pen.Color:=c; Brush.Color:=c;
Ellipse(round(x0+z*CP-x*CPz-R),round(y0-y*CP+x*CPy-R),round(x0+z*CP-x*CPz+R),round(y0-y*CP+x*CPy+R));
end;
end;
procedure TForm1.Plowuna(d: integer; c: Tcolor);
begin
with PaintBox1.Canvas do
begin
Tochka(0,0,d,c);
Pen.Color:=c; Pen.Style:=psDot;
Brush.Color:=c; Brush.Style:=bsBDiagonal;
Polygon([Point(round(x0+d*CP-5*CPz),round(y0-5*CP+5*CPy)),
Point(round(x0+d*CP-5*CPz),round(y0+5*CP+5*CPy)),
Point(round(x0+d*CP+5*CPz),round(y0+5*CP-5*CPy)),
Point(round(x0+d*CP+5*CPz),round(y0-5*CP-5*CPy))]);
Brush.Style:=bsSolid; Pen.Style:=psSolid;
end;
end;
procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
KoorOsi;
Tochka(x,y,z,clGreen);
if pus=true then
begin
Tochka(x1,y1,z1,clRed);
Plowuna(d,clGray);
pus:=false;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
CPz:=CP*dz; CPy:=CP*dy; x:=0; y:=0; z:=0;
w:=PaintBox1.Width; x0:=round(w/2);
h:=PaintBox1.Height; y0:=round(h/2);
Label9.Enabled:=false; Label10.Enabled:=false; Label11.Enabled:=false;
ea.Enabled:=false; eb.Enabled:=false; prjamokyt:=true; pus:=false;
end;
procedure TForm1.N9Click(Sender: TObject);
begin Close; end;
procedure TForm1.Izo30Click(Sender: TObject);
begin CPz:=CP*dy; CPy:=CP*dz; PaintBox1.Repaint; end;
procedure TForm1.Izo45Click(Sender: TObject);
begin CPz:=CP*0.707; CPy:=CP*0.707; PaintBox1.Repaint; end;
procedure TForm1.Izo60Click(Sender: TObject);
begin CPz:=CP*dz; CPy:=CP*dy; PaintBox1.Repaint; end;
procedure TForm1.Dim30Click(Sender: TObject);
begin CPz:=CP*dy*0.5; CPy:=CP*dz*0.5; PaintBox1.Repaint; end;
procedure TForm1.Dim45Click(Sender: TObject);
begin CPz:=CP*0.707*0.5; CPy:=CP*0.707*0.5; PaintBox1.Repaint; end;
procedure TForm1.Dim60Click(Sender: TObject);
begin CPz:=CP*dz*0.5; CPy:=CP*dy*0.5; PaintBox1.Repaint; end;
procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
if RadioGroup1.ItemIndex=0 then
begin
Label9.Enabled:=false; prjamokyt:=true;
Label10.Enabled:=false; ea.Enabled:=false;
Label11.Enabled:=false; eb.Enabled:=false;
Label1.Enabled:=true; ed.Enabled:=true;
ex.Enabled:=true; Label3.Enabled:=true;
ey.Enabled:=true; Label4.Enabled:=true;
end
else
begin
Label9.Enabled:=true; prjamokyt:=false;
Label10.Enabled:=true; ea.Enabled:=true;
Label11.Enabled:=true; eb.Enabled:=true;
Label1.Enabled:=false; ed.Enabled:=false;
ex.Enabled:=false; Label3.Enabled:=false;
ey.Enabled:=false; Label4.Enabled:=false;
end;
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
pus:=true; z:=StrToInt(ez.Text);
if prjamokyt=true then
begin
x:=StrToInt(ex.Text); y:=StrToInt(ey.Text); d:=StrToInt(ed.Text);
x1:=d*x/(z+d); Label6.Caption:='x '+FloatToStr(round(x1*10)/10);
y1:=d*y/(z+d); Label7.Caption:='y '+FloatToStr(round(y1*10)/10);
z1:=d; Label8.Caption:='z '+FloatToStr(round(z1*10)/10);
end
else
begin
x:=0; y:=0; a:=pi*StrToInt(ea.Text)/180; b:=pi*StrToInt(eb.Text)/180; d:=0;
x1:=cos(a)*cos(b)*z/sin(b); Label6.Caption:='x '+FloatToStr(round(x1*10)/10);
y1:=sin(a)*cos(b)*z/sin(b); Label7.Caption:='y '+FloatToStr(round(y1*10)/10);
z1:=0; Label8.Caption:='z '+FloatToStr(round(z1*10)/10);
end;
PaintBox1.Repaint;
end;
end.
Результати виконання програми
Паралельна проекція.
Косокутна проекція.
Висновок: в даній лабораторній роботі я ознайомився з основами комп’ютерної графіки – представленням фігур в просторовій системі координат та здійснення паралельної та косокутної проекцій точок.