Download - Tugas II Transformasi 3d (Fauzan NurAhmadi
Tugas II
Grafika Interaktif dan Multimedia
Transformasi Tiga Dimensi (3D)
Fauzan Nur Ahmadi
09/291925/PPA/02983
Magister Ilmu Komputer
Fakultas Matematika dan Ilmu Pengetahuan Alam
Universitas Gadjah Mada
2010 – 2011
Transformasi Tiga Dimensi (3D)
Pada obyek tiga dimensi dapat dilakukan 3 transformasi pokok yaitu penggeseran
(translation), perputaran (rotasi) , pembesaran (scaling). Adapun jenis transformasi lain
adalah pembebanan (shearing), dan pencerminan (mirroring). Didalam program,
transformasi ini juga dapat dilakukan dengan mengubah persamaan menjadi operasi matriks
4x4. Adapun persamaan setiap transformasi adalah sebagai berikut.
1. Pergeseran (translation)
(x’,y’,z’)=(Tx+x,Ty+y,Tz+z)
dengan x’,y’, z’ : koordinat hasil transformasi x,y,z : koordinat titik awal Tx,Ty, Tz :
faktor penggeseran kearah x, y, z
2. Pembesaran (scaling)
( x’,y’,z’ ) = (Sx *x, Sy *y, Sz *z)
dengan Sx,Sy, Sz : faktor pembesaran kearah x, y, z
3. Perputaran (rotation)
a. Terhadap sumbu X
( x’,y’, z’ ) = (x , y *cos q +z*sinq, - y *sinq+z*consq)
b. Terhadap sumbu Y
( x’,y’,z’ ) = ( x *cos q +z*sinq,y , - x *sinq+z*consq)
c. Terhadap sumbu Z
x’,y’, z’ ) = ( x *cos q +y*sinq, - x*sinq+y*consq , z )
dengan q : sudut putar berlawanan arah jarum jam
Algoritma Clipping
Clipping merupakan sebuah prosedur untuk menangkap sebagian porsi (bukan
keseluruhan) dari suatu objek, baik di dalam maupun di luar objek tersebut. Daerah dimana
suatu objek ditangkap disebut sebagai daerah/ jendela clipping.
Ada berbagai macam algoritma clipping yang umum dikenal, di antaranya algoritma Cohen-
Sutherland dan algoritma Liang-Barsky untuk garis, serta algoritma Sutherland-Hodgman
dan algoritma Weiler-Atherton untuk polygon.
Pada tugas ini, penulis mengembangkan algoritma clipping dari algoritma Bresenham untuk
membentuk garis. Konsepnya cukup sederhana, karena algoritma Bresenham membentuk
sebuah garis melalui perhitungan titik koordinat (𝑥,𝑦) untuk tiap pixel, maka dengan
dibatasi oleh suatu clipping region, dapat diputuskan titik-titik koordinat (pixel-pixel) yang
tidak terdapat di dalam clipping region tersebut. Untuk titik-titik koordinat yang berada di
dalam clipping region akan di-plot, sementara untuk titik-titik koordinat yang berada di luar
clipping region tidak di-plot.
Kode Program Transformasi 3D
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OpenGL, MyOpenGL, Mesh, StdCtrls, ExtCtrls, ComCtrls,Transf3D;
type
TForm1 = class(TForm)
Panel1: TPanel;
GroupBox1: TGroupBox;
ETRZ: TEdit;
ETRY: TEdit;
ETRX: TEdit;
Trx: TLabel;
Label1: TLabel;
Label2: TLabel;
TranslasiBtn: TButton;
GroupBox2: TGroupBox;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
ESZ: TEdit;
ESY: TEdit;
ESX: TEdit;
SkalaBtn: TButton;
GroupBox3: TGroupBox;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
ERZ: TEdit;
ERY: TEdit;
ERX: TEdit;
RotasiBtn: TButton;
ESudut: TEdit;
VertexView: TListView;
Label6: TLabel;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure TranslasiBtnClick(Sender: TObject);
procedure SkalaBtnClick(Sender: TObject);
procedure RotasiBtnClick(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{ Private declarations }
ftrx, ftry, ftrz:real;
frx, fry, frz:real;
fsx,fsy,fsz:real;
fsudut:real;
fmode_transformasi:byte;
fKubus:TKubus;
fTransf:TTransf3D;
procedure AmbilVertex;
procedure TransformVertex;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
const
TRANSF_TRANSLASI = 0;
TRANSF_ROTASI = 1;
TRANSF_SKALA = 2;
procedure TForm1.TransformVertex;
var
index:integer;
vp,v:TVertex3D;
begin
for index:=0 to fKubus.VertexCount-1 do
begin
v:=fKubus.Vertex[index];
fTransf.Transform(v.vertex, vp.vertex);
fKubus.ChangeVertex(index,vp.vertex.x, vp.vertex.y, vp.vertex.z);
end;
end;
procedure TForm1.AmbilVertex;
var
index:integer;
item:TListItem;
begin
//bersihkan VertexView
VertexView.Items.Clear;
for index:=0 to fKubus.VertexCount-1 do
begin
item:=VertexView.Items.Add;
with fKubus do
begin
item.Caption:= Format('%2.2f',[Vertex[index].vertex.x]);
item.SubItems.Add(Format('%2.2f',[Vertex[index].vertex.y]));
item.SubItems.Add(Format('%2.2f',[Vertex[index].vertex.z]));
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fKubus:=TKUbus.Create(true,true,1.0,1.0,0.0);
fKubus.ChangeColor(KUBUS_ATAS,1.0,0.0,0.0);
fTransf:=TTransf3D.Create;
ftrx:=0; ftry:=0; ftrz:=0;
frx:=0; fry:=0; frz:=0;
fsx:=0; fsy:=0; fsz:=0;
fmode_transformasi:=9;
glDC:=GetDC(Handle);
InitOpenGL(glDC);
Axis3D:=TAxis3D.Create;
glEnable(GL_DEPTH_TEST);
// glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glViewport(Panel1.Width,0,Width-Panel1.Width,Height-Memo1.Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(45, (width - Panel1.Width)/height,1.0, 100.0);
gluLookAt(3.0, 2.0, 3.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
end;
procedure TForm1.FormPaint(Sender: TObject);
var
index:integer;
v,vp:TPoint3D;
begin
glClearCOlor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
{ glLoadIdentity;
case fmode_transformasi of
TRANSF_TRANSLASI : glTranslatef(ftrx,ftry,ftrz);
TRANSF_ROTASI : glRotatef(fsudut, frx, fry, frz);
TRANSF_SKALA : glScalef(fsx,fsy,fsz);
end;}
fKubus.Draw;
Axis3D.Draw;
glFlush;
//update daftar vertex
AmbilVertex;
end;
procedure TForm1.TranslasiBtnClick(Sender: TObject);
begin
ftrx:=StrToFloat(ETRX.Text);
ftry:=StrToFloat(ETRY.Text);
ftrz:=StrToFloat(ETRZ.Text);
fmode_transformasi:=TRANSF_TRANSLASI;
fTransf.ClearTransformation;
fTransf.Translation(ftrx,ftry,ftrz);
TransformVertex;
Repaint;
end;
procedure TForm1.SkalaBtnClick(Sender: TObject);
begin
fsx:=StrToFloat(ESX.Text);
fsy:=StrToFloat(ESY.Text);
fsz:=StrToFloat(ESZ.Text);
fmode_transformasi:=TRANSF_SKALA;
fTransf.ClearTransformation;
fTransf.Scaling(fsx,fsy,fsz,0,0,0);
TransformVertex;
Repaint;
end;
procedure TForm1.RotasiBtnClick(Sender: TObject);
begin
frx:=StrToFloat(ERX.Text);
fry:=StrToFloat(ERY.Text);
frz:=StrToFloat(ERZ.Text);
fsudut:=StrToFloat(ESudut.Text);
fmode_transformasi:=TRANSF_ROTASI;
fTransf.ClearTransformation;
fTransf.Rotation(fsudut,frx,fry,frz);
TransformVertex;
Repaint;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
glViewport(Panel1.Width,0,Width-Panel1.Width,Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(45, (width - Panel1.Width)/height,1.0, 100.0);
gluLookAt(8.0, 4.0, 9.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
Repaint;
end;
end.
//class mase
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OpenGL, MyOpenGL, Mesh, StdCtrls, ExtCtrls, ComCtrls,Transf3D;
type
TForm1 = class(TForm)
Panel1: TPanel;
GroupBox1: TGroupBox;
ETRZ: TEdit;
ETRY: TEdit;
ETRX: TEdit;
Trx: TLabel;
Label1: TLabel;
Label2: TLabel;
TranslasiBtn: TButton;
GroupBox2: TGroupBox;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
ESZ: TEdit;
ESY: TEdit;
ESX: TEdit;
SkalaBtn: TButton;
GroupBox3: TGroupBox;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
ERZ: TEdit;
ERY: TEdit;
ERX: TEdit;
RotasiBtn: TButton;
ESudut: TEdit;
VertexView: TListView;
Label6: TLabel;
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure TranslasiBtnClick(Sender: TObject);
procedure SkalaBtnClick(Sender: TObject);
procedure RotasiBtnClick(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{ Private declarations }
ftrx, ftry, ftrz:real;
frx, fry, frz:real;
fsx,fsy,fsz:real;
fsudut:real;
fmode_transformasi:byte;
fKubus:TKubus;
fTransf:TTransf3D;
procedure AmbilVertex;
procedure TransformVertex;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
const
TRANSF_TRANSLASI = 0;
TRANSF_ROTASI = 1;
TRANSF_SKALA = 2;
procedure TForm1.TransformVertex;
var
index:integer;
vp,v:TVertex3D;
begin
for index:=0 to fKubus.VertexCount-1 do
begin
v:=fKubus.Vertex[index];
fTransf.Transform(v.vertex, vp.vertex);
fKubus.ChangeVertex(index,vp.vertex.x, vp.vertex.y, vp.vertex.z);
end;
end;
procedure TForm1.AmbilVertex;
var
index:integer;
item:TListItem;
begin
//bersihkan VertexView
VertexView.Items.Clear;
for index:=0 to fKubus.VertexCount-1 do
begin
item:=VertexView.Items.Add;
with fKubus do
begin
item.Caption:= Format('%2.2f',[Vertex[index].vertex.x]);
item.SubItems.Add(Format('%2.2f',[Vertex[index].vertex.y]));
item.SubItems.Add(Format('%2.2f',[Vertex[index].vertex.z]));
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fKubus:=TKUbus.Create(true,true,1.0,1.0,0.0);
fKubus.ChangeColor(KUBUS_ATAS,1.0,0.0,0.0);
fTransf:=TTransf3D.Create;
ftrx:=0; ftry:=0; ftrz:=0;
frx:=0; fry:=0; frz:=0;
fsx:=0; fsy:=0; fsz:=0;
fmode_transformasi:=9;
glDC:=GetDC(Handle);
InitOpenGL(glDC);
Axis3D:=TAxis3D.Create;
glEnable(GL_DEPTH_TEST);
// glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glViewport(Panel1.Width,0,Width-Panel1.Width,Height-Memo1.Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(45, (width - Panel1.Width)/height,1.0, 100.0);
gluLookAt(3.0, 2.0, 3.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
end;
procedure TForm1.FormPaint(Sender: TObject);
var
index:integer;
v,vp:TPoint3D;
begin
glClearCOlor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
{ glLoadIdentity;
case fmode_transformasi of
TRANSF_TRANSLASI : glTranslatef(ftrx,ftry,ftrz);
TRANSF_ROTASI : glRotatef(fsudut, frx, fry, frz);
TRANSF_SKALA : glScalef(fsx,fsy,fsz);
end;}
fKubus.Draw;
Axis3D.Draw;
glFlush;
//update daftar vertex
AmbilVertex;
end;
procedure TForm1.TranslasiBtnClick(Sender: TObject);
begin
ftrx:=StrToFloat(ETRX.Text);
ftry:=StrToFloat(ETRY.Text);
ftrz:=StrToFloat(ETRZ.Text);
fmode_transformasi:=TRANSF_TRANSLASI;
fTransf.ClearTransformation;
fTransf.Translation(ftrx,ftry,ftrz);
TransformVertex;
Repaint;
end;
procedure TForm1.SkalaBtnClick(Sender: TObject);
begin
fsx:=StrToFloat(ESX.Text);
fsy:=StrToFloat(ESY.Text);
fsz:=StrToFloat(ESZ.Text);
fmode_transformasi:=TRANSF_SKALA;
fTransf.ClearTransformation;
fTransf.Scaling(fsx,fsy,fsz,0,0,0);
TransformVertex;
Repaint;
end;
procedure TForm1.RotasiBtnClick(Sender: TObject);
begin
frx:=StrToFloat(ERX.Text);
fry:=StrToFloat(ERY.Text);
frz:=StrToFloat(ERZ.Text);
fsudut:=StrToFloat(ESudut.Text);
fmode_transformasi:=TRANSF_ROTASI;
fTransf.ClearTransformation;
fTransf.Rotation(fsudut,frx,fry,frz);
TransformVertex;
Repaint;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
glViewport(Panel1.Width,0,Width-Panel1.Width,Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(45, (width - Panel1.Width)/height,1.0, 100.0);
gluLookAt(8.0, 4.0, 9.0,
0.0, 0.0, 0.0,
0.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
Repaint;
end;
end.
Printperview Program
Translasi (Tx,Ty,Tz) sebesar (2,2,0) dari (0,0,0)
Rotasi (1,1,0) dengan sudut -45 dari (0,0,0)
Sekalar (2,2,2) dari posisi (0,0,0)