Лабораторна робота №1
Тема: Основи комп’ютерної графіки. Робота в декартовій системі координат
Мета: Ознайомлення з основами комп’ютерної графіки.
Теоретичні основи
Представления точок
Точка задається за допомогою двох значень (х у), наприклад, (2 3) .
Перетворення точок
Розглянемо результати матричного множення (x, y) , що визначає точку, і матриці перетворення 2х2 загального виду
Дослідимо декілька часткових випадків:
1) a=d=1, b=c=0. Змін не відбувається.
2) d=1, b=c=0 Зміна масштабу по осі x
3) b=c=0 Зміна масштабу по осях x і y.
4) b=c=0, d=1, a=-1. Відображення координат відносно осі y.
5) b=c=0, d=a<0. Відображення відносно початку координат.
6) d=a =l, c=0. Зсув
1.3 Перетворення прямих ліній (відрізків)
Будь-яка пряма будується за допомогою двох точок, наприклад, АВ. Нехай точки À i В задані координатами - А (0, l) i В (2, 3). Матриця ж перетворення, задана такими значеннями:
В результаті декартового добутку вектора-точки на матрицю перетворення одержимо:
Обертання
Розглянемо плоскийтрикутник АВС.Нехай координати трикутника задані такими значеннями: А(3,1), В(6,1) та С(6,4)
Матриця перетворення для повороту на 90° проти годинникової стрілки виглядає так:
Після декартового добутку одержимо матрицю:
Матриця перетворення для повороту на 180° проти годинникової стрілки виглядає так:
Після декартового добутку одержимо матрицю:
Матриця перетворення для повороту на 270° проти годинникової стрілки виглядає так:
Після декартового добутку одержимо матрицю:
Відображення
Відображення визначається поворотом на 180° навколо осі, що лежить в площині х,y.
1)Обертання навколо прямої х=у задається матрицею:
Після декартового добутку одержимо матрицю:
2)Обертання навколо осі у=0 задається матрицею:
Після декартового добутку одержимо:
Зміна масштабу.
Зміна масштабу визначається значениям 2-х елементів головної діагоналі матриці. Якщо використовуємо матрицю
то маємо збільшення в 2 рази. Якщо значения елементів не pівні, то мае місце спотворення.
Збільшимо трикутник в 3 рази. Після декартового добутку одержимо матрицю:
Двовимірний зсув i однорідні координати
Введемо третій компонент у вектори точок (x,y) і (х*,у*).
(x,y,1) і (х*,у*,1)
Матриця перетворення матиме вигляд:
Таким чином:
Константи m і n викликають зсув х*,у*, відносно x,y.
Порядок роботи
Побудуйте декартову систему координат.
Виведіть на панель можливість задания координат тонок та матриці перетворення.
Здійсніть масштабування однієї поділки по осях ОХ та OY.
Побудуйте точку у декартовій системі координат. Здійсніть yci перетворення точок за допомогою матричних перетворень.
Побудуйте відрізок. Виведіть на панель можливість введения координат відрізка та матриці перетворення. Здійсніть перетворення відрізків.
Побудуйте трикутник 3дійсніть перетворення трикутника: обертання, відображення, масштабування, зсув.
Приклад програмної реалізації.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
StringGrid2: TStringGrid;
Button1: TButton;
RadioGroup1: TRadioGroup;
Image1: TImage;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
procedure koord();
procedure draw_P(x_k,y_k:integer);
procedure RadioGroup1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
x0,y0,delta:integer;
implementation
procedure TForm1.koord();
var delta_p,x1,x2,x3,x4,y1,y2,y3,y4,i: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(x0,y2);
LineTo(x0,y2+delta_p);
moveto(x0-2,y2+delta_p);
LineTo (x0+2,y2+delta_p);
y2:=y2+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;
MoveTo(x4,y0);
LineTo(x4-delta_p,y0);
moveto(x4-delta_p,y0-2);
LineTo (x4-delta_p,y0+2);
x4:= x4-delta_p;
end;
end;
end;
procedure TForm1.draw_P(x_k,y_k:integer);
begin
with image1.Canvas do
begin
pen.Color:=clgray;
pen.Width:=5;
MoveTo(x0+x_k*delta,y0-y_k*delta);
LineTo(x0+x_k*delta,y0-y_k*delta);
pen.Width:=1;
pen.Style:=psDot;
MoveTo(x0+x_k*delta,y0-y_k*delta);
LineTo(x0,y0-y_k*delta);
MoveTo(x0+x_k*delta,y0-y_k*delta);
LineTo(x0+x_k*delta,y0);
TextOut(x0+x_k*delta,y0+7,inttostr(x_k));
TextOut(x0+7,y0-y_k*delta,inttostr(y_k));
pen.Style:=psSolid;
end;
end;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
str: array[0..2] of array[0..2] of integer;
x:array[0..2]of array[0..2] of integer;
a:array[0..2]of array[0..2] of integer;
i,j,l:integer;
begin
case RadioGroup1.ItemIndex of
0: begin
image1.Canvas.FillRect(Rect(0,0,image1.Width,image1.Height));
image1.Transparent:=true;
koord();
str[0,0]:=strtoint(StringGrid1.Cells[0,0]);
str[0,1]:=strtoint(StringGrid1.Cells[1,0]);
draw_P(str[0,0],str[0,1]);
if StringGrid2.Cells[0,0]<>'' then begin
a[0,0]:=strtoint(StringGrid2.Cells[0,0]);
a[0,1]:=strtoint(StringGrid2.Cells[1,0]);
a[1,0]:=strtoint(StringGrid2.Cells[0,1]);
a[1,1]:=strtoint(StringGrid2.Cells[1,1]);
x[0,0]:= a[0,0]*str[0,0]+a[1,0]* str[0,1];
x[0,1] := a[0,1]*str[0,0]+a[1,1]* str[0,1];
draw_P(x[0,0],x[0,1]);
end
else
exit;
end;
1: begin
image1.Canvas.FillRect(Rect(0,0,image1.Width,image1.Height));
image1.Transparent:=true;
koord();
str[0,0]:=strtoint(StringGrid1.Cells[0,0]);
str[0,1]:=strtoint(StringGrid1.Cells[1,0]);
str[1,0]:=strtoint(StringGrid1.Cells[0,1]);
str[1,1]:=strtoint(StringGrid1.Cells[1,1]);
draw_P(str[0,0],str[0,1]);
draw_P(str[1,0],str[1,1]);
with image1.Canvas do begin
MoveTo(x0+str[0,0]*delta,y0-str[0,1]*delta);
LineTo(x0+str[1,0]*delta,y0-str[1,1]*delta);
end;
if StringGrid2.Cells[0,0]<>'' then begin
a[0,0]:=strtoint(StringGrid2.Cells[0,0]);
a[0,1]:=strtoint(StringGrid2.Cells[1,0]);
a[1,0]:=strtoint(StringGrid2.Cells[0,1]);
a[1,1]:=strtoint(StringGrid2.Cells[1,1]);
x[0,0]:= a[0,0]*str[0,0]+a[1,0]* str[0,1];
x[0,1] := a[0,1]*str[0,0]+a[1,1]* str[0,1];
draw_P(x[0,0],x[0,1]);
x[1,0]:= a[0,0]*str[1,0]+a[1,0]* str[1,1];
x[1,1] := a[0,1]*str[1,0]+a[1,1]* str[1,1];
draw_P(x[1,0],x[1,1]);
with image1.Canvas do begin
MoveTo(x0+x[0,0]*delta,y0-x[0,1]*delta);
LineTo(x0+x[1,0]*delta,y0-x[1,1]*delta);
end;
end
else
exit;
end;
2: begin
image1.Canvas.FillRect(Rect(0,0,image1.Width,image1.Height));
image1.Transparent:=true;
koord();
str[0,0]:=strtoint(StringGrid1.Cells[0,0]);
str[0,1]:=strtoint(StringGrid1.Cells[1,0]);
str[1,0]:=strtoint(StringGrid1.Cells[0,1]);
str[1,1]:=strtoint(StringGrid1.Cells[1,1]);
str[2,0]:=strtoint(StringGrid1.Cells[0,2]);
str[2,1]:=strtoint(StringGrid1.Cells[1,2]);
draw_P(str[0,0],str[0,1]);
draw_P(str[1,0],str[1,1]);
draw_P(str[2,0],str[2,1]);
with image1.Canvas do begin
MoveTo(x0+str[0,0]*delta,y0-str[0,1]*delta);
LineTo(x0+str[1,0]*delta,y0-str[1,1]*delta);
MoveTo(x0+str[1,0]*delta,y0-str[1,1]*delta);
LineTo(x0+str[2,0]*delta,y0-str[2,1]*delta);
MoveTo(x0+str[2,0]*delta,y0-str[2,1]*delta);
LineTo(x0+str[0,0]*delta,y0-str[0,1]*delta);
end;
if StringGrid2.Cells[0,0]<>'' then begin
a[0,0]:=strtoint(StringGrid2.Cells[0,0]);
a[0,1]:=strtoint(StringGrid2.Cells[1,0]);
a[1,0]:=strtoint(StringGrid2.Cells[0,1]);
a[1,1]:=strtoint(StringGrid2.Cells[1,1]);
x[0,0]:= a[0,0]*str[0,0]+a[1,0]* str[0,1];
x[0,1]:= a[0,1]*str[0,0]+a[1,1]* str[0,1];
draw_P(x[0,0],x[0,1]);
x[1,0]:= a[0,0]*str[1,0]+a[1,0]* str[1,1];
x[1,1] := a[0,1]*str[1,0]+a[1,1]* str[1,1];
draw_P(x[1,0],x[1,1]);
x[2,0]:= a[0,0]*str[2,0]+a[1,0]* str[2,1];
x[2,1] := a[0,1]*str[2,0]+a[1,1]* str[2,1];
draw_P(x[2,0],x[2,1]);
with image1.Canvas do begin
MoveTo(x0+x[0,0]*delta,y0-x[0,1]*delta);
LineTo(x0+x[1,0]*delta,y0-x[1,1]*delta);
MoveTo(x0+x[1,0]*delta,y0-x[1,1]*delta);
LineTo(x0+x[2,0]*delta,y0-x[2,1]*delta);
MoveTo(x0+x[2,0]*delta,y0-x[2,1]*delta);
LineTo(x0+x[0,0]*delta,y0-x[0,1]*delta);
end;
end;
end;
3: begin
image1.Canvas.FillRect(Rect(0,0,image1.Width,image1.Height));
image1.Transparent:=true;
koord();
str[0,0]:=strtoint(StringGrid1.Cells[0,0]);
str[0,1]:=strtoint(StringGrid1.Cells[1,0]);
str[1,0]:=strtoint(StringGrid1.Cells[0,1]);
str[1,1]:=strtoint(StringGrid1.Cells[1,1]);
str[2,0]:=strtoint(StringGrid1.Cells[0,2]);
str[2,1]:=strtoint(StringGrid1.Cells[1,2]);
str[0,2]:=strtoint(StringGrid1.Cells[2,0]);
str[1,2]:=strtoint(StringGrid1.Cells[2,1]);
str[2,2]:=strtoint(StringGrid1.Cells[2,2]);
draw_P(str[0,0],str[0,1]);
draw_P(str[1,0],str[1,1]);
draw_P(str[2,0],str[2,1]);
with image1.Canvas do begin
MoveTo(x0+str[0,0]*delta,y0-str[0,1]*delta);
LineTo(x0+str[1,0]*delta,y0-str[1,1]*delta);
MoveTo(x0+str[1,0]*delta,y0-str[1,1]*delta);
LineTo(x0+str[2,0]*delta,y0-str[2,1]*delta);
MoveTo(x0+str[2,0]*delta,y0-str[2,1]*delta);
LineTo(x0+str[0,0]*delta,y0-str[0,1]*delta);
end;
if StringGrid2.Cells[0,0]<>'' then begin
a[0,0]:=strtoint(StringGrid2.Cells[0,0]);
a[0,1]:=strtoint(StringGrid2.Cells[1,0]);
a[1,0]:=strtoint(StringGrid2.Cells[0,1]);
a[1,1]:=strtoint(StringGrid2.Cells[1,1]);
a[2,0]:=strtoint(StringGrid2.Cells[0,2]);
a[2,1]:=strtoint(StringGrid2.Cells[1,2]);
a[0,2]:=strtoint(StringGrid2.Cells[2,0]);
a[1,2]:=strtoint(StringGrid2.Cells[2,1]);
a[2,2]:=strtoint(StringGrid2.Cells[2,2]);
i:=0;
while i<=2 do
begin
j:=0;
while j<=2 do
begin
x[i,j] := 0;
l:=0;
while l<=2 do
begin
x[i,j] := x[i,j]+str[i,l]*a[l,j];
Inc(l);
end;
Inc(j);
end;
Inc(i);
end;
end;
draw_P(x[0,0],x[0,1]);
draw_P(x[1,0],x[1,1]);
draw_P(x[2,0],x[2,1]);
with image1.Canvas do begin
MoveTo(x0+x[0,0]*delta,y0-x[0,1]*delta);
LineTo(x0+x[1,0]*delta,y0-x[1,1]*delta);
MoveTo(x0+x[1,0]*delta,y0-x[1,1]*delta);
LineTo(x0+x[2,0]*delta,y0-x[2,1]*delta);
MoveTo(x0+x[2,0]*delta,y0-x[2,1]*delta);
LineTo(x0+x[0,0]*delta,y0-x[0,1]*delta);
end;
end;
end;
end;
procedure TForm1.RadioGroup1Click(Sender: TObject);
var i:integer;
begin
case RadioGroup1.ItemIndex of
0: begin
StringGrid1.RowCount:=1;
StringGrid1.Height:=StringGrid1.RowCount*33;
//StringGrid1.ColCount:=2;
//StringGrid1.Width:= StringGrid1.ColCount*66;
end;
1: begin
StringGrid1.RowCount:=2;
StringGrid1.Height:=StringGrid1.RowCount*33;
//StringGrid1.ColCount:=2;
//StringGrid1.Width:= StringGrid1.ColCount*66;
end;
2: begin
StringGrid1.RowCount:=3;
StringGrid1.Height:=StringGrid1.RowCount*33;
//StringGrid1.ColCount:=2;
//StringGrid1.Width:= StringGrid1.ColCount*66;
end;
3: begin
StringGrid1.ColCount:=3;
StringGrid1.RowCount:=3;
StringGrid1.Height:=StringGrid1.RowCount*33;
StringGrid1.Width:= StringGrid1.ColCount*66;
StringGrid2.ColCount:=3;
StringGrid2.RowCount:=3;
StringGrid2.Height:=StringGrid2.RowCount*33;
StringGrid2.Width:= StringGrid2.ColCount*66;
StringGrid2.Cells[0,0]:=inttostr(1);
StringGrid2.Cells[1,0]:=inttostr(0);
StringGrid2.Cells[2,0]:=inttostr(0);
StringGrid2.Cells[0,1]:=inttostr(0);
StringGrid2.Cells[1,1]:=inttostr(1);
StringGrid2.Cells[2,1]:=inttostr(0);
StringGrid2.Cells[2,2]:=inttostr(1);
for i:=0 to 2 do
StringGrid1.Cells[2,i]:=inttostr(1);
end;
end;
end;
end.
Результати роботи програми:
Рис1. Перетворення точки.
Рис1. Перетворення відрізка.
Рис3. Перетворення трикутника.
Рис4. Двовимірний зсув і однорідні координати.
Висновок: На даній лабораторній роботі я ознайомилась з основами комп’ютерної графіки. Побудувала точку у декартовій системі координат і здійснила yci перетворення точок за допомогою матричних перетворень.Також побудувала відрізок і здійснила його перетворення. І трикутник, здійснивши такі його перетворення,як: обертання, відображення, масштабування , зсув і двовимірний зсув.