Anda di halaman 1dari 138

APLIKASI GRAFIKA KOMPUTER UNTUK

TRANSFORMASI GEOMETRI 3 DIMENSI

Tugas Akhir
untuk memenuhi sebagian persyaratan mencapai
derajat Sarjana Teknik

oleh

Alfa Ryano Yohannis


L2F002548

JURUSAN TEKNIK ELEKTRO


FAKULTAS TEKNIK
UNIVERSITAS DIPONEGORO
SEMARANG
2006
HALAMAN PENGESAHAN

Laporan Tugas Akhir dengan judul “APLIKASI GRAFIKA KOMPUTER


UNTUK TRANSFORMASI GEOMETRI 3 DIMENSI” yang disusun oleh

Nama : Alfa Ryano Yohannis


NIM : L2F002548

Telah disetujui dan disahkan untuk dijadikan laporan Tugas Akhir sebagai salah
satu syarat menyelesaikan program Strata Satu Jurusan Teknik Elektro Fakultas
Teknik Universitas Diponegoro Semarang.

Menyetujui dan mengesahkan

Pembimbing I Pembimbing II

Agung B.P., S.T., M.I.T. Eko Handoyo, S.T., M.T.


NIP. 132 137 932 NIP. 132 309 142
Tanggal September 2006 Tanggal September 2006

Mengetahui
a.n. Dekan
Ketua Jurusan Teknik Elektro
Fakultas Teknik Universitas Diponengoro

Ir. Sudjadi, M.T.


NIP. 131 558 567
Tanggal September 2006
Tugas Akhir
APLIKASI GRAFIKA KOMPUTER UNTUK
TRANSFORMASI GEOMETRI 3 DIMENSI

yang dipersiapkan dan disusun oleh

Alfa Ryano Yohannis


L2F002548

Telah dipertahankan di depan para Dosen Penguji


Pada tanggal September 2006
Dan dinyatakan telah memenuhi syarat

Susunan Dosen Penguji

Tanda tangan

Ketua : Aghus Sofwan, S.T., M.T.


NIP. 132 163 757 Tanggal: September 2006

Sekretaris : Maman Somantri, S.T., M.T.


NIP. 132 231 133 Tanggal: September 2006

Anggota : Imam Santoso, S.T., M.T.


NIP. 132 162 546 Tanggal: September 2006
KATA PENGANTAR

Puji syukur kepada Allah Bapa yang bertahta di dalam Kerajaan Sorga yang
telah memberikan karunia-Nya sehingga penyusun dapat menyelesaikan Tugas
Akhir ini. Terpujilah nama-Nya kekal selama-lamanya.
Tugas Akhir ini dibuat sebagai syarat untuk memenuhi gelar Sarjana Teknik
di Jurusan Teknik Elektro Fakutas Teknik Universitas Diponegoro. Penyusun
mengharapkan Tugas Akhir ini dapat bermanfaat bagi pengembangan ilmu
pengetahuan di bidang grafika komputer khususnya di Teknik Elektro Universitas
Diponegoro..
Penyusun mengucapkan terima kasih kepada pihak-pihak yang telah
membantu dalam penyelesaian Tugas Akhir, yaitu:
1. Bapak Agung B.P. sebagai Dosen Pembimbing I. Terima kasih karena beliau
sudah membimbing, mengarahkan, mengkoreksi, dan memberi masukan
dalam penyelesaian Tugas Akhir ini,
2. Bapak Eko Handoyo sebagai Dosen Pembimbing II. Terima kasih karena
beliau telah menolong dalam analisis dan perancangan Tugas Akhir serta
mengkoreksi tata penulisan laporan,
3. Orang tua penyusun yang terus mengingatkan dan mendorong agar segera
menyelesaian Tugas Akhir, dan
4. Pihak-pihak yang tidak bisa penyusun sebutkan satu per satu. Terima kasih
buat setiap bantuan kalian.
Tugas Akhir ini masih memiliki kekurangan. Oleh karena itu, penyusun
meminta maaf. Saran dan kritik Anda sangat diperlukan bagi menyempurnakan
Tugas Akhir ini. Terima kasih.

Semarang, 19 September 2006

Penulis

i
DAFTAR ISI

KATA PENGANTAR ............................................................................................ i


DAFTAR ISI .......................................................................................................... ii
DAFTAR GAMBAR ..............................................................................................v
DAFTAR TABEL ............................................................................................... vii
ABSTRAK .......................................................................................................... viii

BAB I PENDAHULUAN .......................................................................................1


1.1. Latar Belakang .............................................................................................1
1.2. Identifikasi Masalah .....................................................................................2
1.3. Batasan Masalah ...........................................................................................3
1.4. Tujuan Penelitian..........................................................................................3
1.5. Kegunaan Hasil Penelitian ...........................................................................3
1.6. Sistematika Penulisan ...................................................................................4

BAB II TRANSFORMSI GEOMETRI


PADA RUANG 3 DIMENSI .................................................................................5
2.1. Transformasi 3 Dimensi ...............................................................................5
2.1.1. Translasi ...........................................................................................6
2.1.2. Penskalaan ........................................................................................7
2.1.3. Rotasi ................................................................................................7
2.1.4. Shearing ............................................................................................8
2.1.5. Transformasi Komposit ....................................................................9
2.1.6. Rotasi menggunakan sumbu yang tidak melewati titik origin .........9
2.1.7. Penskalaan Menggunakan Sembarang Titik Pusat .........................10
2.2. Transformasi 3 Dimensi pada OpenGL .....................................................10
2.3. Penggunaan OpenGL pada Delphi untuk Transformasi 3D.......................12
2.4. Representasi Objek 3 Dimensi ...................................................................14
2.5. Interaksi Pengguna dengan Aplikasi ..........................................................15

ii
iii

BAB III PERANCANGAN APLIKASI GRAFIKA KOMPUTER


UNTUK TRANSFORMASI OBJEK 3D ...........................................................17
3.1. Use Case ....................................................................................................17
3.2. Kartu Index CRC ........................................................................................18
3.3. Diagram Kelas ............................................................................................21
3.4. Model Hubungan Objek (Object Relationship) .........................................21
3.5. Model Tingkah Laku Objek (Object Behaviour) .......................................23
3.6. Perancangan Antarmuka ............................................................................24

BAB IV IMPLEMENTASI DAN PENGUJIAN APLIKASI


GRAFIKA KOMPUTER UNTUK TRANSFORMASI OBJEK 3D ...............25
4.1. Implementasi Aplikasi ...............................................................................25
4.1.1. Implementasi Tampilan ..................................................................25
4.1.2. Implementasi Objek Geometri .......................................................28
a. Piramida .....................................................................................28
b. Kubus .........................................................................................29
c. Silinder .......................................................................................30
d. Daftar Geometri .........................................................................32
4.1.3. Implementasi Vektor ......................................................................33
4.1.4. Implementasi Transformasi 3D ......................................................35
a. Perkalian Matriks .......................................................................35
b. Matriks Identitas ........................................................................35
c. Translasi .....................................................................................36
d. Penskalaan .................................................................................36
e. Rotasi .........................................................................................37
f. Shearing .....................................................................................38
g. Matriks Transform .....................................................................39
4.1.5. Implementasi Transformasi Menggunakan Mouse ........................39
4.1.6. Implementasi Benda Rumit ............................................................41
4.2. Pengujian Validasi Fungsi Transformasi Aplikasi .....................................43
4.2.1. Pengujian Transformasi Rotasi.......................................................44
a. Contoh perhitungan ...................................................................45
b. Perbandingan antara hasil perhitungan dan hasil aplikasi .........45
4.2.2. Pengujian Transformasi Penskalaan ...............................................45
iv

a. Contoh perhitungan ...................................................................46


b. Perbandingan antara hasil perhitungan dan hasil aplikasi .........47
4.2.3. Pengujian Transformasi Rotasi.......................................................47
a. Contoh perhitungan ...................................................................48
b. Perbandingan antara hasil perhitungan dan hasil aplikasi .........52
4.2.4. Pengujian Transformasi Shearing ..................................................52
a. Contoh perhitungan ...................................................................53
b. Perbandingan antara hasil perhitungan dan hasil aplikasi .........53
4.3. Pengujian Framerate..................................................................................54
5.3.1. Pengujian Framerate Rotasi ............................................................56
5.3.2. Pengujian Framerate Translasi .......................................................57
5.3.3. Pengujian Framerate Penskalaan ....................................................58
5.3.4. Pengujian Framerate Rotasi ............................................................59

BAB V KESIMPULAN DAN SARAN ...............................................................61


5.1. Keimpulan ..................................................................................................61
5.2. Saran ...........................................................................................................62

DAFTAR PUSTAKA ..........................................................................................63


LAMPIRAN A KODE PROGRAM ...................................................................65
PtugasAkhir.dpr .....................................................................................................65
unitUtama.pas.........................................................................................................65
Vektor.pas ..............................................................................................................84
unitPenskalaan.pas .................................................................................................85
unitRotasi.pas .........................................................................................................87
unitShearing.pas .....................................................................................................88
unitTranslasi.pas.....................................................................................................90
unitAbout.pas .........................................................................................................91
Geometri.pas ..........................................................................................................91
Transformasi.pas ..................................................................................................108
LAMPIRAN B WAVEFRONT OBJ FILE FORMAT SUMMARY ............112
LAMPIRAN C PERINTAH OPENGL PADA APLIKASI
GRAFIKA KOMPUTER UNTUK TRANSFORMASI 3D ...........................117
LAMPIRAN D MAKALAH SEMINAR..........................................................120
DAFTAR GAMBAR

BAB I PENDAHULUAN
Gambar 1.1 Aplikasi komputer grafis: Blender .......................................................1
Gambar 1.2 3DS Max 8: Aplikasi Penampil Objek 3D ...........................................2

BAB II TRANSFORMSI GEOMETRI


Gambar 2.1 Rotasi menggunan sumbu yang tidak melewati titik origin .................9
Gambar 2.2 Objek geometri kubus ........................................................................14

BAB III ANALISIS DAN PENCANGAN APLIKASI


Gambar 3.1 Diagram use case aplikasi grafika komputer
untuk transformasi dimensi ....................................................................................18
Gambar 3.2 Diagram kelas aplikasi grafika komputer
untuk transformasi 3 dimensi ................................................................................21
Gambar 3.3 Diagram runtun aplikasi grafika komputer
untuk transformasi 3 dimensi ................................................................................22
Gambar 3.4 Diagram statechart aplikasi grafika komputer
untuk transformasi 3 dimensi ................................................................................23
Gambar 3.5 Desain antarmuka aplikasi grafika komputer
untuk transformasi 3 dimensi ................................................................................24

BAB IV IMPLEMENTASI DAN PENGUJIAN APLIKASI


Gambar 4.1 Tampilan aplikasi grafika komputer untuk transformasi 3 dimensi ..25
Gambar 4.2 Toolbar dan menu aplikasi .................................................................26
Gambar 4.3 Tampilan tab-tab untuk objek kubus, piramid,
silinder, meja, dan kursi .........................................................................................26
Gambar 4.4 Status bar ............................................................................................27
Gambar 4.5 Tampilan popup menu hasil klik kanan .............................................27
Gambar 4.6 Form untuk transformasi translasi, penskalaan, rotasi, dan shearing .27
Gambar 4.7 Objek geometri piramida....................................................................28
Gambar 4.8 Objek geometri kubus ........................................................................29

v
vi

Gambar 4.9 Objek geometri silinder ......................................................................30


Gambar 4.10 Objek mobil dan bola menggunakan obj loader (a) posisi awal
(b) posisi setelah rotasi ...........................................................................................42

Gambar 4.11 Posisi awal piramida pada layar aplikasi..........................................43


Gambar 4.12 Form untuk memasukkan nilai translasi ..........................................44
Gambar 4.13 Piramida: (a) sebelum translasi (b) sesudah translasi.......................44
Gambar 4.14 Form untuk memasukkan nilai penskalaan ......................................46
Gambar 4.15 Piramida: (a) sebelum penskalaan (b) sesudah penskalaan ..............46
Gambar 4.16 Form untuk memasukkan nilai rotasi ...............................................47
Gambar 4.17 Piramida: (a) sebelum rotasi (b) sesudah rotasi ...............................48
Gambar 4.18 Form untuk memasukkan nilai shearing ..........................................52
Gambar 4.19 Piramida: (a) sebelum shearing (b) sesudah shearing ......................53
Gambar 2.20 Pengujian framerate untuk penskalaan
(a) aplikasi yang menggunakan fungsi transformasi bawaan sendiri
(b) aplikasi menggunakan fungsi transformasi bawaan OpenGL. .........................56
DAFTAR TABEL

BAB II TRANSFORMASI GEOMETRI PADA RUANG 3D


Tabel 2.1 Verteks penyusun kubus ........................................................................15

BAB III ANALISIS DAN PENCANGAN APLIKASI


Tabel 3.1 Kartu indeks CRC kelas objek geometri ................................................19
Tabel 3.2 Kartu indeks CRC kelas kubus...............................................................19
Tabel 3.3 Kartu indeks CRC kelas piramid ............................................................19
Tabel 3.4 Kartu indeks CRC kelas silinder ............................................................19
Tabel 3.5 Kartu indeks CRC kelas meja ................................................................20
Tabel 3.6 Kartu index CRC kelas kursi ..................................................................20
Tabel 3.7 Kartu indeks CRC kelas Transformasi ...................................................20

BAB IV IMPLEMENTASI DAN PENGUJIAN APLIKASI


Tabel 4.1 Koordinat awal titik-titik piramida ........................................................44
Tabel 4.2 Perbandingan antara hasil perhitungan dan
hasil aplikasi untuk translasi ................................................................................45
Tabel 4.3 Perbandingan antara hasil perhitungan dan
hasil aplikasi untuk pensklaan ................................................................................47
Tabel 4.4 Perbandingan antara hasil perhitungan dan
hasil aplikasi untuk rotasi .......................................................................................52
Tabel 4.5 Perbandingan antara hasil perhitungan dan
hasil aplikasi untuk shearing................................................................................54
Tabel 4.6 Perbandingan framerate transformasi aplikasi dan OpenGL
untuk transformasi rotasi ........................................................................................57
Tabel 4.7 Perbandingan framerate transformasi aplikasi dan OpenGL
untuk transformasi translasi ...................................................................................57
Tabel 4.8 Perbandingan framerate transformasi aplikasi dan OpenGL
untuk transformasi penskalaan ...............................................................................58
Tabel 4.9 Perbandingan framerate ransformasi aplikasi dan OpenGL. .................59

vii
ABSTRAK

Perkembangan teknologi di bidang grafika komputer begitu pesat. Ini terbukti dengan
banyaknya aplikasi yang menggunakan grafika komputer antara lain video game, CAD, dan
simulator. Grafika komputer sendiri tidak lepas dari transformasi geometri. Dengan transformasi
geometri, suatu objek geometri dapat dipindahkan dan diubah bentuknya. Masalah yang timbul,
yaitu bagaimana mengimplementasikan transformasi geometri tersebut ke dalam suatu aplikasi.
Transformasi geometri yang dapat dilakukan oleh aplikasi berupa translasi, rotasi, penskalaan,
dan shearing. Selain itu, aplikasi tersebut dapat digunakan dengan mudah oleh pengguna untuk
menampilkan objek 3 dimensi dan mentransformasinya.
Agar menghasilkan suatu aplikasi yang dapat mengimplementasikan transformasi geometri,
aplikasi dibuat dengan menggunakan bahasa pemrograman Delphi dan API OpenGL. OpenGL
digunakan untuk menampilkan objek 3 dimensi dan Delphi digunakan untuk membuat antarmuka
pengguna, struktur data, dan fungsi-fungsi transformasi. Perancangan dilakukan dengan
menggunakan pendekatan berorientasi objek. Sebagai parameter aplikasi dapat berjalan baik,
aplikasi dapat mentransformasi objek 3 dimensi melalui antarmuka pengguna yang dibuat dan
hasil transformasinya sesuai dengan persamaan transformasi geometri.
Sebagai implementasi, aplikasi dibuat dalam bentuk aplikasi studio yang dapat menerapkan
transformasi 3 dimensi pada objek geometri. Pengujian dilakukan dengan membandingkan hasil
transformasi aplikasi dan hasil transformasi melalui perhitungan untuk melihat apakah aplikasi
dapat mentransformasi dengan tepat. Hasilnya, koordinat-koordinat hasil transformasi aplikasi
sama dengan hasil perhitungan. Pengujian juga dilakukan dengan membandingkan framerate
antara fungsi transformasi aplikasi dan fungsi transformasi bawaan OpenGL. Hasilnya, fungsi
transformasi bawaan OpenGL memiliki framerate lebih tinggi dibandingkan fungsi aplikasi.

Kata kunci: transformasi, rotasi, penskalaan, translasi, shearing, OpenGL

viii
ABSTRACT
Computer graphics technology grows rapidly. It can be seen by many application that use
computer graphics such as video game, CAD, and simulator. Computer graphics itselves are not
free from gometric transformation. By goemetric transformation, an geometric object can be
moved and it’s shape can be changed. The problem that appear is how to implement geometric
transformation into an application. Geometric transformations that can be done by the application
are translation, rotation, scaling, and shearing. Beside that, the application can be used easily by
user to show 3 dimension objects and transform them.
In order to produce an application that can implement geometric transformation, the
application is made by using Delphi programming language OpenGL API. OpenGL is used to
show 3 dimension object and Delphi is used to make user interface, data stucture, and functions of
tranformation. Design is performed by using object oriented approach. As parameters if the
application run well, the application can transform 3 dimension object by using it’s user interface
and the it’s transformation result equal to the geometric transformation equation.
As implementation, application is made in a studio form that can do 3 dimension
transfomation on geometric objects. The testing is performed by comparing application
transformation results with transformation results from calculation to show if the application can
transform correctly. The results, coordinates from the application transformation results are equal
with the results from calculation. The testing is also performed by comparing framerate between
application transformation functions and OpenGL transformation functions. The results, OpenGL
transformation functions has higher framerate than the application functions have.

Keywords: transformation, translation, rotation, scaling, shearing, and OpenGL

ix
BAB I

PENDAHULUAN

1.1 Latar Belakang Masalah


Grafika komputer–salah satu cabang ilmu komputer–berkembang cukup
pesat. Ini terbukti dengan banyaknya bidang yang menerapkan grafika komputer
seperti video game, CAD (Computer Aided Design), animasi, simulasi, dan lain-
lain. Gambar 1.1 memperlihatkan aplikasi komputer grafis bernama Blender[17]
yang biasa digunakan untuk pemodelan dan animasi.

Gambar 1.1 Aplikasi komputer grafis: Blender.

Grafika komputer sendiri terbagi beberapa bagian, yaitu transformasi


(transformation), pewarnaan (colouring), shading, dan ray tracing. Transformasi
memiliki bagian yang penting pada grafika komputer. Dengan transformasi, suatu
objek dapat dipindahkan dari satu tempat ke tempat yang lain, ukurannya dapat
diperbesar atau diperkecil, objek dapat mengalami shearing, atau objek dapat
diputar dengan besar sudut dan arah tertentu. Transformasi juga memiliki peran
penting dalam membentuk animasi, misalnya animasi suatu objek begerak dari
titik A ke titik B. Objek tersebut mengalami transformasi translasi dari titik A ke
titik B dalam selang waktu tertentu.

1
2

Tugas akhir ini mencoba mengimplementasikan transformasi 3 dimensi


dalam bentuk suatu aplikasi studio. Aplikasi dapat membuat suatu objek yang
kemudian dapat ditransformasikan sesuai dengan transformasi yang dimiliki oleh
aplikasi tersebut. Transformasi yang dapat dilakukan berupa translasi, penskalaan,
rotasi, dan shearing. Analisis dan perancangan aplikasi menggunakan pendekatan
berorientasi objek. Aplikasi dibuat dengan menggunakan bahasa pemrograman
Delphi dan OpenGL API (Application Programming Interface).

Gambar 1.2 3DS Max 8: Aplikasi Penampil Objek 3 Dimensi.

Tugas Akhir ini diharapkan dapat menghasilkan suatu aplikasi studio yang
dapat melakukan transformasi 3 dimensi pada objek yang dibuat. Aplikasi dapat
melakukan transformasi translasi, penskalaan, rotasi, dan shearing seperti yang
terdapat pada aplikasi-aplikasi pemodelan 3 dimensi, antara lain 3DS Max[16]
(gambar 1.2) atau Blender (gambar 1.1). Aplikasi juga diharapkan memiliki
antarmuka yang mudah digunakan (user friendly) sehingga mempermudah
melakukan transformasi 3 dimensi pada objek.

1.2 Identifikasi Masalah


Dalam mengimplementasikan aplikasi grafika komputer untuk transformasi
3 dimensi dapat diidentifikasi 3 masalah utama, yaitu:
3

1. Bagaimana merepresentasikan objek 3 dimensi sehingga dapat ditampilkan


pada layar.
2. Melakukan transformasi pada objek 3 dimensi pada aplikasi tersebut.
Tansformasi meliputi translasi, penskalaan, shearing, dan rotasi.
3. Antarmuka pengguna dengan program sehingga pengguna dapat melakukan
transformasi pada objek sesuai yang dikehendaki.

1.3 Batasan Masalah


1. Tugas Akhir ini membahas mengenai implementasi transformasi 3 dimensi
dalam bentuk suatu aplikasi studio penampil objek 3 dimensi.
2. Implementasi transformasi 3 dimensi menggunakan bahasa pemrograman
Delphi dan API OpenGL.
3. Analisis dan perancangan aplikasi menggunakan pendekatan berorientasi
objek.

1.4 Tujuan Penelitian


Tujuan penelitian adalah implementasi fungsi-fungsi transformasi 3 dimensi
dalam bentuk suatu aplikasi studio.

1.5 Kegunaan Hasil Penelitian


Kegunaan dari Tugas Akhir Implementasi Transformasi 3 Dimensi
Komputer Grafis Pada Aplikasi Penampil Objek 3 Dimensi, yaitu:
1. Mengetahui bagaimana mengimplementasikan transformasi 3 dimensi pada
aplikasi 3 dimensi menggunakan OpenGL dan Delphi dengan pendekatan
berorientasi objek.
2. Menghasilkan suatu aplikasi yang dapat melakukan transformasi 3 dimensi.
Aplikasi ini dapat dikembangkan lebih untuk fungsi-fungsi yang lebih luas
yang berkaitan dengan Grafika Komputer, seperti pewarnaan, texture mapping,
rendering, dan animasi.

1.6 Sistematika Penulisan Laporan


Laporan Tugas Akhir yang berjudul Aplikasi Grafika Komputer untuk
Transformasi Geometri 3 Dimensi tersusun dari lima bab, yaitu Bab I
Pendahuluan, Bab II Transformasi Geometri pada Ruang 3 Dimensi, Bab III
4

Perancangan Aplikasi Grafika Komputer untuk Transformasi Geometri 3


Dimensi, Bab IV Implementasi dan Pengujian Aplikasi Grafika Komputer untuk
Transformasi Geometri 3 Dimensi, dan Bab V Kesimpulan dan Saran. Berikut
penjelasan gambaran singkat bab-bab tersebut:
Bab I Pendahuluan. Bab ini berisi latar belakang yang menjadi alasan
mengapa penulis mengambil topik tugas akhir di bidang grafika komputer,
identifikasi masalah yang diperkirakan ada selama pembuatan aplikasi, batasan
masalah tugas akhir, tujuan penelitian, dan kegunaan hasil penelitian.
Bab II Transformasi Geometri pada Ruang 3 Dimensi. Bab II memuat teori-
teori tentang transformasi geometri pada ruang 3 dimensi, bagaimana melakukan
transformasi tersebut pada OpenGL, bagaimana menghubungkan OpenGL dengan
bahasa pemrograman Delphi, dan landasan teori bagaimana pengguna dapat
mentransformasi objek 3 dimensi dengan menggunakan antarmuka yang
disediakan aplikasi.
Bab III Perancangan Aplikasi Grafika Komputer untuk Transformasi
Geometri 3 Dimensi. Bab III berisi perancangan yang dilakukan sebelum
membuat aplikasi. Perancangan dilakukan dengan menggunakan pendekatan
berorientasi objek. Langkah-langkah yang dilakukan, yaitu membuat use case,
kartu indeks CRC, diageam kelas, model hubungan objek, model tingkah laku
objek, dan perancangan antarmuka.
Bab IV Implementasi dan Pengujian Aplikasi Grafika Komputer untuk
Transformasi Geometri 3 Dimensi. Pada bab ini, hasil penelitian dipaparkan
dalam bentuk penjelasan implementasi aplikasi yang dibuat. Pada bagian ini pula,
pengujian aplikasi dilakukan dengan menguji validasi hasil transformasi aplikasi
dengan hasil transformasi melalui perhitungan. Pengujian juga dilakukan dengan
membandingkan framerate transformasi aplikasi dan framerate transformasi
bawaan OpenGL.
Bab V Kesimpulan dan Saran. Bab V, bab yang terakhir, berisi kesimpulan-
kesimpulan penelitian dan saran-saran untuk bagi pengembangan penelitian
selanjutnya.
BAB II

TRANSFORMASI GEOMETRI PADA RUANG TIGA DIMENSI

Untuk membangun suatu aplikasi studio yang mendukung fungsi


transformasi 3 dimensi setidaknya dibutuhan 5 bagian penting. Bagian-bagian
tersebut, yaitu pemahaman teori transformasi 3 dimensi, transformasi 3 dimensi
menggunakan OpenGL, penggunaan OpenGL API pada bahasa pemrograman
Delphi, representasi objek 3 dimensi, dan interaksi pengguna dengan aplikasi.
Pada subbab-subbab selanjutnya akan dijelaskan mengenai bagian-bagian
tersebut.

2.1 Transformasi Geometri 3 Dimensi


Teori transformasi geometri 3 dimensi memegang peranan penting karena
bagian ini merupakan ilmu dasar yang akan diimplentasikan pada program
aplikasi. Sebelum melangkah lebih jauh, sangat penting untuk mengetahui arti
dari transformasi geometri. Menurut Hearn-Baker, transformasi geometri adalah
operasi yang diberikan pada gambaran geometri dari suatu objek untuk mengubah
posisinya, orientasinya, atau ukurannya[1]. Jadi setiap operasi yang dapat
mengubah posisi, orientasi, dan ukuran dari gambaran objek geometri dapat
disebut sebagai transformasi geoemetri. Pada tugas akhir ini hanya akan
membahas dan menggunakan transformasi translasi, rotasi, penskalaan, dan
shearing.
Translasi, rotasi, penskalaan, dan shearing memiliki persamaan, yaitu sam-
sama dapat memindahkan verteks-verteks (titik-titik) penyusun objek geometri.
Yang membedakan keempatnya adalah cara atau bagaimana memindahkan
verteks-vereteks tersebut. Ini ditandai dengan berbedanya persamaan yang
digunakan oleh tiap-tiap transformasi tersebut.
Pada tugas akhir ini digunakan system koordinat homogen. Sistem
koordinat homogen menggunakan empat ordinat untuk menyatakan titik-titiknya.
P = (xp, yp, zp, s)
Ordinat keempat menyatakan faktor skala. konversi ke sistem koordinat kartesian
dapat dilakukan dengan membagi ketiga ordinat yang lain dengan ordinat keempat
sehingga titik (xp, yp, zp, s) memiliki koordinat kartesian (xp/s, yp/s, zp/s).

5
6

Titik hasil transformasi dapat diperoleh melalui persamaan 2.1:


Q=P· M (2.1)
dengan :
Q = [xq, yq, zq, s] menyatakan matriks 1x4 yang berisi titik hasil
transformasi.
P = [xp, yp, zp, s] menyatakan matriks 1x4 yang berisi titik yang akan
ditransformasikan
M = Matriks transformasi berukuran 4x4 seperti pada persamaan 2.2.
m00 m01 m02 m03 
m m11 m12 m13 
M =  10 (2.2)
m20 m21 m22 m23 
 
 m30 m31 m32 m33 
Transformasi 3 dimensi terdiri dari beberapa fungsi transformasi, yaitu
translasi, rotasi, penskalaan, dan shearing. Transformasi-transformasi tersebut
akan dijelaskan satu per satu.

2.1.1. Translasi
Transformasi translasi merupakan transformasi yang berfungsi
memindahkan suatu objek dari posisi satu ke posisi lainnya melalui suatu garis
lurus[1]. Translasi memiliki matriks seperti pada persamaan 2.3.
1 0 0 0
0 1 0 0
T = (2.3)
0 0 1 0
 
t x t y tz 1

Berikut contoh penggunaanya.


P' = P ⋅ T (2.4)
M=
0t
T x

 1 0 0 0
 0 1 0 0
[x ' y ' z ' 1] = [x y z 1] ⋅ 
 0 0 1 0 (2.5)

 
t x t y t z 1 
[x ' [
y ' z ' 1] = x + t x y + t y z + tz 1]

Operasi invers dapat dilakukan dengan memberikan tanda negatif (-) pada tx,
ty, dan tz sehingga hasil perkalian matriks menjadi [x-tx y-ty z-tz 1].
7

2.1.2. Penskalaan
Transformasi penskalaan merupakan transformasi yang berfungsi mengubah
ukuran suatu objek[1]. Ukurannya dapat menjadi lebih kecil atau lebih besar.
Penskalaan memiliki matriks seperti pada persamaan 2.6.
sx 0 0 0
0 sy 0 0
S= (2.6)
0 0 sz 0
 
0 0 0 1
Berikut contoh penggunaanya.
P' = P ⋅ S (2.7)
s x 0 0 0
0 sy 0 0
[x ' y ' z ' 1] = [x y z 1] ⋅ 
0 0 sz 0 (2.8)
 
0 0 0 1
[x ' [
y ' z ' 1] = x ⋅ s x y ⋅ sy z ⋅ sz 1 ]
Operasi invers dapat dilakukan dengan mengubah sx, sy, dan sz menjadi 1/sx,
1/sy, 1/sz sehingga hasil perkalian matriks menjadi [x/sx y/sy z/sz 1].

2.1.3. Rotasi
Menurut Hearn-Baker, transformasi rotasi dilakukan dengan memindahkan
semua titik-titik dari suatu objek ke posisi yang baru dengan memutar titik-titik
tersebut dengan sudut dan sumbu putar yang ditentukan[1]. Rotasi memiliki
matriks seperti pada persamaan 2.9, 2.11, dan 2.13. Tiap sumbu memiliki matriks
rotasi yang bebeda.
1 0 0 0
0 Cos (θ ) Sin(θ ) 0
Rx (θ ) =  (2.9)
0 − Sin(θ ) Cos (θ ) 0
 
0 0 0 1

P ' = P ⋅ Rx (θ ) (2.10)

Cos (θ ) 0 − Sin(θ ) 0
 0 1 0 0
R y (θ ) =  (2.11)
 Sin(θ ) 0 Cos (θ ) 0
 
 0 0 0 1
8

P ' = P ⋅ R y (θ ) (2.12)

 Cos (θ ) Sin(θ ) 0 0
− Sin(θ ) Cos (θ ) 0 0
Rz (θ ) =  (2.13)
 0 0 1 0
 
 0 0 0 1

P' = P ⋅ Rz (θ ) (2.14)
Operasi invers dapat dilakukan dengan memberikan tanda negatif (-) pada θ.

2.1.4. Shearing
Shearing adalah transformasi yang mendistorsi bentuk dari suatu objek
seakan-akan objek tersebut tersusun atas lapisan-lapisan yang mengalami
kemiringan (slide) satu sama yang lain[1]. Shearing memiliki matriks seperti pada
persamaan 2.15 (sumbu X), 2.17 (sumbuY), dan 2.19 (sumbu Z).
1 Shxy Shxz 0
0 1 0 0
M xshear = (2.15)
0 0 1 0
 
0 − Shxy ⋅ X ref − Shxz ⋅ X ref 1

P' = P ⋅ M xshear (2.16)

 1 0 0 0
 Sh 1 Shyz 0
=
yx
M yshear (2.17)
 0 0 1 0
 
− Shyx ⋅ Yref 0 − Shyz ⋅ Yref 1

P' = P ⋅ M yshear (2.18)

 1 0 0 0
 0 1 0 0
M zshear = (2.19)
 Shzx Shzy 1 0
 
− Shzx ⋅ Z ref − Shzy ⋅ Z ref 0 1

P' = P ⋅ M zshear (2.20)


Sh menyatakan besar shearing yang akan dilakukan dan *ref menyatakan titik
referensi pada sumbu yang akan digunakan. Operasi invers dapat dilakukan
dengan memberikan tanda negatif (-) pada Sh.
9

2.1.5. Transformasi Berturut-turut


Transformasi berturut-turut atau transformasi komposit dapat dilakukan
dengan cara mengalikan matriks-matriks transformasi sesuai ururtan transformasi.
Misalnya suatu titik akan ditranslasi dan diskala dengan matriks T dam S, maka
matriks yang digunakan adalah matriks MK = T · S
P’ = P · MK
P’ = P · (T · S)
1 0 0 0  s x 0 0 0 
 
 0 1 0 0  0 sy 0 0 
P' = [x y z 1] ⋅   ⋅ 
0 0 1 0  0 0 sz 0  (2.21)
   
 t x ty tz 1  0 0 0 1  

P' = [x' y ' z ' 1]
Dengan P adalah titik awal dan P’ merupakan titik hasil transformasi.

2.1.6. Rotasi Menggunakan Sumbu yang Tidak Melewati Titik Origin


Langkah-langkah yang dilakukan agar benda dapat dirotasi menggunakan
sumbu yang tidak melewati titik origin adalah sebagai berikut:
1. Mentranslasikan objek sehingga sumbu putar melewati titik origin (gambar
2.1a).
2. Merotasi objek sehingga sumbu putar berimpit dengan salah satu sumbu
koordinat (gambar 2.1b).

3. Lakukan rotasi yang telah ditentukan pada sumbu koordinat yang ditentukan
pada no 2 (gambar 2.1c).
4. Lakukan rotasi invers agar objek kembali ke orientasi semula (gambar 2.1d).
5. Lakukan translasi invers agar objek kembali ke posisi semula (gambar 2.1e).

Y Y Y Y Y

X α X X α X X

β θ β
Z Z Z Z Z

(a) (b) (c) (d) (e)


Gambar 2.1 Rotasi Menggunakan Sumbu yang Tidak Melewati Titik Origin.
10

2.1.7. Penskalaan Menggunakan Sembarang Titik Pusat


Langkah-langkah yang dilakukan agar benda dapat diskalakan menggunakan
sembarang titik pusat (tx, ty, tz) adalah sebagai berikut:
1. Lakukan translasi sebesar T-1(tx, ty, tz). Langkah ini akan membuat titik (tx, ty,
tz) berimpit dengan titik (0, 0, 0).
2. Lakukan pensakalaan sebesar S(sx, sy, sz).
3. Lakukan translasi sebesar T(-tx, -ty, -tz). Langkah ini akan mengembalikan
benda ke lokasi semula.
4. Dengan demikian matriks transformasi yang diperlukan untuk melalukan
penskalaan menggunakan titik origin O = (0, 0, 0) sebagai titik pusat dapat
diperoleh melalui:
M K = T −1 ⋅ S ⋅ T
 1 0 0 0  s x 0 0 0  1 0 0 0
 0 0  0  0
1 0 sy 0 0  0 1 0
MK =  * * (2.22)
 0 0 1 0  0 0 sz 0  0 0 1 0
     
− t x − ty − tz 1  0 0 0 1 t x ty tz 1

 sx 0 0 0
 0 sy 0 0
MK =  (2.23)
 0 0 sz 0
 
(−t x ⋅ s x ) + t x ( −t y ⋅ s y ) + t y ( −t z ⋅ s z ) + t z 1

2.2 Transformasi 3 Dimensi pada OpenGL


OpenGL sendiri sudah menyediakan perintah-perintah untuk melakukan
transformasi. Perintah-perintah yang berhubungan dengan transformasi akan
dijelaskan secara singkat pada subbab ini.

Procedure glMatriksMode(m:GLenum);

Perintah di atas mengatur pemakaian matriks. Ada tiga macam matriks yang
dapat digunakan, yaitu: MODELVIEW, PROJECTION, dan TEXTURE. MODELVIEW
adalah matriks yang digunakan untuk melakukan transformasi. PROJECTION
adalah matriks yang digunakan untuk proyekdi, dan TEXTURE adalah mariks yang
digunakan untuk mengatur tekstur/tampilan permukaan.
11

glLoadIndentity;

Perintah di atas mengatur agar matriks yang digunakan diisi dengan matriks
identitas. Matriks indentitas adalah matriks yang elemen diagonal ke kanan bawah
berisi angka 1 dan elemen yang lain berisi 0.

Procedure glTranslated(x,y,z:GLdouble);
Procedure glTranslatef(x,y,z:GLfloat);
Procedure glTranslate(x,y,z:GLdouble);
Procedure glTranslate(x,y,z:GLfloat);

Perintah-perintah di atas menggunakan transformasi translasi matriks yang


sedang digunakan. Parameter x, y, z menyatakan besarnya translasi yang dilaluksn
pada sumbu x, y, dan z.

Procedure glRotated(angle,x,y,z:GLdouble);
Procedure glRotatef(angle,x,y,z:GLfloat);
Procedure glRotate(angle,x,y,z:GLdouble);
Procedure glRotate(angle,x,y,z:GLfloat);

Perintah-perintah di ats menggunakan rotasi untuk matriks yang sedang


digunakan. Parameter x, y, z menyatakan vektor yang digunakan sebagai sumbu
putar. Vektor sumbu dibentuk dari titik (0, 0, 0) ke (x, y, z). Apabila salah satu
dari parameter diisi dengan nilai 1 dan parameter yang lain diisi dengan 0 maka
perputaran terhadap sumbu sesuai dengan yang bernilai 1. Parameter angle
menatakan besar sudut rotasi yang dilakukan.

Procedure glScaled(x,y,z:PGLdouble);
Procedure glScalef(x,y,z:PGLfloat);
Procedure glScale(x,y,z:GLdouble);
Procedure glScale(x,y,z:GLfloat);

Perintah-perintah di atas menggunakan transformasi penskalaan pada


matriks yang sedang digunakan. Parameter x, y, dan z menyatakan besar
penskalaan.
Agar OpenGL dapat melakukan translasi maka perintah-perintah yang
12

digunakan disusun dalam urutan berikut:

glMatriksMode(GL_MODELVIEW);
glLoadIndentity; //jika diperlukan menggunakan matriks identitas
<perintah transformasi, glTranslate, glRotate, atau glScale>

Perintah glMatriksMode(GL_MODELVIEW) memberitahukan OpenGL agar


perintah-perintah transformasi berikutnya diterapkan pada matriks. Perintah-
perintah transformasi yang telah disediakan oleh OpenGL akan digunakan dalam
membangun aplikasi studio, tentunya digunakan bersama-sama dengan bahasa
pemrograman Delphi. Perintah-perintah transformasi OpenGL diharapkan dapat
mempercepat membangun aplikasi.

2.3 Penggunaan OpenGL pada Delphi


Di dalam sistem operasi Windows, OpenGL diimplementasikan ke dalam 2
buah berkas, yaitu opengl32.dll dan glut32,dll. Opengl32.dll merupakan pustaka
program yang menyediakan perintah-perintah utama dari OpenGL dan glut32.dll
menyediakan perintah-perintah tambahan (utility) dari OpenGL.
OpenGL dan Delphi perlu dihubungkan sehingga transformasi 3 dimensi
menggunakan OpenGL dapat dilakukan. Untuk menghubungkannya, yaitu dengan
menggunakan file opengl.dcu yang biasanya terdapat di direktori …\lib pada
direktori Delphi. Penggunaannya cukup dengan menambahkan klausa OpenGL
pada kode program di bagian uses.

uses
OpenGL, Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms, Dialogs;

OpenGL bukan merupakan bagian dari system operasi Windows sehingga


diperlukan memberitahu Windows bahwa program menggunakan API dari
OpenGL. Informasi yang perlu disampaikan, yaitu:
1. Format Pixel yang disampaikan melalui struktur data TPIXELFORMAT-
DESCRIPTOR. Format Pixel (pfd) memberikan informasi mengenai jumlah
warna dalam bit per pixel, versi OpenGL yang digunakan, kedalaman sumbu z,
tipe pixel, dan lain-lain.
13

2. Device Context yang merupakan perangkat yang akan digunakan oleh OpenGL
untuk menggambar. Device context yang disediakan oleh Windows dan
rendering context yang disediakan oleh OpenGL harus dihubungkan sehingga
apa yang digambar oleh OpenGL akan ditampilkan oleh Windows.

type
TForm1 = class(TForm)
private
{ Private declarations }
rc : HGLRC; //rendering context OpenGL
dc : HDC; //device context windows

Atribut pfd merupakan atribut yang digunakan untuk memyimpan informasi


pixel, sedangkan dc merupakan atribut untuk menyimpan device context yang
dibuat oleh Window dan atribut rc digunakan untuk menyimpan rendering
context yang dibuat oleh OpenGL. Antara device context yang dibuat melalui
windows (dc) dan rendering context yang dibuat melalui OpenGL (rc) nantinya
akan dihubungkan melalui wglMakeCurrent.

procedure TForm1.FormCreate(Sender: TObject);


var pfd : TPIXELFORMATDESCRIPTOR;
pf : Integer;
begin
dc:=GetDC(Form1.Handle);
pfd.nSize:=sizeof(pfd);
pfd.nVersion:=1;
pfd.dwFlags:=PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL
or PFD_DOUBLEBUFFER or 0;
pfd.iPixelType:=PFD_TYPE_RGBA;
pfd.cColorBits:=32;
pfd.cDepthBits:=32;
pf :=ChoosePixelFormat(dc, @pfd);
SetPixelFormat(dc, pf, @pfd);
rc :=wglCreateContext(dc);
wglMakeCurrent(dc,rc);
end;
14

Perintah dc:=GetDC(Form1.Handle) digunakan untuk menangkap device


context dari Handle yang diliki oleh Form1 dan hasilnya diberikan ke varaibel dc.
Perintah berikutnya mengisi struktur pfd dengan nilai yang diinginkan, dua
diantaranya, yaitu iPixelType yang menggunakan PFD_TYPE_RGBA untuk
mendukung warna 32 bit per pixel dan cDepthBits untuk kedalaman sumbu z
sebesar 32 bit. Setelah pfd selesai diisi maka isi pfd digunakan untuk memformat
rc dan indeks format pixel dari format yang dikembalikan melalui variabel pf.
Langkah selanjutnya adalah mengatur agar device context dc menggunakan
format tersebut. Rendering context dari OpenGL dibuat berdasarkan device
context dc. Antara rc dan dc dihubungkan satu sama lain menggunakan
wglMakeCurrent(dc,rc) yang menyatakan mulai saat itu OpenGL menggunakan
dc sebagai kanvas untuk menggambar.

2.4 Representasi Objek 3 Dimensi


Objek 3 dimensi disusun dengan menghubungkan sejumlah verteks (titik).
Struktur data untuk verteks 3 dimensi adalah sebagai berikut:
type
Ttitik3d = record
posX,posY,posZ:GLFloat;
end;
Garis-garis yang menghubungkan suatu kumpulan verteks-verteks disebut
sebagai wireframe atau kerangka dan benda yang dibentuk oleh dari kumpulan
titik-titik dan garis-garis tersebut disebut sebagai Mesh.
Pada gambar 2.2 suatu objek (mesh) kubus terbentuk dari 9 buah verteks.
Verteks 0 digunakan sebagai titik pusat sedangkan verteks-verteks dari 1 sampai 8
dihubungkan dengan garis-garis membentuk kerangka kubus.

8 7

5 6

4 3

1 2

Gambar 2.2 Objek geometri kubus.


15

Karena suatu objek terdiri dari satu verteks atau lebih maka perlu membuat
struktur data untuk menampung informasi koordinat verteks-verteks penyusunnya.
Struktur data yang digunakan, yaitu array dengan tipe Ttitik3d yang telah
didefiniskan di atas.
verteks:array of Ttitik3d;
Jika diimplementasikan pada objek kubus di atas maka panjang arraynya adalah
sembilan.
verteks:array[0..8] of Ttitik3d;
Kubus pada gambar 2.2 dapat disusun berdasrkan data yang ad pada tabel 2.1.

Tabel 2.1 Verteks penyusun kubus.


Verteks X Y Z
0 0 0 0
1 -1 -1 1
2 1 -1 1
3 1 -1 -1
4 -1 -1 -1
5 -1 1 1
6 1 1 1
7 1 1 -1
8 -1 1 -1

2.5 Interaksi Pengguna dengan Aplikasi


Antarmuka diperlukan agar pengguna dapat berinteraksi dengan aplikasi.
Interaksi yang digunakan pada aplikasi dibagi menjadi 3, yaitu interaksi
menggunakan button, interaksi menggunakan keyboard, dan interaksi
menggunakan mouse.
1. Interaksi menggunakan button
Interaksi menggunakan button dilakukan dengan memakai event handling
bawaan Delphi seperti onClick, onChange, dan lain-lain untuk operasi-operasi
tertentu.
2. Interaksi menggunakan keyboard
Interaksi menggunakan keyboard juga dilakukan dengan memakai event
handling bawaan Delphi. Salah satunya event onKeyPress. Event pada
keyboard digunakan sebagai shortcut untuk melakukan operasi tertentu,
misalnya mengatifkan mode transformasi rotasi dengan menekan tombol ‘r’.
3. Interaksi menggunakan mouse
Interaksi menggunakan mouse tetap menggunakan event handling bawaan
16

Delphi tetapi mengkombinasikannya dengan perintah bawaan OpenGL, yaitu


gluUnProject. Perintah ini digunakan untuk mengubah koordinat 2 dimensi
pointer mouse pada layar window dan mengembalikan nilai berupa koordinat 3
dimensi dari gambar OpenGL. Dalam implementasinya, mouse digunakan
untuk mentransformasi objek 3 dimensi dengan cara mengeser mouse tersebut.
Perbedaan kordinat 2 dimensi setelah pergesesan menjadi acuan untuk
transformasi 3 dimensi pada koordinat 3 dimensi.
BAB III

PERANCANGAN
APLIKASI GRAFIKA KOMPUTER UNTUK
TRANSFORMASI GEOMETRI OBJEK 3 DIMENSI

Perancangan aplikasi grafika komputer untuk transformasi objek 3 dimensi


menggunakan pendekatan berorientasi objek. Langkah-langkah perancangan yang
dilakukan mengikuti model yang diutarakan oleh Pressman[6], yaitu:
1. Use case,
2. Kartu Index CRC,
3. Diagram Kelas,
4. Model Hubungan Objek (Object Relationship), dan
5. Model Tingkah Laku Objek (Object Behaviour).

3.1 Use case


Use case merupakan rangkaian skenario yang mengidentifikasikan urutan
pemakaian aplikasi yang akan dibangun[6]. Skenario penggunaan aplikasi grafika
komputer untuk transformasi objek 3 dimensi adalah sebagai berikut:
1. Pengguna membuat objek geometri. Pengguna dapat memilih objek geometri
yang akan dibuat, yaitu kubus, piramid, silinder, meja, dan kursi.
2. Pengguna melakukan transformasi terhadap objek geometri. Objek yang akan
ditransformasi dipilih terlebih dahulu kemudian pengguna menentukan
transformasi apa yang akan dilakukan. Transformasi yang dapat dilakukan,
meliputi translasi, penskalaan, rotasi, dan shearing. Tiap-tiap transformasi
memiliki parameter-parameter tersendiri dan pengguna dapat menentukan
nilai parameter-parameter tersebut. Misalnya: Rotasi pada suatu kubus.
Pengguna dapat menentukan besar sudut rotasi dan sumbu rotasi.
3. Pengguna menghapus objek. Pengguna memilih objek yang telah dibuat
kemudian menghapusnya.
Skenario di atas kemudian diubah ke dalam bentuk diagram use case yang
bentuknya seperti gambar 3.1.

17
18

Buat Objek Translasi

Penskalaan

Transformasi
Pengguna

Rotasi

Hapus Objek Shearing

Gambar 3.1 Diagram use case aplikasi grafika komputer untuk


transformasi objek 3 dimensi.

Sistem hanya memiliki satu aktor, yaitu pengguna. Pengguna dapat


melakukan tiga use case, yaitu membuat objek, melakukan transformasi pada
objek, dan menghapus objek.
Pada diagram terlihat bahwa use case transformasi merupakan generalisasi
dari 4 macam use case, yaitu translasi, penskalaan, rotasi, dan shearing. Artinya,
transformasi masih dapat lebih spesifikkan, yaitu translasi, penskalaan, rotasi, atau
pun shearing.

3.2 Kartu Index CRC (Class-Responsibility-Collaborator)


Setelah melakukan analisis use case, selanjutnya adalah membuat kartu
index CRC. Pemodelan CRC memberikan cara sederhana untuk mengidentifikasi
dan mengumpulkan kelas-kelas yang relevan[6] yang nantinya akan digunakan
untuk aplikasi grafika komputer untuk transformasi objek 3 dimensi.
Dari analisis use case, dapat diidentifikasi 2 kelas utama, yaitu kelas objek
geometri dan kelas transfomasi. Kelas objek geometri diturunkan menjadi
subkelas-subkelas menurut kekhasan objek geometri itu sendiri, misalnya kelas
kubus, kelas piramid, kelas silinder, kelas meja, dan kelas kursi. Kelas
transformasi memiliki operasi, yaitu translasi, rotasi, penskalaan, dan shearing.
Tabel 3.1 menunjukkan kartu index CRC untuk kelas-kelas objek geometri dan
turunannya.
19

Tabel 3.1 Kartu index CRC kelas objek geometri.


Kelas: Objek Geometri
Tanggung Jawab: Kolaborator:
Atribut:
• nama • -
• index
• jenis
• pusat
• jumTitik
• titik
• sudut
• Aktif
Operasi:
• Gambar

Tabel 3.2 Kartu index CRC kelas kubus.


Kelas: Kubus
Tanggung Jawab: Kolaborator:
Atribut:
• Sisi • -
Operasi:
• Create
• Gambar

Tabel 3.3 Kartu index CRC kelas piramid.


Kelas: Piramid
Tanggung Jawab: Kolaborator:
Atribut:
• Tinggi • -
• Sisi
Operasi:
• Gambar
• Create

Tabel 3.4 Kartu index CRC kelas silinder.


Kelas: Silinder
Tanggung Jawab: Kolaborator:
Atribut:
• Radius • -
• Tinggi
Operasi:
• Gambar
• Create
20

Tabel 3.5 Kartu index CRC kelas meja.


Kelas: Meja
Tanggung Jawab: Kolaborator:
Atribut:
• - • -
Operasi:
• Gambar
• Create

Tabel 3.6 Kartu index CRC kelas kursi.


Kelas: kursi
Tanggung Jawab: Kolaborator:
Atribut:
• - • -
Operasi:
• Gambar
• Create

Kelas objek geometri dapat diturunkan menjadi subkelas-subkelas objek


geometri seperti kelas kubus, kelas piramid, kelas silinder, kelas meja, dan kelas
kursi. Karena merupakan turunan dari kelas objek geometri, maka kelas-kelas
tersebut memiliki atribut yang sama dengan kelas objek geometri. Selain itu, tiap-
tiap kelas memiliki atribut tersendiri yang membedakannya dengan kelas lain
yang berasal dari kelas induk yang sama, misalnya objek kubus memiliki atribut
ukuran sisi sedangkan piramid memiliki atribut tinggi dan sisi untuk alasnya.
Kelas transformasi memiliki operasi-operasi seperti yang ditunjukkan tabel
3.2, yaitu operasi translasi, rotasi, penskalaan, shearing, dan lain-lain.

Tabel 3.7 Kartu index CRC Transformasi.


Kelas: Transformasi
Tanggung Jawab: Kolaborator:
Atribut:
• Matriks • Objek Geometri
Operasi:
• PerkalianMatriks
• MatriksIdentitas
• Translasi
• Penskalaan
• Rotasi
• Shearing
• Transform
• nolkanTransformasi
• ambilPos3d
21

3.3 Diagram Kelas


Diagram kelas (gambar 3.2) dibuat dari kartu index CRC pada subbab 3.2.
Diagram kelas memberikan gambaran tentang kelas-kelas apa saja yang perlu
dibuat untuk membangun aplikasi, lengkap dengan atribut dan operasinya. Pada
gambar 3.2, kelas geometri memiliki 5 kelas turunan, yaitu kubus, silinder,
piramid, meja, dan kursi. Kelas transformasi tidak memiliki turunan tetapi
memiliki operasi-operasi untuk melakukan transformasi 3 dimensi.

Transformasi
Geometri Matriks
nama : String
perkalianMatriks()
index : Integer
MatriksIdentitas()
jenis : String Mentransformasi
Translasi()
posisi : Single
Penskalaan()
sudut : Single 1..* 1 Rotasi()
pusat : Single Shearing()
Transform()
gambar() nolkanTransformasi()
ambilPos3d()

Kubus Piramid Meja Kursi


Silinder
sisi : Single tinggi : Single
radius : Single
tinggi : Single sisi : Single gambar() gambar()
gambar() create() create()
create() gambar()
gambar()
create()

Gambar 3.2 Diagram kelas aplikasi grafika komputer untuk


transformasi objek 3 dimensi.

3.4 Model Hubungan Objek


Model hubungan objek (object relationship model) dapat digambarkan
dengan menggunakan diagram runtun (sequence diagram). Dengan diagram
runtun, interaksi antarobjek dapar diperlihatkan. Pada gambar 3.3 terdapat 3
skenario, yaitu menciptakan objek geometri, mentransformasi objek geometri, dan
menghapus objek geometri.
Pengguna membuat objek dengan objek dan mendefinisikan nilai atribut-
atributnya pada antarmuka. Setelah itu, objek geometri dibuat dan digambarkan
pada layar sehingga dapat dilihat oleh pengguna.
22

Antarmuka : Transformasi : Geometri Layar


: Pengguna

Memilih objek
yang akan dibuat
dan nilai atributnya
gambar objek
Membuat objek geometri
pada layar
Menampilkan objek geometri

Memilih jenis
transformasi dan
nilainya Memberi nilai sesuai input Gambar
Mentransformasi objek pada
objek geometri layar

Menampilkan
objek geometri
hasil
transformasi

Memilih
objek yang
akan Menghapus objek geometri Hapus
dihapus
objek pada
layar
Meampilkan hasil menghapus objek geometri

Gambar 3.3 Diagram runtun aplikasi grafika komputer untuk


transformasi objek 3 dimensi.

Untuk melakukan transformasi pada objek geometri, pengguna


mendefinisikan transformasi yang akan dilakukan beserta nilai-nilainya pada
antarmuka. Antarmuka kemudian memberi nilai-nilai tersebut ke objek
transformasi. Objek transformasi kemudian menerapkan transfomasi pada objek
geometri. Akibatnya, objek berubah pada bentuk, posisi, atau sudut. Objek
digambar ulang pada layar dan hasilnya ditampilkan pada pengguna.
Pengguna dapat menghapus objek dengan terlebih dahulu memilih objek
tersebut antarmuka. Antarmuka kemudian menghapus objek geometri tersebut.
Hasilnya, objek geometri akan terhapus pada layar. Layar kemudian ditampilkan
pada pengguna sehingga pengguna mengetahui bahwa objek telah terhapus.
23

3.5 Model Tingkah Laku Objek


Gambar 3.4 merupakan diagram statechart yang menggambarkan perilaku
dua objek, yaitu objek transformasi (a) dan objek geometri (b). Model tingkah
laku objek menunjukkan bagaimana sistem akan merespon kejadian atau stimulus
eksternal.
Mulai
Mentransformasi
Membuat objek geometri
objek
transformasi

Objek transformasi Menunggu


tercipta perintah transformasi selanjutnya

Menutup
Aplikasi

Selesai
Objek transformasi
terhapus

(a)

Mulai Posisi, sudut, dan


bentuk yang baru

Membuat objek geometri Mentransformasi


objek geometri

Objek geometri
Menunggu transformasi
tercipta
selanjutnya

Menghapus
objek geometri

Selesai Objek geometri


terhapus

(b)
Gambar 3.4 Diagram statechart aplikasi grafika komputer
untuk transformasi objek 3 dimensi: (a) diagram statechart objek transformasi
(b) diagram statechart objek geometri.

Ketika aplikasi dijalankan, operasi membuat objek transformasi


mengakibatkan objek transformasi tercipta. Objek transformasi kemudian
menunggu perintah transformasi untuk mentransformasi objek geometri. Pada saat
aplikasi ditutup, maka objek transformasi akan terhapus.
Operasi buat objek geometri akan membuat objek geometri tercipta. Operasi
transformasi (rotasi, translasi, penskalaan, dan shearing) akan mentransformasi
objek tersebut sehingga nilai atribut-atribut seperti posisi dan ukuran akan
berubah. Setelah operasi transformasi dilakukan, objek akan menunggu
24

transformasi selanjutnya. Objek akan terhapus jika dilakukan operasi hapus objek
pada objek tersebut.

3.6 Desain Antarmuka


Aplikasi grafika komputer untuk transformasi objek 3 dimensi terdiri dari
satu form utama. Form utama terdiri dari beberapa bagian, yaitu menubar,
toolbar, tab objek, layar, dan statusbar. Menubar berisi menu-menu untuk
melakukan operasi-operasi pada aplikasi. Toolbar berisi tombol-tombol untuk
melakukan operasi-operasi pada aplikasi. Layar digunakan untuk menampilkan
gambar 3 dimensi. Tab objek digunakan untuk membuat objek geometri yang
dikehendaki. Statusbar digunakan untuk melihat status-status seperti posisi
mouse, mode transformasi yang sedang aktif, dan sumbu koordinat yang sedang
aktif. Perancangan antarmuka aplikasi dapat dilihat pada gambar 3.5.

Menu Bar
Tool Bar
Tab Layar
Objek

Status Bar
Gambar 3.5 Desain antarmuka aplikasi grafika komputer
untuk transformasi objek 3 dimensi.
BAB IV

IMPLEMENTASI DAN PENGUJIAN APLIKASI GRAFIKA KOMPUTER

UNTUK TRANSFORMASI 3 DIMENSI

Bab IV membahas mengenai implementasi dan pengujian pada aplikasi


grafika komputer untuk transformasi 3 dimensi. Implementasi adalah bagaimana
mewujudnyatakan hasil dari perancangan sehingga menghasilkan suatu aplikasi
yang dapat bekerja dengan baik. Setelah itu, pengujian dilakukan untuk
mengetahui apakah aplikasi sudah dapat bekerja sebagaimana mestinya atau
belum. Jika hasilnya belum maka aplikasi masih perlu disempurnakan.

4.1. Implementasi
Implementasi aplikasi grafika komputer untuk transformasi 3 dimensi
memiliki 4 bagian penting, yaitu implementasi tampilan aplikasi, implementasi
objek geometri, implementasi vektor, dan implementasi transformasi 3 dimensi.

4.1.1. Implementasi Tampilan Aplikasi

Gambar 4.1 Tampilan aplikasi grafika komputer untuk transformasi geometri.

Gambar 4.1 merupakan tampilan aplikasi grafika komputer untuk

25
26

transformasi 3 dimensi yang terdiri dari satu form utama. Form utama terdiri dari
beberapa bagian, yaitu toolbar, menu, tab objek, layar, log, dan statusbar.

Gambar 4.2 Toolbar dan menu aplikasi.

Gambar 4.2 menujukkan tampilan toolbar dan menu. Toolbar terdiri dari 10
tombol dan 1 combo box. Button transalasi untuk melakukan translasi, tombol
penskalaan untuk transformasi penskalaan, tombol rotasi untuk rotasi, tombol
shearing untuk operasi shearing, tombol reset untuk kembali ke mode awal,
button zoom untuk memperbesar atau memperkecil tampilan pada layar, tombol
rotasi kamera untuk memutar kamera dengan sumbu pada titik fokus kamera,
tombol rotasi fokus untuk memutar titik fokus kamera, tombol geser kamera
digunakan untuk menggeser layar, dan tombol fokus ke objek digunakan untuk
memindahkan fokus kamera ke objek terpilih, dan tombol reset kamera untuk
mengembalikan kamera ke posisi awal. Combo box digunakan untuk memilih
sumbu atau arah vektor.

Gambar 4.3 Tampilan tab-tab untuk objek kubus, kursi, meja, piramida, silinder,
kamera, dan OBJ Loader serta Memo untuk menampilkan log.
27

Gambar 4.3 adalah tampilan tab-tab objek. Tab piramida unuk membuat
piramida, tab kubus untuk membuat kubus, tab silinder untuk membuat silinder,
tab meja untuk membuat meja, tab kursi untuk membuat kursi, dan tab kamera
untuk memindah posisi kamera atau titik fokusnya, dan tab OBJ Loader untuk
memuat berkas OBJ.

Gambar 4.4 Status Bar.

Gambar 4.4 memperlihatkan statusbar. Statusbar berfungsi untuk


menampilkan posisi mouse pada koordinat world, posisi mouse pada layar, mode
transformasi yang sedang aktif, arah vektor/sumbu putar, dan framerate.

Gambar 4.5 Tampilan popup menu klik kanan.

Gambar 4.5 memperlihatkan popup menu aplikasi. Menu terdiri dari


beberapa pilihan. Pilihan translasi akan menampilkan form translasi. Pilihan rotasi
akan menampilkan form rotasi. Pilihan penskalaan akan menampilkan form
penskalaan. Pilihan shearing akan menampilkan form shearing. Pilihan hapus
akan menghapus objek terpilih. Form-form tersebut dapat dilihat pada gambar 4.6.

Gambar 4.6 Form untuk transformasi translasi, penskalaan, rotasi dan shearing.
28

4.1.2. Implementasi Objek Geometri


a. Piramida
Geometri piramida (gambar 4.7) terdiri dari 7 titik dengan titik 2 dan 6 berada
pada posisi yang sama.
1

5 4

2 dan 6 3

Gambar 4.7 Objek geometri piramida.

Inisialisasi nilai koordinat titik-titik tersebut dilakukan ketika objek piramida


diciptakan.Ini dilakukan pada konstruktor create.
constructor Tpiramid.create(pTinggi,pSisi:GLfloat;
titikPusat:Ttitik3d);
Konstruktor ini membutuhkan nilai tinggi, sisi, dan titik pusat yang akan
dilewatkan pada parameter pTinggi, pSisi, dan titikPusat. Dari ketiga nilai
tersebut, konstruktor akan menghitung nilai-nilai untuk setiap titik. Detil
prosesnya dapat dilihat pada source code di lampiran A.
Setelah setiap titik memiliki nilai koordinat, piramida digambar
menggunakan prosedur Gambar.
procedure TPiramid.Gambar;
Pada prosedur gambar, bagian atas piramida digambar dahulu kemudian
bagian alasnya. Bagian atas piramida digambar dengan perintah berikut:
glBegin(GL_TRIANGLE_FAN);
for i:=1 to 6 do
glVertex3f(titik[i].posX,titik[i].posY,titik[i].posZ);
glEnd;
Bagian alas piramida digambar dengan perintah berikut:
glBegin(GL_QUADS);
for i:=2 to 5 do
glVertex3f(titik[i].posX,titik[i].posY,titik[i].posZ);
glEnd;
29

b. Kubus
Geometri kubus (gambar 4.8) terdiri dari 9 titik. Inisialisasi nilai koordinat titik-
titik tersebut dilakukan ketika objek kubus diciptakan.

8 7

5 6

4 3

1 2

Gambar 4.8 Objek geometri kubus.

Ini dilakukan pada konstruktor create.


constructor Tkubus.create(pSisi:GLFloat;
titikPusat:Ttitik3d);
Konstruktor ini membutuhkan nilai tinggi, sisi, dan titik pusat yang akan
dilewatkan pada parameter pSisi dan titikPusat. Dari kedua nilai tersebut,
konstruktor akan menghitung nilai-nilai untuk setiap titik. Detil prosesnya dapat
dilihat pada source code di lampiran A.
Setelah setiap titik memiliki nilai koordinat, piramida digambar
menggunakan prosedur Gambar.
procedure TKubus.Gambar;
Pada prosedur gambar, bagian depan, belakang, kiri, kanan, atas, dan bawah
kubus dibuat berurutan. Bagian depan kubus digambar dengan perintah berikut:
glBegin(GL_QUADS);
glVertex3f(titik[1].posX,titik[1].posY,titik[1].posZ);
glVertex3f(titik[2].posX,titik[2].posY,titik[2].posZ);
glVertex3f(titik[6].posX,titik[6].posY,titik[6].posZ);
glVertex3f(titik[5].posX,titik[5].posY,titik[5].posZ);
Bagian belakang kubus digambar dengan perintah berikut:
glVertex3f(titik[4].posX,titik[4].posY,titik[4].posZ);
glVertex3f(titik[3].posX,titik[3].posY,titik[3].posZ);
glVertex3f(titik[7].posX,titik[7].posY,titik[7].posZ);
glVertex3f(titik[8].posX,titik[8].posY,titik[8].posZ);
Bagian kiri kubus digambar dengan perintah berikut:
30

glVertex3f(titik[4].posX,titik[4].posY,titik[4].posZ);
glVertex3f(titik[1].posX,titik[1].posY,titik[1].posZ);
glVertex3f(titik[5].posX,titik[5].posY,titik[5].posZ);
glVertex3f(titik[8].posX,titik[8].posY,titik[8].posZ);
Bagian kanan kubus digambar dengan perintah berikut:
glVertex3f(titik[2].posX,titik[2].posY,titik[2].posZ);
glVertex3f(titik[3].posX,titik[3].posY,titik[3].posZ);
glVertex3f(titik[7].posX,titik[7].posY,titik[7].posZ);
glVertex3f(titik[6].posX,titik[6].posY,titik[6].posZ);
Bagian atas kubus digambar dengan perintah berikut:
glVertex3f(titik[5].posX,titik[5].posY,titik[5].posZ);
glVertex3f(titik[6].posX,titik[6].posY,titik[6].posZ);
glVertex3f(titik[7].posX,titik[7].posY,titik[7].posZ);
glVertex3f(titik[8].posX,titik[8].posY,titik[8].posZ);
Bagian bawah kubus digambar dengan perintah berikut:
glVertex3f(titik[1].posX,titik[1].posY,titik[1].posZ);
glVertex3f(titik[2].posX,titik[2].posY,titik[2].posZ);
glVertex3f(titik[3].posX,titik[3].posY,titik[3].posZ);
glVertex3f(titik[4].posX,titik[4].posY,titik[4].posZ);
glEnd;

c. Silinder
Geometri silinder (gambar 4.9) terdiri dari 33 titik. Inisialisasi nilai koordinat
titik-titik tersebut dilakukan ketika objek silinder diciptakan.
18

17 24

18
19

12

1
8
2
3

Gambar 4.9 Objek geometri silinder.

Ini dilakukan pada konstruktor create.


constructor Tsilinder.Create(pRadius,pTinggi:GLfloat;
titikPusat:Ttitik3d);
31

Konstruktor ini membutuhkan nilai tinggi, sisi, dan titik pusat yang akan
dilewatkan pada parameter pTinggi, pRadius, dan titikPusat. Dari ketiga nilai
tersebut, konstruktor akan menghitung nilai-nilai untuk setiap titik. Detil
prosesnya dapat dilihat pada source code di lampiran A.
Setelah setiap titik memiliki nilai koordinat, silinder digambar
menggunakan prosedur Gambar.
procedure TSilinder.Gambar;
Pada prosedur gambar, bagian atas, alas, dan badan silnder dibuat
berurutan. Bagian tutup silinder digambar dengan perintah berikut:
glBegin(GL_POLYGON);
for i:=1 to 16 do
begin
glVertex3f(titik[i].posX,titik[i].posY,titik[i].posZ);
end;
glEnd;
Bagian alas silinder digambar dengan perintah berikut:
glBegin(GL_POLYGON);
for i:=17 to 32 do
begin
glVertex3f(titik[i].posX,titik[i].posY,titik[i].posZ);
end;
glEnd;
Bagian badan silinder digambar dengan perintah berikut:
i:=1;
glBegin(GL_QUAD_STRIP);
while i<=16 do
begin
glVertex3f(titik[i].posX,titik[i].posY,titik[i].posZ);
glVertex3f(titik[i+16].posX,titik[i+16].posY,
titik[i+16].posZ);
i:=i+1;
end;
glVertex3f(titik[32].posX,titik[32].posY,titik[32].posZ);
glVertex3f(titik[1].posX,titik[1].posY,titik[1].posZ);
glEnd;
32

d. Daftar Geometri
Objek-objek geometri yang dibuat perlu ditampung sehingga objek-objek
dapat dikelola lebih mudah. Misalnya mentranfomasi hanya objek yang aktif
terpilih, menghapus objek-objek tertentu, dan sebagainya. Objek-objek tersebut
disimpan pada daftar geometri yang berwujud kelas TdaftarGeometri. Objek-
objek tersebut disimpan varaibel f yang bertipe Tlist. Tlist merupakan kelas linked
list bawaan OpenGL.
constructor TDaftarGeometri.Create(Owner:Tcomponent);
begin
f:=TList.Create;
end;
Constructor digunakan untuk inisialisasi pada saat objek dari kelas
TdaftarGeometri dibuat. Pada saat contructor dipanggil, objek f dibuat dari kelas
Tlist.
destructor TDaftarGeometri.Destroy;
begin
f.Free;
end;
Destructor digunakan untuk menghapus objek dari kelas TdaftarGeometri.
Pada saat destructor dipanggil, variabel f akan dikosongkan. Dengan demikian
semua informasi objek yan disipan pada f akan terhapus.
procedure TDaftarGeometri.TambahGeometri(var O:TGeometri);
var item:TGeometri;i:integer;
begin
i:=f.Add(O);
FormUtama.sMemo1.Lines.add('Index Objek: '+IntToStr(i));
item:=f.Items[i];
item.index:=i;
f.Items[i]:=item;
end;
Prosedur TambahGeometri digunakan untuk menambahkan objek yang
dibuat ke f yang merupakan objek dari kelas Tlist. Pertama-tama, objek geometri
O disimpan ke f dengan perintah f.add(O). Perintah f.add(O) akan mengembalikan
nilai integer yang merupakan nilai index O pada f. Kedua, Index objek tersebut
ditampilkan pada bagian log, yaitu komponen sMemo1. Ketiga, variabel item
yang bertipe Tgeometri digunakan untuk menyimpan sementara isi dari f.items[i]
33

yang berisi objek dari kelas Tgeometri yang baru dibuat. Keempat, atribut index
dari item kemudian diisi dengan nilai i. Kelima, setelah atribut index terisi, nilai
item kemudian diberikan kembali ke f.items[i].
procedure TDaftarGeometri.Gambar;
var index:integer;
item:Tgeometri;
begin
for index:=0 to f.Count-1 do
begin
item:=f.Items[index];
glLoadName(item.index+100);
item.Gambar;
glEnd();
end;
end;
Prosedur Gambar digunakan untuk menggambarkan selurug objek geometri
yang terdapat pada daftar geometri. Setiap objek yang akan digambarkan diberi
nama dengan perintah glLoadName(item.index+100). Nama yang diberikan
akan digunakan pada saat objek tersebut diklik pada layar. Jika nama yang
dihasilkan ketika mengklik objek sama dengan nilai index objek dikurangi 100,
maka objek akan menjadi aktif.

4.1.3. Implementasi Vektor


Transformasi membutuhkan operasi vektor. Operasi vektor yang digunakan
pada aplikasi ini, yaitu:
1.) Mengubah koordinat 3 dimensi menjadi vektor 3 dimensi. Operasi ini
dinyatakan dalam bentuk fungsi buatVektor.
function BuatVektor(x,y,z:real):Ttitik3d;
var va:Ttitik3d;
begin
va.posX:=x; va.posY:=y; va.posZ:=z;
result:=va;
end;
2.) Menghitung panjang vektor. Operasi ini dinyatakan dalam bentuk fungsi
PanjangVektor.
function PanjangVektor(va:Ttitik3d):real;
begin
34

Result:=abs(sqrt(va.posx*va.posx+va.posy*va.posy+
va.posz*va.posz));
end;
3.) Normalisasi vektor. Operasi ini dinyatakan dalam bentuk fungsi
Normalisasi.
function Normalisasi(va:Ttitik3d):Ttitik3d;
var l:real; v:Ttitik3d;
begin
l:=PanjangVektor(va);
if l=0 then exit
else
begin
v.posx:=va.posx/l;
v.posy:=va.posy/l;
v.posz:=va.posz/l;
result:=v;
end;
end;
4.) Operasi dot product. Operasi ini dinyatakan dalam bentuk fungsi
DotProduct.
function DotProduct(va,vb:Ttitik3d):real;
var s:real;
begin
s:=va.posx*vb.posx+va.posy*vb.posy+va.posz*vb.posz;
result:=s;
end;
5.) Operasi cross product. Operasi ini dinyatakan dalam bentuk fungsi
CrossProduct.
function CrossProduct(va,vb:Ttitik3d):Ttitik3d;
var vs:Ttitik3d;
begin
vs.posx:=(va.posy*vb.posz)-(va.posz*vb.posy);
vs.posy:=(va.posz*vb.posx)-(va.posx*vb.posz);
vs.posz:=(va.posx*vb.posy)-(va.posy*vb.posx);
result:=vs;
end;
35

4.1.4. Implementasi Transformasi


Dalam mengimplementasikan transformasi diperlukan beberapa operasi
seperti perkalian matriks, mengidentitaskan matriks, translasi, penskalaan, rotasi,
dan shearing. Operasi-operasi tersebut dibuat dalam bentuk prosedur-prosedur
seperti berikut.

a. Perkalian Matriks
Perkalian matriks dibutukan untuk melakukan transformasi geometri.
Misalnya mengalikan matriks translasi dengan matriks penskalaan untuk
transformasi berturut-turut. Operasi perkalian matriks dinyatakan dalam bentuk
prosedur PerkalianMatriks.
procedure TTransformasi.PerkalianMatriks(Matriks1,Matriks2:
Matriks4x4;var Matriks3:Matriks4x4);
var
baris,kolom:byte;
matriksTemp:Matriks4x4;
begin
for baris:=0 to 3 do
begin
for kolom:=0 to 3 do
begin
matriksTemp[baris,kolom]:=Matriks1[baris,0]*Matriks2
[0,kolom]+
Matriks1[baris,1]*Matriks2[1,kolom]+
Matriks1[baris,2]*Matriks2[2,kolom]+
Matriks1[baris,3]*Matriks2[3,kolom];
end;
end;
for baris:=0 to 3 do
for kolom:=0 to 3 do
Matriks3[baris,kolom]:=matriksTemp[baris,kolom];
end;

b. Mantriks Identitas
Matriks identitas digunakan untuk menolkan suatu matriks transformasi.
Operasi MatriksIdentitas dinyatakan dalam bentuk prosedur MatriksIdentitas.
procedure TTransformasi.MatriksIdentitas(var m:Matriks4x4);
36

begin
m[0,0]:=1;m[0,1]:=0;m[0,2]:=0;m[0,3]:=0;
m[1,0]:=0;m[1,1]:=1;m[1,2]:=0;m[1,3]:=0;
m[2,0]:=0;m[2,1]:=0;m[2,2]:=1;m[2,3]:=0;
m[3,0]:=0;m[3,1]:=0;m[3,2]:=0;m[3,3]:=1;
end;

c. Translasi
Persamaan tranasformasi translasi yang terdapat pada persamaan 2.3 dan 2.4
dibuat ke dalam bentuk prosedur translasi di bawah ini. Prosedur ini digunakan
untuk mentranslasikan suatu titik sebesar parameter x,y, dan z-nya.
procedure TTransformasi.Translasi(x,y,z:real);
var matriksTranslasi:Matriks4x4;
begin
MatriksIdentitas(MatriksTranslasi);
MAtriksTranslasi[3,0]:=x;
MAtriksTranslasi[3,1]:=y;
MAtriksTranslasi[3,2]:=z;
PerkalianMatriks(MAtriks,MAtriksTranslasi,MAtriks);
end;

d. Penskalaan
Persamaan transformasi penskalaan yang terdapat pada persamaan 2.5 dan
2.6 dibuat ke dalam bentuk prosedur penskalaan di bawah ini. Prosedur ini
digunakan untuk menskalakan suatu titik sebesar parameter sx, sy, dan sz dengan
titik acuan xc, xy, dan xz.
procedure TTransformasi.Penskalaan(sx,sy,sz,xc,yc,zc:real);
var matriksPenskalaan:Matriks4x4;
begin
MatriksIdentitas(matriksPenskalaan);
Translasi(-xc,-yc,-zc);
matriksPenskalaan[0,0]:=sx;
matriksPenskalaan[1,1]:=sy;
matriksPenskalaan[2,2]:=sz;
PerkalianMatriks(Matriks,matriksPenskalaan,Matriks);
Translasi(xc,yc,zc);
end;
37

e. Rotasi
Persamaan transformasi rotasi yang terdapat pada persamaan 2.6, 2.7,
dan 2.8 serta pemahaman tentang subbab 2.1.6 maka dapat dibuat prosedur
rotasi di bawah ini. Prosedur ini digunakan untuk merotasikan suatu titik sebesar
parameter sudut dengan sumbu xr, yr, dan zr.
procedure TTransformasi.Rotasi(sudut:real;xr,yr,zr:real);
var
alpha,betha,radian:real;
ryb,rza,ryb_1,rza_1,ry:Matriks4x4;
u,u1,u2,s:Ttitik3d;
begin
MatriksIdentitas(ryb);
MatriksIdentitas(rza);
MatriksIdentitas(ry);
MatriksIdentitas(ryb_1);
MatriksIdentitas(rza_1);
MatriksIdentitas(Matriks);

radian:=sudut*PI/180;

u1:=Normalisasi(BuatVektor(1,0,0));
u2:=Normalisasi(buatVektor(0,1,0));
s :=Normalisasi(BuatVektor(xr,yr,zr));
u :=BuatVektor(xr,0,zr);
if PanjangVektor(u)=0 then betha:=0
//Sumbu putar berhimpit dengan sumbu Y
else
begin
u:=normalisasi(u);
betha:=arcCos(DotProduct(u1,u));
if u.posZ<0 then betha:=-betha;
end;

alpha:=arcCos(DotProduct(u2,s));

ryb[0,0]:=cos(betha);ryb[0,2]:=-sin(betha);
ryb[2,0]:=sin(betha);ryb[2,2]:=cos(betha);
//Ry(-betha)
38

perkalianMatriks(Matriks,ryb,Matriks);

rza[0,0]:=cos(alpha);rza[0,1]:=sin(alpha);
rza[1,0]:=-sin(alpha);rza[1,1]:=cos(alpha);
//Ry(-betha)*Rz(-alpha)
PerkalianMatriks(MAtriks,rza,Matriks);

ry[0,0]:=cos(radian);ry[0,2]:=-sin(radian);
ry[2,0]:=sin(radian);ry[2,2]:=cos(radian);
//Ry(Degree)
PerkalianMatriks(Matriks,ry,Matriks);

rza_1[0,0]:=cos(-alpha);rza_1[0,1]:=sin(-alpha);
rza_1[1,0]:=-sin(-alpha);rza_1[1,1]:=cos(-alpha);
//Rz(degree)
PerkalianMAtriks(Matriks,rza_1,MAtriks);

ryb_1[0,0]:=cos(-betha);ryb_1[0,2]:=-sin(-betha);
ryb_1[2,0]:=sin(-betha);ryb_1[2,2]:=cos(-betha);
//Ry(betha)
PerkalianMatriks(Matriks,ryb_1,MAtriks);
end;

f. Shearing
Persamaan transformasi shearing yang terdapat pada persamaan 2.9,
2.10, dan 2.11 dibuat ke dalam bentuk prosedur shearing di bawah ini. Prosedur
ini digunakan untuk melakukan shearing pada suatu titik dengan sumbu sumbu,
nilai referensi ref, dan nilai shearing shear.
Procedure
TTransformasi.Shearing(sumbu:integer;ref,shear1,shear2:real
);
var matriksShearing:Matriks4x4;
begin
MatriksIdentitas(matriksShearing);
if sumbu=1 then
begin
matriksShearing[3,1]:=-shear1*ref;
matriksShearing[3,2]:=-shear2*ref;
39

matriksShearing[0,1]:=shear1;
matriksShearing[0,2]:=shear2;
end;
if sumbu=2 then
begin
matriksShearing[3,0]:=-shear1*ref;
matriksShearing[3,2]:=-shear2*ref;
matriksShearing[1,0]:=shear1;
matriksShearing[1,2]:=shear2;
end;
if sumbu=3 then
begin
matriksShearing[3,0]:=-shear1*ref;
matriksShearing[3,1]:=-shear2*ref;
matriksShearing[2,0]:=shear1;
matriksShearing[2,1]:=shear2;
end;
PerkalianMatriks(Matriks,matriksShearing,Matriks);
end;

g. Matriks Transformasi
Operasi matriks transformasi digunakan untuk mengalikan suatu titik 3
dimensi dengan matriks transformasi sehingga diperoleh titik hasil
transformasinya. Operasi ini dinyatakan dalam bentuk prosedur Transform.
procedure TTransformasi.Transform(P:Ttitik3d;
var Q:Ttitik3d);
begin
Q.posX:=P.posX*Matriks[0,0]+P.posY*Matriks[1,0]+
P.posZ*MAtriks[2,0]+1*Matriks[3,0];
Q.posY:=P.posX*Matriks[0,1]+P.posY*Matriks[1,1]+
P.posZ*MAtriks[2,1]+1*Matriks[3,1];
Q.posZ:=P.posX*Matriks[0,2]+P.posY*Matriks[1,2]+
P.posZ*MAtriks[2,2]+1*Matriks[3,2];
end;

4.1.5. Implementasi Transformasi Menggunakan Mouse


Konversi koordinat 2 dimensi layar ke koordinat 3 dimensi OpenGL
dilakukan oleh kelas Ttransformasi melalui prosedur ambilPos3d(X,Y:integer;
40

var titik:TArTitik3D).
Procedure TTransformasi.ambilPos3d(X,Y:integer;
var titik:TArTitik3D);
var viewport : array[1..4] of Integer;
modelview: array[1..16] of Double;
proyeksi : array[1..16] of Double;
winZ : Single;
begin
glGetDoublev(GL_MODELVIEW_MATRIX, @modelview);
glGetDoublev(GL_PROJECTION_MATRIX,@proyeksi);
glGetIntegerv(GL_VIEWPORT,@viewport);
if Y=0 then Y:=1;
glReadPixels(X,-Y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,@winZ);
gluUnProject(X,viewport[4]Y,winZ,@modelview,
@proyeksi,@viewport,titik[1],titik[2],titik[3]);
end;
Nilai koordinat yang diperoleh pada variabel titik akan digunakan untuk
transformasi 3 dimensi menggunakan mouse.
Transformasi dengan mouse dilakukan dengan menggunakan 3 prosedur
dari kelas Tform, yaitu Panel1MouseDown, Panel1MouseMove, dan
Panel1MouseUp. Pada prosedur Panel1MouseDown, membuat variabel mouse
Turun menjadi true agar transformasi pada prosedur Panel1MouseMode dapat
dilakukan. Pada saat mouse bergerak, koordinat 2 dimensi layar dan 3 dimensi
OpenGL diambil dengan perintah berikut:
Transform.ambilPos3d(X,Y,titikPro3D);
dx:=titikPro3D[1]-awalX;
dy:=titikPro3D[2]-awalY;
dz:=titikPro3D[3]-awalZ;
deltaX:=X-X2;
deltaY:=Y-Y2;
Variabel X dan Y di atas diambil dari prosedur TFormUtama.Panel1MouseMove
(Sender: TObject; Shift: TShiftState;X, Y: Integer). Selanjutnya
prosedur akan melakukan transformasi. Kode program untuk melakukan
transformasi dapat dilihat pada lampiran A. Pada akhir prosedur ini dilakukan
memberikan nilai posisi mouse sekarang ke poisisi mouse awal.
X2:=X;
Y2:=Y;
41

awalX:=titikPro3d[1];
awalY:=titikPro3d[2];
awalZ:=titikPro3d[3];
Pada prosedur Panel1MouseUp variabel mouseTurun dibuat menjadi false agar
transformasi menggunakan mouse menjadi tidak aktif.

4.1.6. Implementasi Benda Rumit


Aplikasi ini juga dapat menampilkan objek rumit, yaitu dengan memuat
berkas berektensi obj dan menampilkan objeknya pada layar. Untuk memuat
berkas berkestensi obj, penulis menggunakan berkas kode program yang dibuat
oleh Jan Horn[7]. Penggunaannya cukup dengan menambahkan klausa OBJLoader
pada bagian uses (berkas OBJLoader ada pada direktori yang sama dengan
aplikasi). Berkas ini berfungsi seperti kodek yang membaca isi berkas obj dan
menterjemahkannya ke OpenGL.
Dalam mengimplementasikan Obj Loader, penyusun membuat kelas baru
yang merupakan turunan dari kelas Tgeometri. Kodenya dapat dilihat seperti di
bawah ini:
TOBJLoader = class(Tgeometri)
private
titikMin,titikMax:Ttitik3d;
procedure hitungMinMax(i:integer);
procedure gambarKotak;
public
m:Tmodel;
berkas:string;
constructor create(fileObj:string);
procedure Gambar;override;
end;
Pada saat objek dari kelas TOBJLoader diciptakan melalui konstruktor,
berkas dimuat dengan perintah m:=LoadModel(berkas). Objek tersebut di
simpan ke variabel m.
Constructor TOBJLoader.create(fileObj:string);
var i:integer;
begin
berkas:=fileObj;
m:=LoadModel(berkas);
42

. . .
End;
Untuk memgambar objek yang terdapat pada variabel m cukup dengan
menggunakan perintah DrawModel(m) yang terdapat pada prosedur
TOBJLoader.Gambar.
procedure TOBJLoader.Gambar;
var i:integer;
begin
. . .
DrawModel(m);
. . .
end;
Semua fungsi-fungsi di atas dilakukan pada saat tombol gambar (sButton4) pada
tab OBJ Loader ditekan. Kodenya seperti di bawah ini:
procedure TFormUtama.sButton4Click(Sender: TObject);
Var ObjekBaru:Tgeometri;
begin
if sOpenDialog1.execute then
begin
ObjekBaru:=nil;
ObjekBaru:=TOBJLoader.create(sOpenDialog1.FileName);
DaftarGeometri.TambahGeometri(ObjekBaru);
end;
end;
Hasil dari implentasi obj loader dapat dilihat pada gambar 4.10.

Gambar 4.10a Objek mobil dan bola menggunakan obj loader pada posisi awal.
43

Gambar 4.10b Objek mobil dan bola menggunakan obj loader pada
posisi setelah rotasi (-30o, 0, 1, 0).

Objek bola dan mobil dimuat menggunakan obj loader (gambar 4.10a).
Objek bola dan mobil masing-masing terdiri dari 1761 dan 233 verteks, jauh lebih
banyak dibandingkan kubus yang hanya memiliki 9 verteks. Keduanya kemudian
di rotasi sebesar -30o dengan sumbu putar Y dan hasilnya dapat dilihat pada
gambar 4.10b.

4.2. Pengujian Validasi Fungsi Transformasi Aplikasi


Pada subbab ini, transformasi-transformasi 3D pada aplikasi diuji.
Pengujian dilakukan dengan membandingkan hasil transformasi aplikasi dengan
hasil transformasi menggunakan perhitungan. Pengujian dilakukan pada objek
geometri piramida yang memiliki 7 titik. Gambar 4.11 menunjukkan posisi awal
piramida ketika dibuat pada aplikasi.

Gambar 4.11 Posisi awal piramida pada layar aplikasi.


44

Titik-titik penyusun piramida kemudian dibuat dalam bentuk tabel 4.1.

Tabel 4.1 Koordinat awal titik-titik piramida.

Titik Koordinat Awal

0 0,00 0,00 0,00


1 0,00 0,50 0,00
2 -0,50 -0,50 0,50
3 0,50 -0,50 0,50
4 0,50 -0,50 -0,50
5 -0,50 -0,50 -0,50
6 -0,50 -0,50 0,50

4.2.1. Pengujian Transformasi Translasi


Keadaan awal piramida seperti yang ditunjukkan pada gambar 4.12 dan
tabel 4.1 akan ditranslasikan dengan tx=1, ty=1, dan tz=-1 (gambar4.11).

Gambar 4.11 Form untuk memasukkan nilai translasi.

Hasil yang diperoleh pada layar aplikasi seperti gambar 4.13 dengan koordinat
baru pada tabel 4.2.

(a) (b)
Gambar 4.13 Piramida: (a) sebelum translasi (1, 1, -1);
(b) sesudah translasi (1, 1, -1).
45

a. Contoh Perhitungan
Sebagai contoh perhitungan digunakan titik 2 pada piramida. Titik 2
memiliki koordinat awal (-0,50, -0,50, 0,50) ditranslasikan sebesar (1,00 1,00 -
1,00). Dengan menggunakan persamaan 2.3, 2.4, dan 2.5 maka:
1 0 0 0
0 1 0 0
[x ' y ' z ' 1] = [x y z 1] ⋅ 
0 0 1 0
 
t x ty tz 1
[x ' [
y ' z ' 1] = x + t x y + ty z + tz 1 ]
1 0
0 0
0 1 0 0
[x ' y ' z ' 1] = [− 0,5 − 0,5 0,5 1]⋅ 
0 0 1 0
 
1 1 − 1 1
[x ' y ' z ' 1] = [− 0,5 + 1 − 0,5 + 1 0,5 + (−1) 1]
[x ' y ' z ' 1] = [0,5 0,5 − 0,5 1]
Dengan cara perhitungan yang sama, untuk titik-titik piramida yang lain, titik-titik
hasil translasinya dapat dilihat pada tabel 4.3.

b. Perbandingan antara hasil perhitungan dan hasil aplikasi


Perbandingan antara hasil perhitungan dan hasil aplikasi dapat dilihat pada
tabel 4.2. Hasil yang ditunjukkan aplikasi sama dengan hasil perhitungan. Ini
menandakan aplikasi dapat melakukan translasi dengan tepat.

Tabel 4.2. Perbandingan antara hasil perhitungan dan hasil aplikasi


untuk translasi (1,00, 1,00, -1,00);
Koordinat Hasil Transformasi
Titik
Awal Aplikasi Perhitungan
0 0,00 0,00 0,00 1,00 1,00 -1,00 1,00 1,00 -1,00
1 0,00 0,50 0,00 1,00 1,50 -1,00 1,00 1,50 -1,00
2 -0,50 -0,50 0,50 0,50 0,50 -0,50 0,50 0,50 -0,50
3 0,50 -0,50 0,50 1,50 0,50 -0,50 1,50 0,50 -0,50
4 0,50 -0,50 -0,50 1,50 0,50 -1,50 1,50 0,50 -1,50
5 -0,50 -0,50 -0,50 0,50 0,50 -1,50 0,50 0,50 -1,50
6 -0,50 -0,50 0,50 0,50 0,50 -0,50 0,50 0,50 -0,50

4.2.2. Pengujian Transformasi Penskalaan


Keadaan awal piramida seperti yang ditunjukkan pada gambar 4.11 dan
46

tabel 4.1 akan diskalakan dengan sx=2, sy=2, dan sz=2 (gambar 4.15).

Gambar 4.15 Form untuk memasukkan nilai penskalaan.

Hasil yang diperoleh pada layar aplikasi seperti gambar 4.16 dengan koordinat
baru pada tabel 4.3.

(a) (b)
Gambar 4.16 Piramida: (a) sebelum penskalaan (2, 2, 2);
(b) sesudah penskalaan (2, 2, 2).

a. Contoh Perhitungan
Sebagai contoh perhitungan digunakan titik 2 pada piramida. Titik 2
memiliki koordinat awal (-0,50, -0,50, 0,50) diskalakan sebesar (2,00, 2,00, 2,00).
Dengan menggunakan persamaan 2.8 maka:
sx 0 0 0
0 sy 0 0
[x ' y ' z ' 1] = [x y z 1]⋅ 
0 0 sz 0
 
0 0 0 1
[x ' [
y ' z ' 1] = x ⋅ s x y ⋅ sy z ⋅ sz 1 ]
47

2 0 0 0
0 2 0 0
[x ' y ' z ' 1] = [−,5 − 0,5 0,5 1]⋅ 
0 0 2 0
 
0 0 0 1
[x ' y ' z ' 1] = [− 0,5 ⋅ 2 − 0,5 ⋅ 2 0,5 ⋅ 2 1]
[x ' y ' z ' 1] = [− 1 − 1 1 1]
Dengan cara perhitungan yang sama, untuk titik-titik piramida yang lain, titik-titik
hasil penskalaannya dapat dilihat pada tabel 4.3.

b. Perbandingan antara hasil perhitungan dan hasil aplikasi


Perbandingan antara hasil perhitungan dan hasil aplikasi dapat dilihat pada
tabel 4.3. Hasil yang ditunjukkan aplikasi sama dengan hasil perhitungan. Ini
menandakan aplikasi dapat melakukan penskalaan dengan tepat.

Tabel 4.3. Perbandingan antara hasil perhitungan dan hasil


aplikasi untuk transformasi penskalaan (2,00 2,00 2,00);
Koordinat Hasil Transformasi
Titik
Awal Aplikasi Perhitungan
0 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00
1 0,00 0,50 0,00 0,00 1,00 0,00 0,00 1,00 0,00
2 -0,50 -0,50 0,50 -1,00 -1,00 1,00 -1,00 -1,00 1,00
3 0,50 -0,50 0,50 1,00 -1,00 1,00 1,00 -1,00 1,00
4 0,50 -0,50 -0,50 1,00 -1,00 -1,00 1,00 -1,00 -1,00
5 -0,50 -0,50 -0,50 -1,00 -1,00 -1,00 -1,00 -1,00 -1,00
6 -0,50 -0,50 0,50 -1,00 -1,00 1,00 -1,00 -1,00 1,00

4.2.3. Pengujian Transformasi Rotasi


Keadaan awal piramida seperti yang ditunjukkan pada gambar 4.11 dan
tabel 4.1 akan dirotasikan dengan sudut putar sebesar 30o dan sumbu putar ry=1
(gambar 4.17).

Gambar 4.17 Form untuk memasukkan nilai rotasi.


48

Hasil yang diperoleh pada layar aplikasi seperti gambar 4.18 dengan koordinat
baru pada tabel 4.4.

(a) (b)
Gambar 4.18 Piramida: (a) sebelum rotasi (30o, 0,00, 1,00, 0,00);
(b) sesudah rotasi (30o, 0,00, 1,00m 0,00).

a. Contoh Perhitungan
Sebagai contoh perhitungan digunakan titik 2 pada piramida. Titik 2
memiliki koordinat awal (-0,50, -0,50, 0,50) dirotasikan dengan sudut 30o dan
sumbu ry=1. Dengan menggunakan persamaan 2.11, maka yang pertama
dilakukan adalah menghitung panjang vektor koordinat awal.
s = ( x2 − x1 y 2 − y1 z 2 − z1 )
s = (0 − 0 1 − 0 0 − 0)
s = (0 1 0 )
Langkah kedua adalah vektor s diubah menjadi unit vektor dengan membagi
vektor dengan panjang absolut vektor.

s = xr + y r + z r
2 2 2

s = 0 2 + 12 + 0 2

s =1
x yr z r 
s =  r 

 s s s 
0 1 0
s= 
1 1 1
s = (0 1 0 )
Langkah ketiga adalah mencari besar sudut alpha (α) yang dibentuk oleh vektor s
49

dan u2 (vektor searah sumbu y positif).

u 2 = 0 2 + 12 + 0 2 = 1

u2 =
(0
1 0)
= (0 1 0 )
1
α = arccos( u 2 • s )
α = arccos ((0 1 0 ) • (0 1 0 ))
α = arccos(1)
α = 00
Langkah keempat adalah mencari besar sudut betha (β) yang dibentuk oleh vektor
u (x, 0, z) dan u1 (vektor searah sumbu x positif).

u1 = 12 + 0 2 + 0 2 = 1

u1 =
(1 0 0)
= (1 0 0 )
1
u = 02 + 02 + 02 = 0

u=
(0
0 0)
= (~ ~ ~ )
0
β = arccos(u1 • u )
β = arccos((1 0 0) • (~ ~ ~ ))
β = arccos(~)
Karena vektor u bernilai 0 maka sudut β yang dibentuk oleh vektor u dan u1
bernilai 0o.
Langkah kelima adalah memutar titik pada sumbu Y sehingga terletak di bidang
XY.

Cos ( β ) 0 − Sin( β ) 0
 0 1 0 0
[x ' y ' z ' 1] = [x y z 1] ⋅ 
 Sin( β ) 0 Cos ( β ) 0
 
 0 0 0 1

Cos (0 0 ) 0 − Sin(0 0 ) 0
 
[x ' y ' z ' 1] = [− 0,5 − 0,5 0,5 1] ⋅ 
0
 Sin(00 )
1 0 0
0 Cos (0 0 ) 0
 
 0 0 0 1
50

1 0 0 0
0 1 0 0
[x ' y ' z ' 1] = [− 0,5 − 0,5 0,5 1]* 
0 0 1 0
 
0 0 0 1
[x ' y ' z ' 1] = [− 0,5 − 0,5 0,5 1]
Langkah keenam adalah memutar titik pada sumbu z sehingga terletak di bidang
di sumbu y.
 Cos (α ) Sin(α ) 0 0
− Sin(α ) Cos (α ) 0 0
[x ' y ' z ' 1] = [x y z 1] ⋅ 
 0 0 1 0
 
 0 0 0 1

 Cos (0 0 ) Sin(0 0 ) 0 0
 
− Sin(0 0 ) Cos (0 0 )
[x ' y ' z ' 1] = [− 0,5 − 0,5 0,5 1] ⋅ 

0 0
0 0 1 0
 
 0 0 0 1
1 0 0 0
0 1 0 0
[x ' y ' z ' 1] = [− 0,5 − 0,5 0,5 1] ⋅ 
0 0 1 0
 
0 0 0 1
[x ' y ' z ' 1] = [− 0,5 − 0,5 0,5 1]
Langkah keenam adalah memutar titik pada sumbu z sebesar sudut yang
ditentukan untuk transformasi rotasi.

Cos (θ ) 0 − Sin(θ ) 0
 0 1 0 0
[x ' y ' z ' 1] = [x y z 1] ⋅ 
 Sin(θ ) 0 Cos (θ ) 0
 
 0 0 0 1

Cos (30 0 ) 0 − Sin(30 0 ) 0


 
[x ' y ' z ' 1] = [− 0,5 − 0,5 0,5 1] ⋅ 
0
 Sin(30 0 )
1 0 0
0 Cos (30 0 ) 0
 
 0 0 0 1
51

0,866 0 − 0,5
0
 0 1 0
0
[x ' y ' z ' 1] = [− 0,5 − 0,5 0,5 1] ⋅ 
 0,5 0 0,866 0
 
 0 0 0 1
[x ' y ' z ' 1] = [0,183 − 0,5 0,683 1]
Langkah ketujuh adalah memutar balik titik sebesar –α pada sumbu Z.
 Cos (−α ) Sin(−α ) 0 0
− Sin(−α ) Cos (−α ) 0 0
[x ' y ' z ' 1] = [x y z 1] ⋅ 
 0 0 1 0
 
 0 0 0 1

 Cos (−0 0 ) Sin(−0 0 ) 0 0


 
− Sin(−0 0 ) Cos (−0 0 )
[x ' y ' z ' 1] = [− 0,183 − 0,5 0,683 1] ⋅ 

0 0
0 0 1 0
 
 0 0 0 1
1 0 0 0
0 1 0 0
[x ' y ' z ' 1] = [− 0,183 − 0,5 0,683 1] ⋅ 
0 0 1 0
 
0 0 0 1
[x ' y ' z ' 1] = [− 0,183 − 0,5 0,683 1]

Langkah kedelapan adalah memutar balik titik sebesar –β pada sumbu Y.


Cos (− β ) 0 − Sin(− β ) 0
 0 1 0 0
[x ' y ' z ' 1] = [x y z 1] ⋅ 
 Sin(− β ) 0 Cos (− β ) 0
 
 0 0 0 1

Cos (−0 0 ) 0 − Sin(−0 0 ) 0


 
[x ' y ' z ' 1] = [− 0,183 − 0,5 0,683 1] ⋅ 
0
 Sin(−0 0 )
1 0 0
0 Cos (−0 0 ) 0
 
 0 0 0 1
1 0 0 0
0 1 0 0
[x ' y ' z ' 1] = [− 0,183 − 0,5 0,683 1] ⋅ 
0 0 1 0
 
0 0 0 1
[x ' y ' z ' 1] = [− 0,183 − 0,5 0,683 1]
52

Dengan cara perhitungan yang sama, untuk titik-titik piramida yang lain, titik-titik
hasil penskalaannya dapat dilihat pada tabel 4.4.

b. Perbandingan antara hasil perhitungan dan hasil aplikasi


Perbandingan antara hasil perhitungan dan hasil aplikasi dapat dilihat pada
tabel 4.4. Hasil yang ditunjukkan aplikasi sama dengan hasil perhitungan. Ini
menunjukkan aplikasi dapat melakukan rotasi dengan tepat.

Tabel 4.4. Perbandingan antara hasil perhitungan dan hasil


aplikasi untuk transformasi rotasi (30o 0,00 1,00 0,00).
Koordinat Hasil Transformasi
Titik
Awal Aplikasi Perhitungan
0 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00
1 0,00 0,50 0,00 0,00 0,50 0,00 0,00 0,50 0,00
2 -0,50 -0,50 0,50 -0,18 -0,50 0,68 -0,18 -0,50 0,68
3 0,50 -0,50 0,50 0,68 -0,50 0,18 0,68 -0,50 0,18
4 0,50 -0,50 -0,50 0,18 -0,50 -0,68 0,18 -0,50 -0,68
5 -0,50 -0,50 -0,50 -0,68 -0,50 -0,18 -0,68 -0,50 -0,18
6 -0,50 -0,50 0,50 -0,18 -0,50 0,68 -0,18 -0,50 0,68

4.2.4. Pengujian Transformasi Shearing


Keadaan awal piramida seperti yang ditunjukkan pada gambar 4.11 dan
tabel 4.1 akan dilakukan shearing dengan sumbu X, faktor shearing 1,00, dan titik
referensi di X=1,00. (gambar 4.19).

Gambar 4.19 Form untuk memasukkan nilai shearing.

Hasil yang diperoleh pada layar aplikasi seperti gambar 4.20 dengan koordinat
baru pada tabel 4.5.
53

(a) (b)
Gambar 4.20 Piramida: (a) sebelum shearing (X 1,00 1,00);
(b) sesudah shearing (X 1,00 1,00).

a. Contoh Perhitungan
Sebagai contoh perhitungan digunakan titik 2 pada piramida. Titik 2
memiliki koordinat awal (-0,50 -0,50 0,50) dilakukan shearing dengan (X 1,00
1,00). Karena menggunakan sumbu X sebagai sumbu shearing maka persamaan
yang digunakan adalah persamaan 2.15 (untuk sumbu lain persamaan yang
digunakan menyesuaikan). Dengan demikian:
1 Shxy Shxz 0
0 1 0 0
[x ' y ' z ' 1] = [x y z 1] ⋅ 
0 0 1 0
 
0 − Shxy ⋅ X ref − Shxz ⋅ X ref 1

1 1 1 0
0 1 0 0
[x ' y ' z ' 1] = [− 0,5 − 0,5 0,5 1] ⋅ 
0 0 1 0
 
0 − 1 ⋅ 1 − 1 ⋅ 1 1
[x ' y ' z ' 1] = [− 0,5 − 2,0 − 1,0 1]
Dengan cara perhitungan yang sama, untuk titik-titik piramida yang lain, titik-titik
hasil shearing-nya dapat dilihat pada tabel 4.5.

b. Perbandingan antara hasil perhitungan dan hasil aplikasi


Perbandingan antara hasil perhitungan dan hasil aplikasi dapat dilihat pada
tabel 4.5. Hasil yang ditunjukkan aplikasi sama dengan hasil perhitungan. Ini
menandakan aplikasi dapat melakukan shearing dengan tepat.
54

Tabel 4.5 Perbandingan antara hasil perhitungan dan hasil


aplikasi untuk transformasi shearing (X 1,00 1,00).
Koordinat Hasil Transformasi
Titik
Awal Aplikasi Perhitungan
0 0,00 0,00 0,00 0,00 -1,00 -1,00 0,00 -1,00 -1,00
1 0,00 0,50 0,00 0,00 -0,50 -1,00 0,00 -0,50 -1,00
2 -0,50 -0,50 0,50 -0,50 -2,00 -1,00 -0,50 -2,00 -1,00
3 0,50 -0,50 0,50 0,50 -1,00 0,00 0,50 -1,00 0,00
4 0,50 -0,50 -0,50 0,50 -1,00 -1,00 0,50 -1,00 -1,00
5 -0,50 -0,50 -0,50 -0,50 -2,00 -2,00 -0,50 -2,00 -2,00
6 -0,50 -0,50 0,50 -0,50 -2,00 -2,00 -0,50 -2,00 -2,00

Dari semua pengujian yang dilakukan, hasil pengujian aplikasi dan perhitungan
menunjukkan kesamaan. Jika hanya dari hasil tersebut, dapat dikatakan bahwa
aplikasi dapat menjalankan fungsi-fungsi transformasi dengan tepat.

4.3. Pengujian Framerate


Selain pengujian validasi fungsi transformasi aplikasi, pengujian juga
dilakukan dengan membandingkan framerate hasil aplikasi tugas akhir dengan
framerate yang dihasilkan aplikasi yang menggunakan fungsi transformasi
OpenGL. Tujuan pengujian ini adalah untuk mengetahui kecepatan transformasi
aplikasi dengan transformasi bawaan OpenGL. Pengujian dilakukan pada
komputer dengan spesifikasi berikut: prosesor AMD Athlon +2500 1,8 GHz,
RAM 512 MB, motherboard ECS N2U400-A, dan kartu VGA GeForce FX 5700
128 MB AGP 8X.
Framerate adalah banyaknya gambar yang ditampilkan oleh aplikasi dalam
waktu satu detik. Makin tinggi framerate maka pergerakan gambar yang
ditampilkan makin halus. Dengan menggunakan spesifikasi komputer yang
disebutkan sebelumnya, framerate gambar polos tanpa objek yang dapat
ditampilkan adalah 60 FPS (frame per second).
Gambar dibuat tiap kali aplikasi berada dalam kondisi idle, yaitu kondisi di
mana aplikasi menunggu atau tanpa beban matematis. Jika framerate 60 FPS
berarti aplikasi menggambar sebanyak 60 kali per detik pada saat aplikasi idle.
Perintah Application.OnIdle := Idle digunakan agar aplikasi menggambar
pada saat aplikasi idle.
55

procedure TFormUtama.FormCreate(Sender: TObject);


var . . .;
begin
. . .
// when the app has spare time, render the GL scene
Application.OnIdle := Idle;
. . .
end;
Kode di bawah merupakan prosedur yang dieksekusi pada saat aplikasi idle. Di
dalam prosedur tersebut terdapar prosedur untuk menggambar dan meampilkan
scene, yaitu glDraw() dan SwapBuffers(DC).
procedure TFormUtama.Idle(Sender: TObject;
var Done: Boolean);
begin
. . .
glDraw(); // Draw the scene
SwapBuffers(DC); // Display the scene
. . .
end;
Nilai framerate berkaitan erat dengan beban matematis. Jika beban
matematis ditambah seperti menjalankan operasi translasi, rotasi, atau penskalaan
maka komputer harus mengerjakan beban matematis itu terlebih dahulu lalu
menggambarkan hasilnya. Akibatnya jika beban matematisnya berat atau banyak
maka jumlah gambar yang dapat dibuat dalam satu detik akan menurun sehingga
mengakibatkan terjadinya penurunan framerate. Pada akhirnya pergerakan
gambar yang ditampilkan menjadi tidak halus.
Dua aplikasi berbeda dipakai pada saat pengujian. Aplikasi pertama (gambar
4.21a) menggunakan fungsi transformasi buatan sendiri dan aplikasi kedua
(gambar 4.21b) menggunakan fungsi transformasi bawaan OpenGL. Pengujian
dilakukan hanya pada transformasi rotasi, translasi, dan penskalaan sedangkan
shearing tidak dilakukan karena OpenGL tidak memiliki fungsi transformasi
shearing.
Gambar 4.21 menunjukkan gambar pengujian framerate pada pengujian
transformasi penskaalan untuk 3 objek potatohead. Perhatikan bagian gambar
4.21a dan bagian 4.21b. Di situ ditampilkan framerate aplikasi.
56

(a)

(b)
Gambar 2.21 Pengujian framerate untuk penskalaan: (a) aplikasi menggunakan fungsi
transformasi buatan sendiri dan (b) aplikasi menggunakan fungsi transformasi bawaan OpenGL.

4.3.1. Pengujian Framerate Rotasi


Pengujian framerate rotasi dilakukan dengan menguji framerate pada saat
objek dirotasi dengan sudut 1o pada sumbu Y secara terus-menerus. Hasilnya
dapat dilihat pada tabel 4.6.
57

Tabel 4.6 Perbandingan framerate transformasi aplikasi dan OpenGL


untuk transformasi rotasi.
Framerate (FPS)
No. Gambar Jumlah Verteks
Aplikasi OpenGL Selisih
1. 1 kursi 48 60 60 0
2. 2 bola 3522 59 60 1
3. 110 kursi 5390 50 60 10
4. 120 kursi 5880 47 60 13
5. 4 bola 7044 43 60 17
6. 1 potatohead 8576 37 60 23
7. 200 kursi 9800 30 60 30
8. 250 Meja 10250 20 60 40
9. 2 potatohead 17152 18 60 42
10. 3 potatohead 25728 12 59 48
11. 4 potatohead 34304 9 45 36
12. 5 potatohead 42880 6 30 24

Hasil (tabel 4.6) menunjukkan aplikasi mengalami penurunan framerate pada


saat jumlah verteks 3522 (No.2) sedangkan OpenGL mengalami penurunan
framerate pada saat jumlah verteks 25728 (No. 10). Ini menunjukkan bahwa
fungsi transformasi OpenGL lebih stabil dibandingkan fungsi transformasi
aplikasi.
Tabel 4.6 juga memperlihatkan bahwa tiap data pengujian nilai framerate
transformasi OpenGL hampir selalu lebih tinggi daripada framerate transformasi
aplikasi. Ini menunjukkan transformasi rotasi OpenGL lebih cepat dibandingkan
transformasi rotasi aplikasi.

4.3.2. Pengujian Framerate Translasi


Pengujian framerate translasi dilakukan dengan menguji framerate pada
saat objek dari z=0 ke z=-3 lalu kembali lagi ke z=0, balik lagi ke z=-3, dan
seterusnya. Tiap frame-nya objek dipindah sejauh 0,01. Hasilnya dapat dilihat
pada tabel 4.7.

Tabel 4.7 Perbandingan framerate transformasi aplikasi dan OpenGL


untuk transformasi translasi.
Framerate (FPS)
No. Gambar Jumlah Verteks
Aplikasi OpenGL Selisih
1. 1 kursi 48 60 60 0
2. 2 bola 3522 60 60 0
3. 110 kursi 5390 60 60 0
4. 120 kursi 5880 60 60 0
5. 4 bola 7044 60 60 0
6. 1 potatohead 8576 60 60 0
58

Framerate (FPS)
No. Gambar Jumlah Verteks
Aplikasi OpenGL Selisih
7. 200 kursi 9800 60 60 0
8. 250 Meja 10250 60 60 0
9. 2 potatohead 17152 59 60 1
10. 3 potatohead 25728 40 60 10
11. 4 potatohead 34304 31 46 15
12. 5 potatohead 42880 27 30 3

Hasil (tabel 4.7) menunjukkan aplikasi mengalami penurunan framerate pada


saat jumlah verteks 17152 (No.9) sedangkan OpenGL mengalami penurunan
framerate pada saat jumlah verteks 25728 (No. 10). Ini menunjukkan bahwa
fungsi transformasi OpenGL lebih stabil dibandingkan fungsi transformasi
aplikasi. Tabel 4.7 juga memperlihatkan bahwa mulai data no. 9 pengujian nilai
framerate transformasi OpenGL lebih tinggi daripada framerate transformasi
aplikasi. Ini menunjukkan transformasi rotasi OpenGL lebih cepat dibandingkan
transformasi translasi aplikasi jika jumlah verteksnya dari 17152 ke atas.

4.3.3. Pengujian Framerate Penskalaan


Pengujian framerate penskalaan dilakukan dengan menguji framerate pada
saat objek diskalakan dari skala=1 ke skala=4, lalu kembali lagi ke skala=1,
kembali lagi ke skala=4, dan seterusnya. Tiap framenya, skala objek ditambah
atau dikurangi 0,01. Hasilnya dapat dilihat pada tabel 4.8.

Tabel 4.8 Perbandingan framerate transformasi aplikasi dan OpenGL


untuk transformasi penskalaan.
Framerate (FPS)
No. Gambar Jumlah Verteks
Aplikasi OpenGL Selisih
1. 1 kursi 48 60 60 0
2. 2 bola 3522 60 60 0
3. 110 kursi 5390 30 60 30
4. 120 kursi 5880 20 60 40
5. 4 bola 7044 50 60 10
6. 1 potatohead 8576 60 60 0
7. 200 kursi 9800 15 60 45
8. 250 Meja 10250 15 60 45
9. 2 potatohead 17152 41 60 19
10. 3 potatohead 25728 27 60 33
11. 4 potatohead 34304 17 45 43
12. 5 potatohead 42880 15 30 15

Hasil (tabel 4.8) menunjukkan pada transformasi penskalaan aplikasi terjadi


naik turun atau ketidakstabilan penurunan framerate seiring dengan pertambahan
59

jumlah verteks sedangkan pada OpenGL framerate mengalami penurunan pada


saat jumlah verteks 25728 (No. 10). Ini menunjukkan bahwa fungsi transformasi
OpenGL lebih stabil dibandingkan fungsi transformasi aplikasi.
Tabel 4.8 juga memperlihatkan bahwa hampir semua data pengujian nilai
framerate transformasi OpenGL lebih tinggi daripada framerate transformasi
aplikasi. Ini menunjukkan transformasi rotasi OpenGL lebih cepat dibandingkan
transformasi penskalaan aplikasi.

4.3.4. Perbandingan Framerate Transformasi Aplikasi dan OpenGL


Pada subbab ini akan dilakukan perbadingan secara keseluruhan ketiga
transformasi tersebut, yaitu perbandingan antara jumlah verteks dengan framerate
dan pengaruh jenis transformasi dengan framerate. Hasilnya dapat dilihat pada
tabel 4.9.

Tabel 4.9 Perbandingan framerate ransformasi aplikasi dan OpenGL.


Framerate (FPS)
Jumlah
No. Gambar Rotasi Translasi Penskalaan
Verteks
Aplikasi OpenGL Aplikasi OpenGL Aplikasi OpenGL
1. 1 kursi 48 60 60 60 60 60 60
2. 2 bola 3522 59 60 60 60 60 60
3. 110 kursi 5390 50 60 60 60 30 60
4. 120 kursi 5880 47 60 60 60 20 60
5. 4 bola 7044 43 60 60 60 50 60
6. 1 potatohead 8576 37 60 60 60 60 60
7. 200 kursi 9800 30 60 60 60 15 60
8. 250 Meja 10250 20 60 60 60 15 60
9. 2 potatohead 17152 18 60 59 60 41 60
10. 3 potatohead 25728 12 59 40 60 27 60
11. 4 potatohead 34304 9 45 31 46 17 45
12. 5 potatohead 42880 6 30 27 30 15 30
Total = 391 674 637 676 410 675

Dari ketiga pengujian (tabel 4.9) transformasi aplikasi, dengan melihat


jumlah total framerate dari 12 data maka framerate transformasi translasi paling
mendekati nilai framerate tranformasi OpenGL, kedua adalah penskalaan, dan
ketiga adalah rotasi. Ini disebabkan beban komputasi translasi lebih rendah
dibandingkan rotasi dan penskalaan. Mansing-masing tranformasi tersebut
memiliki persamaan tersendiri, yaitu:
Translasi : z’ = z + tz (4.1)
Rotasi : x’ = x cos(θ) - z sin(θ) dan y = x sin(θ) + z cos(θ) (4.2)
Penskalaan : x’ = sx · x , y’ = sy · y , dan z’ = sz · z (4.3)
60

Translasi hanya memiliki beban operasi penjumlahan. Ini tentu lebih ringan
daripada penskalaan yang memiliki beban operasi perkalian dan rotasi yang
memiliki beban mencari nilai kosinus terlebih dahulu lalu melakukan operasi
perkalian serta penjumlahan. Jadi, nilai framerate juga bergantung pada jenis
transformasi yang digunakan.
Tabel 4.9 memperlihatkan bahwa framerate hasil tranformasi dengan
OpenGL, untuk jumlah verteks yang banyak, lebih tinggi daripada framerate hasil
transformasi aplikasi. Ini menunjukkan bahwa transformasi menggunakan fugnsi
bawaan OpenGL lebih cepat daripada fungsi tranformasi yang dibuat pada
aplikasi Tugas Akhir. Beban matematis transformasi pada aplikasi banyak
dibebankan ke prosesor dan beban matamatis diperkirakan juga mengoptimalkan
pemakaian kartu grafis selain pengunaan prosesor.
Tabel 4.9 juga memperlihatkan bahwa semakin tinggi jumlah verteks maka
semakin rendah pula nilai framerate, baik dari hasil transformasi aplikasi maupun
OpenGL. Transformasi dilakukan sekali pada satu verteks. Jika semakin banyak
verteks maka semakin banyak transformasi yang dilakukan. Makin banyak
transformasi dilakukan akan mengakibatkan turunya nilai framerate. Jadi, jumlah
verteks berbanding terbalik dengan nilai framerate.
BAB V

KESIMPULAN DAN SARAN

Bab V berisi kesimpulan dan saran. Kesimpulan yang ditulis merupakan hal-
hal penting dan berkesan yang didapat selama pembuatan aplikasi grafika
komputer untuk transformasi 3 dimensi. Saran yang diberikan merupakan
pengembangan lebih lanjut untuk meningkatkan kualitas aplikasi.

5.1. Kesimpulan
1. Aplikasi Tugas Akhir memiliki kemampuan melakukan transformasi
geometri pada objek-objek 3 dimensi yang dibuat dalam aplikasi.
2. Transformasi geometri yang dapat dilakukan oleh aplikasi, yaitu translasi,
rotasi, penskalaan, dan shearing.
3. Aplikasi Tugas Akhir memiliki perbedaan dengan OpenGL, yaitu aplikasi
memiliki transformasi shearing yang tidak dimiliki oleh OpenGL. Shearing
adalah transformasi geometri dimana benda dimiringkan dengan cara
menggeser salah satu atau kedua tepi yang saling menghadap menurut titik
acuan tertentu.
4. Transformasi geometri dilakukan dengan pertama-tama mengambil nilai
koordinat verteks-verteks objek, lalu mentranformasi nilai verteks-verteks
tersebut, kemudian nilai hasil transformasi diberikan kembali ke verteks-
verteks objek tadi, dan terakhir menggambar ulang objek dengan nilai
koordinat verteks yang baru.
5. Aplikasi Tugas Akhir dapat mentransformasi objek geoemetri melalui
penggunaan mouse dan masukan nilai parameter tranformasi. Melalui
penggunaan mouse berarti objek ditransformasi berdasarkan perubahan posisi
mouse yang dilakukan oleh pengguna. Melalui masukan parameter berarti
objek ditransformasi berdasarkan masukan nilai yang dilakukan oleh
pengguna melalui form yang disediakan.

61
62

6. Aplikasi Tugas Akhir dapat membuat objek-objek muai dari yang sederhana
seperti piramida yang terdiri dari 6 verteks, kubus (9 verteks), silinder (33
verteks), meja (41 verteks), kursi (48 verteks) hingga memuat objek-objek
yang rumit seperti mobil (233 verteks), bola (1761), dan potatohead (8576).
7. Perbandingan framerate hasil penggunaan fungsi transformasi geometri
aplikasi Tugas Akhir lebih rendah daripada framerate hasil penggunaan
fungsi transformasi geometri bawaan OpenGL.
8. Makin banyak verteks yang menyusun suatu objek maka makin lama pula
waktu yang dibutuhkan untuk mentranformasi objek secara keseluruhan.
9. Nilai framerate berbanding terbalik dengan jumlah verteks yang akan
ditransformasi dan jumlah operasi matematis pada transformasi yang
dilakukan. Makin tinggi jumlah verteks dan operasi matematis makin rendah
nilai framerate. Makin rendah jumlah verteks dan operasi matematis makin
tinggi nilai framerate.

5.2. Saran
1. Aplikasi dapat dikembangkan lebih lanjut dengan menambahkan fasilitas
pewarnaan (coloring) dan texture mapping sehingga warna suatu objek dapat
diubah sesuai kehendak pengguna dan objek memiliki tekstur yang membuat
tampilannya menjadi lebih realistis.
2. Aplikasi dapat dikembangkan lebih lanjut dengan menambahkan fasilitas
vertex modifer Dengan verteks modifier bentuk objek geometri dapat diubah
dengan fleksibel. Verteks-verteks penyusun objek geometri dapat
ditransformasi sehingga bentuk objek tersebut berubah.
DAFTAR PUSTAKA

[1]. Baker, M.P., Hearn, D., Computer Graphics with OpenGL, Third Edition,
Prentice Hall, New Jersey, 2004.
[2]. Bambang, H., Grafik komputer dengan C, Penerbit ANDI, 2004.
[3]. Benstead, L., Using gluUnProject, http://nehe.gamedev.net/, Maret 2006.
[4]. Davis, T., Neider, J., dan Woo, M., OpenGL Programming Guide, Addison-
Wesley Publishing Company, ISBN: 0-201-63274-8.
[5]. Dharwiyanti S., Wahono R.S., Pengantar Unified Modelling Language
(UML), ilmukomputer.com, 2003.
[6]. Fernandes, A.R., Picking Tutorial, http://www.lighthouse3d.com/opengl/,
Mei 2006.
[7]. Kronberger, M., OpenGL Tutorial, http://www.sulaco.co.za/, Maret 2006.
[8]. Maksimchuk, R.A., Naiburg, E.J., UML for Mere Mortals, Addison Wesley
Proffesional, October 26th, 2004.
[9]. Martz, P., OpenGL® Distilled, Addison Wesley Proffesional, 2004.
[10]. Munir, R., Pengolahan Citra Digital dengan Pendekatan Algoritmik,
Penerbit Informatika, Bandung, 2004.
[11]. Nugroho, Edi., Teori dan Praktek Grafika Komputer Menggunakan Delphi
dan OpenGL, Penerbit Graha ilmu, Yogyakarta, 2005.
[12]. Nuydens, T., Dot Project, http://www.delphi3d.net/, Maret 2006.
[13]. Philips, D., Image Processing in C, Second Edition, R & D Publications,
Kansas, 2000.
[14]. Pressman, R.S., Rekayasa Perangkat Lunak Pendekatan Praktisi, Buku Satu
dan Dua, McGraw-Hil Book Co., Penerbit ANDI, Yogyakarta, 2003.
[15]. Susilo, D., Grafika Komputer dengan Delphi, Penerbit Graha ilmu,
Yogyakarta, 2005.
[16]. ---, 3DS Max Application, http://www.autodesk.com/, Maret 2006.
[17]. ---, Blender Application, http://www.blender.org/, Maret 2006.
[18]. ---, Delphi Help, Borland Delphi Corporation, 2001.
[19]. ---, GLScene Demo, http://www.caperaven.co.za/, Maret 2006.
[20]. ---, OpenGL Specification, http://www.opengl.org/, Maret 2006.

63
[21]. ---, Tutorial on UML, Chapter 12, TIMe Electronic Textbook version 4.0,
SINTEF, July 16th, 1999.
[22]. --, Wavefront OBJ File Format Summary, http://www.fileformat.info/
resource/book/1565921615/index.htm, Agustus 2006.
[23]. ---, Win32 Developer’s References, Borland Delphi Corporation, 2001.

64
LAMPIRAN

D
LAMPIRAN A

KODE PROGRAM

GRAFIKA KOMPUTER UNTUK TRANSFORMASI 3D

PtugasAkhir.dpr
program PTugasAkhir;

uses
Forms,
unitUtama in 'unitUtama.pas' {FormUtama},
Geometri in 'Geometri.pas',
Transformasi in 'Transformasi.pas',
unitTranslasi in 'unitTranslasi.pas' {FormTranslasi},
unitPenskalaan in 'unitPenskalaan.pas' {FormPenskalaan},
unitRotasi in 'unitRotasi.pas' {FormRotasi},
vektor in 'vektor.pas',
unitShearing in 'unitShearing.pas' {FormShearing},
unitAbout in 'unitAbout.pas' {FormAbout};

{$R *.res}

begin
Application.Initialize;
Application.Title := 'A-Studio';
Application.CreateForm(TFormUtama, FormUtama);
Application.Run;
end.

unitUtama.pas
unit unitUtama;

interface

uses
GLext,OpenGL,Windows, Messages, SysUtils, Variants,
Classes,Graphics,Controls,
Forms,Dialogs, ToolWin, ComCtrls, sToolBar, ImgList,
Menus,sSkinProvider,
sSkinManager, ExtCtrls, sPanel, StdCtrls, sHintManager, sAdapter,
sGridAdapter, sMemo, sButton, sEdit, sSpinEdit, sGroupBox, sLabel,
sPageControl, sScrollBox, sFrameBar, sComboBox, sStatusBar,
Grids,Buttons,
ValEdit,Geometri,Transformasi,vektor,OBJloader, sDialogs,Math, ExtDlgs;

type
TFormUtama = class(TForm)
sSkinManager1: TsSkinManager;
sSkinProvider1: TsSkinProvider;
MainMenu1: TMainMenu;
File1: TMenuItem;
Help1: TMenuItem;
ImageList1: TImageList;
sStatusBar1: TsStatusBar;
sToolBar1: TsToolBar;
Exit1: TMenuItem;
ToolButton1: TToolButton;
Panel1: TPanel;
sGridAdapter1: TsGridAdapter;
Button1: TButton;

65
66

sFrameBar1: TsFrameBar;
tabObjek: TsPageControl;
sTabSheet1: TsTabSheet;
sTabSheet2: TsTabSheet;
sTabSheet3: TsTabSheet;
sTabSheet4: TsTabSheet;
About1: TMenuItem;
sGroupBox1: TsGroupBox;
sLabel1: TsLabel;
sLabel2: TsLabel;
sLabel3: TsLabel;
sDecimalSpinEdit1: TsDecimalSpinEdit;
sDecimalSpinEdit2: TsDecimalSpinEdit;
sDecimalSpinEdit3: TsDecimalSpinEdit;
sLabel4: TsLabel;
sLabel5: TsLabel;
sDecimalSpinEdit4: TsDecimalSpinEdit;
sDecimalSpinEdit5: TsDecimalSpinEdit;
sButton1: TsButton;
PopupMenu1: TPopupMenu;
ransformasi1: TMenuItem;
ranslasi1: TMenuItem;
Rotasi1: TMenuItem;
Penskalaan1: TMenuItem;
sGroupBox2: TsGroupBox;
sLabel6: TsLabel;
sLabel7: TsLabel;
sLabel8: TsLabel;
sDecimalSpinEdit6: TsDecimalSpinEdit;
sDecimalSpinEdit7: TsDecimalSpinEdit;
sDecimalSpinEdit8: TsDecimalSpinEdit;
sGroupBox3: TsGroupBox;
sLabel9: TsLabel;
sLabel10: TsLabel;
sLabel11: TsLabel;
sDecimalSpinEdit9: TsDecimalSpinEdit;
sDecimalSpinEdit10: TsDecimalSpinEdit;
sDecimalSpinEdit11: TsDecimalSpinEdit;
sGroupBox4: TsGroupBox;
sLabel12: TsLabel;
sLabel13: TsLabel;
sLabel14: TsLabel;
sDecimalSpinEdit12: TsDecimalSpinEdit;
sDecimalSpinEdit13: TsDecimalSpinEdit;
sDecimalSpinEdit14: TsDecimalSpinEdit;
sGroupBox5: TsGroupBox;
sLabel15: TsLabel;
sLabel16: TsLabel;
sLabel17: TsLabel;
sDecimalSpinEdit15: TsDecimalSpinEdit;
sDecimalSpinEdit16: TsDecimalSpinEdit;
sDecimalSpinEdit17: TsDecimalSpinEdit;
sComboBox1: TsComboBox;
sLabel18: TsLabel;
sLabel19: TsLabel;
sLabel20: TsLabel;
sDecimalSpinEdit18: TsDecimalSpinEdit;
sButton5: TsButton;
sLabel21: TsLabel;
sLabel22: TsLabel;
sDecimalSpinEdit19: TsDecimalSpinEdit;
sDecimalSpinEdit20: TsDecimalSpinEdit;
sButton7: TsButton;
sMemo1: TsMemo;
ToolButton7: TToolButton;
67

ToolButton8: TToolButton;
ToolButton9: TToolButton;
ToolButton10: TToolButton;
Hapus1: TMenuItem;
sTabSheet5: TsTabSheet;
sTabSheet6: TsTabSheet;
sGroupBox6: TsGroupBox;
sLabel23: TsLabel;
sLabel24: TsLabel;
sLabel25: TsLabel;
sDecimalSpinEdit21: TsDecimalSpinEdit;
sDecimalSpinEdit22: TsDecimalSpinEdit;
sDecimalSpinEdit23: TsDecimalSpinEdit;
sGroupBox7: TsGroupBox;
sLabel26: TsLabel;
sLabel27: TsLabel;
sLabel28: TsLabel;
sDecimalSpinEdit24: TsDecimalSpinEdit;
sDecimalSpinEdit25: TsDecimalSpinEdit;
sDecimalSpinEdit26: TsDecimalSpinEdit;
sButton2: TsButton;
sButton3: TsButton;
sHintManager1: TsHintManager;
sComboBox2: TsComboBox;
ToolButton14: TToolButton;
ToolButton2: TToolButton;
ToolButton3: TToolButton;
ToolButton4: TToolButton;
ToolButton5: TToolButton;
ToolButton6: TToolButton;
ToolButton11: TToolButton;
ToolButton12: TToolButton;
Shearing1: TMenuItem;
sTabSheet7: TsTabSheet;
sButton4: TsButton;
sOpenDialog1: TsOpenDialog;
ToolButton13: TToolButton;
Options1: TMenuItem;
ModeWireframe1: TMenuItem;
ModeAnimasi1: TMenuItem;
ToolButton15: TToolButton;
Smooth1: TMenuItem;
ransformasi2: TMenuItem;
Kamera1: TMenuItem;
ranslasi2: TMenuItem;
Penskalaan2: TMenuItem;
Rotasi2: TMenuItem;
Shearing2: TMenuItem;
Edit1: TMenuItem;
Hapus2: TMenuItem;
Zoom1: TMenuItem;
RotasiKamera1: TMenuItem;
RotasiFokus1: TMenuItem;
Geser1: TMenuItem;
FokusObjek1: TMenuItem;
Reset1: TMenuItem;
Timer1: TTimer;
Reset2: TMenuItem;
Grid1: TMenuItem;
sButton6: TsButton;
SavePictureDialog1: TSavePictureDialog;
SaveAsBMP1: TMenuItem;
procedure SaveAsBMP1Click(Sender: TObject);
procedure sButton6Click(Sender: TObject);
68

procedure Exit1Click(Sender: TObject);


procedure FormResize(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Panel1Resize(Sender: TObject);
procedure FormKeyPress(Sender: TObject; var Key: Char);
procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure sButton1Click(Sender: TObject);
procedure ranslasi1Click(Sender: TObject);
procedure sButton3Click(Sender: TObject);
procedure sButton5Click(Sender: TObject);
procedure sButton7Click(Sender: TObject);
procedure Penskalaan1Click(Sender: TObject);
procedure Rotasi1Click(Sender: TObject);
procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure sComboBox1Change(Sender: TObject);
procedure ToolButton8Click(Sender: TObject);
procedure Hapus1Click(Sender: TObject);
procedure ToolButton7Click(Sender: TObject);
procedure ToolButton9Click(Sender: TObject);
procedure sMemo1DblClick(Sender: TObject);
procedure sButton2Click(Sender: TObject);
procedure ToolButton2Click(Sender: TObject);
procedure ToolButton10Click(Sender: TObject);
procedure ToolButton3Click(Sender: TObject);
procedure ToolButton4Click(Sender: TObject);
procedure ToolButton5Click(Sender: TObject);
procedure ToolButton6Click(Sender: TObject);
procedure Shearing1Click(Sender: TObject);
procedure sComboBox2Change(Sender: TObject);
procedure sButton4Click(Sender: TObject);
procedure ToolButton13Click(Sender: TObject);
procedure ToolButton15Click(Sender: TObject);
procedure Hapus2Click(Sender: TObject);
procedure ranslasi2Click(Sender: TObject);
procedure Penskalaan2Click(Sender: TObject);
procedure Rotasi2Click(Sender: TObject);
procedure Shearing2Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure About1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);

private
{ Private declarations }
rc : HGLRC; // Rendering Context
dc : HDC; // Device Context
FPSCount:integer;
function DapatIndexObjek(x, y: integer): integer;
procedure glDraw;
procedure modePutar;
procedure Idle(Sender: TObject; var Done: Boolean);
public
{ Public declarations }
deltaX,deltaY,X2,Y2,ModeOperasi:integer;
DaftarGeometri:TdaftarGeometri;
modeTransformasi:integer;
Transform:Ttransformasi;
dX,dY,dZ,awalX,awalY,awalZ:double;
MouseTurun:boolean;
titikPro3d:TArTitik3D;
sudut,tempX,tempY,tempZ:real;
69

JarakKamFoc,kamera,fokus,atasKam,Dump3d,SumbuX,SumbuY:Ttitik3d;
end;

const
light_position1:array[0..3] of GLFloat=(5.0,5.0,5.0,1.0);
light_position2:array[0..3] of GLFloat=(5.0,5.0,5.0,1.0);
light_position3:array[0..3] of GLFloat=(5.0,5.0,-5.0,1.0);
light_position4:array[0..3] of GLFloat=(-5.0,5.0,-5.0,1.0);

var
FormUtama: TFormUtama;
Grid:Tgrid;

implementation

uses unitTranslasi, unitPenskalaan, unitRotasi, unitShearing, unitAbout;

{$R *.dfm}

procedure glInit();
begin
glClearColor(0.6, 0.6, 0.6, 1); // Black Background
glShadeModel(GL_FLAT); // Enables Smooth Color Shading
glClearDepth(1.0); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enable Depth Buffer
glEnable(GL_NORMALIZE);
glDepthFunc(GL_LESS); // The Type Of Depth Test To
Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Realy Nice
perspective calculations
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHT2);
glEnable(GL_LIGHT3);
glLightfv(GL_LIGHT0,GL_POSITION,@light_position1);
glLightfv(GL_LIGHT1,GL_POSITION,@light_position2);
glLightfv(GL_LIGHT2,GL_POSITION,@light_position3);
glLightfv(GL_LIGHT3,GL_POSITION,@light_position4);
end;

procedure TFormUTama.modePutar;
var index,i,X,Y,Z:integer;
item:TGeometri;
begin
if sComboBox2.ItemIndex=0 then Begin X:=1; Y:=1;Z:=1; end;
if sComboBox2.ItemIndex=1 then Begin X:=1; Y:=0;Z:=0; end;
if sComboBox2.ItemIndex=2 then Begin X:=0; Y:=1;Z:=0; end;
if sComboBox2.ItemIndex=3 then Begin X:=0; Y:=0;Z:=1; end;

for index:=0 to DaftarGeometri.f.Count-1 do


begin
item:=DaftarGeometri.f.Items[index];
if item.Aktif=true then
begin
for i:=0 to item.jumTitik do
begin
Transform.nolkanTransformasi;
Transform.Rotasi(0.3,X,Y,Z);
Transform.Transform(Item.Titik[i],item.Titik[i]);
end;
end;
DaftarGeometri.f.Items[index]:=item;
end;
end;
70

procedure TFormUtama.Exit1Click(Sender: TObject);


begin
if Application.MessageBox('Apakah Anda ingin
keluar?','Konfirmasi',MB_YESNO
or MB_ICONINFORMATION)=IDYES then
Application.terminate;
end;

procedure TFormUtama.FormResize(Sender: TObject);


begin
Panel1.Width:=FormUtama.Width-223;
Panel1.Height:=FormUtama.Height-125;
Panel1Resize(Sender);
sMemo1.Height:=FormUtama.Height-480;
end;

procedure TFormUtama.FormCreate(Sender: TObject);


var pfd : TPIXELFORMATDESCRIPTOR;
pf : Integer;
begin
DaftarGeometri:=TDaftarGeometri.Create(self);
Transform:=TTransformasi.Create;
//inisialisasi openGL
dc:=GetDC(Panel1.Handle);

// PixelFormat
pfd.nSize:=sizeof(pfd);
pfd.nVersion:=1;
pfd.dwFlags:=PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or
PFD_DOUBLEBUFFER or 0;
pfd.iPixelType:=PFD_TYPE_RGBA; // PFD_TYPE_RGBA or PFD_TYPEINDEX
pfd.cColorBits:=32;

pf :=ChoosePixelFormat(dc, @pfd); // Returns format that most closely


matches above pixel format
SetPixelFormat(dc, pf, @pfd);

rc :=wglCreateContext(dc); // Rendering Context = window-


glCreateContext
wglMakeCurrent(dc,rc); // Make the DC (Form1) the rendering
Context

// Initialist GL environment variables


glInit;
Panel1Resize(sender); // sets up the perspective
//AppStart :=GetTickCount();

// when the app has spare time, render the GL scene


Application.OnIdle := Idle;

kamera.posX:=0;kamera.posY:=2;kamera.posZ:=6;
fokus.posX:=0;fokus.posY:=0;fokus.posZ:=0;
atasKam.posX:=0;atasKam.posY:=1;atasKam.posZ:=0;
sumbuX.posX:=1;sumbuX.posY:=0;sumbuX.posZ:=0;
sumbuY.posX:=0;sumbuY.posY:=1;sumbuY.posZ:=0;
end;

procedure TFormUtama.glDraw();
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // Clear The
Screen And The Depth Buffer
glLoadIdentity(); // Reset The
View
if ModeWireframe1.Checked=true then
71

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

if Smooth1.Checked=true then
glShadeModel(GL_SMOOTH) else glShadeModel(GL_FLAT);

glInitNames();
glPushName(0);
if Grid1.Checked=true then
begin
Grid.Gambar; //Gambar Grid
glBegin(GL_LINES);

glVertex3f(0,0,0);glVertex3f(SumbuX.posX,SumbuX.posY,sumbuX.posZ);

glVertex3f(0,0,0);glVertex3f(sumbuY.posX,sumbuY.posY,sumbuY.posZ);
glEnd;
end;
DaftarGeometri.Gambar; //Gambar Objek
glPopName();
end;

procedure TFormUtama.FormDestroy(Sender: TObject);


begin
wglMakeCurrent(0,0);
wglDeleteContext(rc);
end;

procedure TFormUtama.Idle(Sender: TObject; var Done: Boolean);


begin
Done := false;
Panel1Resize(Sender);
if modeAnimasi1.Checked=true then
modePutar;
glDraw(); // Draw the scene
SwapBuffers(DC); // Display the scene
Inc(FPSCount);
end;

procedure TFormUtama.Panel1Resize(Sender: TObject);


begin
glViewport(0, 0, Panel1.Width, Panel1.Height); // Set the viewport
for the OpenGL window
glMatrixMode(GL_PROJECTION); // Change Matrix Mode to Projection
glLoadIdentity(); // Reset View
gluPerspective(45.0, Panel1.Width/Panel1.Height, 1.0, 500.0); // Do
the perspective calculations. Last value = max clipping depth

gluLookAt(Kamera.posX,Kamera.posY,Kamera.posZ,Fokus.posX,Fokus.posY,
Fokus.posZ,atasKam.posX,atasKam.posY,atasKam.posZ);

glMatrixMode(GL_MODELVIEW); // Return to the modelview matrix


end;

procedure TFormUtama.FormKeyPress(Sender: TObject; var Key: Char);


begin
case key of
#27:Self.Close; //exit app
//mode kamera
'z':ToolButton2.Click;
'k':ToolButton3.Click;
'l':ToolButton4.Click;
'g':ToolButton5.Click;
'e':ToolButton13.Click;
//Mode Transformasi
72

't':ToolButton7.Click;
'p':ToolButton8.Click;
'r':ToolButton9.Click;
's':ToolButton10.Click;
'd':ToolButton15.Click;
else
Exit;
end;

end;

procedure TFormUtama.sButton1Click(Sender: TObject);


var
i:integer;
ObjekBaru:TGeometri;
tinggi,sisi:Glfloat;
titikPusat:Ttitik3d;
begin
tinggi:=StrToFloat(sDecimalSpinEdit4.Text);
sisi:=StrToFloat(sDecimalSpinEdit5.Text);
titikPusat.posX:=StrToFloat(sDecimalSpinEdit1.Text);
titikPusat.posY:=StrToFloat(sDecimalSpinEdit2.Text);
titikPusat.posZ:=StrToFloat(sDecimalSpinEdit3.Text);

ObjekBaru:=nil;
ObjekBaru:=Tpiramid.create(tinggi,sisi,titikPusat);
DaftarGeometri.TambahGeometri(ObjekBaru);

sMemo1.Lines.Add(ObjekBaru.jenis);
for i:=0 to ObjekBaru.jumTitik do
begin
sMemo1.Lines.Add('Titik'+IntToStr(i)+' ('+
Format('%.2f',[objekBaru.titik[i].posX])+' '+
Format('%.2f',[objekBaru.titik[i].posY])+' '+
Format('%.2f',[objekBaru.titik[i].posZ])+')');
end;
end;

procedure TFormUtama.ranslasi1Click(Sender: TObject);


begin
TFormTranslasi.Create(self);
end;

procedure TFormUtama.sButton3Click(Sender: TObject);


var
ObjekBaru:TGeometri;
titikPusat:Ttitik3d;
begin
titikPusat.posX:=StrToFloat(sDecimalSpinEdit21.Text);
titikPusat.posY:=StrToFloat(sDecimalSpinEdit22.Text);
titikPusat.posZ:=StrToFloat(sDecimalSpinEdit23.Text);

ObjekBaru:=nil;
ObjekBaru:=Tkursi.Create(titikPusat);
DaftarGeometri.TambahGeometri(ObjekBaru);
end;

procedure TFormUtama.sButton5Click(Sender: TObject);


var sisi:Glfloat;
titikPusat:Ttitik3d;
objekBaru:Tgeometri;
begin
sisi:=StrToFloat(sDecimalSpinEdit18.Text);
titikPusat.posX:=StrToFloat(sDecimalSpinEdit6.Text);
titikPusat.posY:=StrToFloat(sDecimalSpinEdit7.Text);
73

titikPusat.posZ:=StrToFloat(sDecimalSpinEdit8.Text);

ObjekBaru:=nil;
ObjekBaru:=Tkubus.create(sisi,titikPusat);
DaftarGeometri.TambahGeometri(ObjekBaru);
end;

procedure TFormUtama.sButton7Click(Sender: TObject);


var titikPusat:Ttitik3d;
RAdius,tinggi:Glfloat;
objekbaru:TGeometri;
begin
titikPusat.posX:=StrToFloat(sDecimalSpinEdit9.Text);
titikPusat.posY:=StrToFloat(sDecimalSpinEdit10.Text);
titikPusat.posZ:=StrToFloat(sDecimalSpinEdit11.Text);
Radius:=StrToFloat(sDecimalSpinEdit20.Text);
tinggi:=StrToFloat(sDecimalSpinEdit19.Text);

ObjekBaru:=nil;
ObjekBaru:=TSilinder.Create(Radius,tinggi,titikPusat);
DaftarGeometri.TambahGeometri(ObjekBaru);
end;

procedure TFormUtama.Penskalaan1Click(Sender: TObject);


begin
TFormPenskalaan.Create(self);
end;

procedure TFormUtama.Rotasi1Click(Sender: TObject);


begin
TFormRotasi.Create(self);
end;

procedure TFormUtama.Panel1MouseDown(Sender: TObject; Button:


TMouseButton;
Shift: TShiftState; X, Y: Integer);
var indexObjek,index: integer;
item:Tgeometri;
begin
indexObjek:=DapatIndexObjek(X,Y);
if(button=mbLeft)then
begin
mouseTurun:=true;
for index:=0 to daftarGeometri.f.Count-1 do
begin
item:=daftarGeometri.f.Items[index];
if item.index=indexObjek-100 then
begin
item.Aktif:=true;
sMEmo1.Lines.Add(item.jenis);
end;
daftarGeometri.f.Items[index]:=item;
end;
end;

if(button=mbMiddle)then
begin
for index:=0 to daftarGeometri.f.Count-1 do
begin
item:=daftarGeometri.f.Items[index];
if item.index=indexObjek-100 then
begin
item.Aktif:=false;
sMEmo1.Lines.Add(item.jenis);
end;
74

daftarGeometri.f.Items[index]:=item;
end;
end;

if(Button=mbRight)then
begin
PopupMenu1.AutoPopup:=true;
PopupMenu1.Popup(X+FormUtama.Left+Panel1.Left,
Y+FormUTama.Top+Panel1.Top);
end;
end;

procedure TFormUtama.Panel1MouseMove(Sender: TObject; Shift: TShiftState;


X, Y: Integer);
var i,index:integer;
faktor,dDump:real;
item:Tgeometri;
uz:Ttitik3d;
begin
if modeTransformasi=8 then Panel1.Cursor:=crHandPoint
else Panel1.Cursor:=crCross;

if Y < 0 then y:=0;

Transform.ambilPos3d(X,Y,titikPro3D);
dx:=titikPro3D[1]-awalX;
dy:=titikPro3D[2]-awalY;
dz:=titikPro3D[3]-awalZ;
deltaX:=X-X2;
deltaY:=Y-Y2;
//###################################################################
if sComboBox2.ItemIndex=1 then
begin
if dx=0 then dx:=dz;
dy:=0;dz:=0;
end;
if sComboBox2.ItemIndex=2 then
begin
if dy=0 then dy:=dx;
dx:=0;dz:=0;
end;
if sComboBox2.ItemIndex=3 then
begin
if dz=0 then dz:=dx;
dx:=0;dy:=0;
end;
//################### SHEARING DENGAN MOUSE ##########################

if(mouseTurun=true)and(modeTransformasi=4)and(sComboBox2.itemIndex>0)then
begin
for index:=0 to DaftarGeometri.f.Count-1 do
begin
item:=DaftarGeometri.f.Items[index];
tempX:=item.titik[0].posX;
tempY:=item.titik[0].posY;
tempZ:=item.titik[0].posZ;

if item.Aktif=true then
begin
for i:=0 to item.jumTitik do
begin
Transform.nolkanTransformasi;
Transform.Translasi(-tempX,-tempY,-tempZ);
Transform.Transform(Item.Titik[i],item.Titik[i]);
Transform.nolkanTransformasi;
75

Transform.Shearing(scomboBox2.ItemIndex,0,deltaX/100,deltaX/100);
Transform.Transform(Item.Titik[i],item.Titik[i]);
Transform.nolkanTransformasi;
Transform.Translasi(tempX,tempY,tempZ);
Transform.Transform(Item.Titik[i],item.Titik[i]);
end;
end;
DaftarGeometri.f.Items[index]:=item;
end;
end;

//################ ZOOMING KAMERA ######################################


if(mouseTurun=true)and(modeTransformasi=5)then
begin
if deltaX > 0 then dDump:=0.1;
if deltaX < 0 then dDump:=-0.1;

JarakKamFoc.posX:=kamera.posX-fokus.posX;
JarakKamFoc.posY:=kamera.posY-fokus.posY;
JarakKamFoc.posZ:=kamera.posZ-fokus.posZ;
faktor:=PanjangVektor(JarakKamFoc);

Transform.nolkanTransformasi;
Transform.Translasi(dDump*JarakKamFoc.posX/faktor,
dDump*JarakKamFoc.posY/faktor,
dDump*JarakKamFoc.posZ/faktor);
Transform.Transform(kamera,kamera);
end;

//################### TRANSLASI DENGAN MOUSE ##########################


if(mouseTurun=true)and(modeTransformasi=1)then
begin
JarakKamFoc.posX:=kamera.posX-fokus.posX;
JarakKamFoc.posY:=kamera.posY-fokus.posY;
JarakKamFoc.posZ:=kamera.posZ-fokus.posZ;
faktor:=PanjangVektor(JarakKamFoc);

for index:=0 to DaftarGeometri.f.Count-1 do


begin
item:=DaftarGeometri.f.Items[index];
if item.Aktif=true then
begin
for i:=0 to item.jumTitik do
begin
Transform.nolkanTransformasi;
Transform.Translasi(dx*faktor,dy*faktor,dz*faktor);
Transform.Transform(Item.Titik[i],item.Titik[i]);
end;
end;
DaftarGeometri.f.Items[index]:=item;
end;
end;
//################### ROTASI DENGAN MOUSE ##########################
if(mouseTurun=true)and(modeTransformasi=3)then
begin
for index:=0 to DaftarGeometri.f.Count-1 do
begin
item:=DaftarGeometri.f.Items[index];
item:=FormUtama.DaftarGeometri.f.Items[index];
tempX:=item.titik[0].posX;
tempY:=item.titik[0].posY;
tempZ:=item.titik[0].posZ;
if item.Aktif=true then
begin
76

for i:=0 to item.jumTitik do


begin
//Transform.nolkanTransformasi;
//Transform.Translasi(-tempX,-tempY,-tempZ);
//Transform.Transform(Item.Titik[i],item.Titik[i]);
if sComboBox2.ItemIndex=0 then
begin
Transform.nolkanTransformasi;
Transform.Rotasi(deltaY,sumbuX.posX,sumbuX.posY,sumbuX.posZ);
Transform.Transform(Item.Titik[i],item.Titik[i]);
Transform.nolkanTransformasi;
Transform.Rotasi(deltaX,SumbuY.posX,sumbuY.posY,SumbuY.posZ);
Transform.Transform(Item.Titik[i],item.Titik[i]);
end;
Transform.nolkanTransformasi;
if sComboBox2.ItemIndex=1 then Transform.Rotasi(deltaX,1,0,-1);
if sComboBox2.ItemIndex=2 then Transform.Rotasi(deltaX,0,1,1);
if sComboBox2.ItemIndex=3 then Transform.Rotasi(deltaX,0,0,1);
Transform.Transform(Item.Titik[i],item.Titik[i]);
//Transform.nolkanTransformasi;
//Transform.Translasi(tempX,tempY,tempZ);
//Transform.Transform(Item.Titik[i],item.Titik[i]);
end;
end;
DaftarGeometri.f.Items[index]:=item;
end;

end;
//################### DILATASI DENGAN MOUSE ##########################
if(mouseTurun=true)and(modeTransformasi=2)then
begin
if deltaX > 0 then dDump:=0.01;
if deltaX < 0 then dDump:=-0.01;
if sComboBox2.ItemIndex=0 then begin
dx:=dDump;dy:=dDump;dz:=dDump;end;
if sComboBox2.ItemIndex=1 then begin dx:=dDump;dy:=0;dz:=0;end;
if sComboBox2.ItemIndex=2 then begin dx:=0;dy:=dDump;dz:=0;end;
if sComboBox2.ItemIndex=3 then begin dx:=0;dy:=0;dz:=dDump;end;

for index:=0 to DaftarGeometri.f.Count-1 do


begin
item:=DaftarGeometri.f.Items[index];
if item.Aktif=true then
begin
for i:=0 to item.jumTitik do
begin
Transform.nolkanTransformasi;
Transform.Translasi(-tempX,-tempY,-tempZ);
Transform.Transform(Item.Titik[i],item.Titik[i]);
Transform.nolkanTransformasi;
Transform.Penskalaan(1+dx,1+dy,1+dz,0,0,0);
Transform.Transform(Item.Titik[i],item.Titik[i]);
Transform.nolkanTransformasi;
Transform.Translasi(tempX,tempY,tempZ);
Transform.Transform(Item.Titik[i],item.Titik[i]);
end;
end;
DaftarGeometri.f.Items[index]:=item;
end;
end;

//################ ROTASI KAMERA ######################################


if(mouseTurun=true)and(modeTransformasi=6)then
begin
if deltaX > 0 then dDump:=1;
77

if deltaX < 0 then dDump:=-1;


//if sComboBox2.ItemIndex=0 then begin dx:=0;dy:=0;dz:=0;end;

Transform.nolkanTransformasi;
Transform.Translasi(-fokus.posX,-fokus.posY,-fokus.posZ);
Transform.Transform(kamera,kamera);
if sComboBox2.ItemIndex=0 then
begin
Transform.nolkanTransformasi;
Transform.Rotasi(deltaY/10,sumbuX.posX,SumbuX.posY,sumbuX.posZ);
Transform.Transform(Kamera,Kamera);
Transform.Transform(atasKam,atasKam);
Transform.Transform(sumbuY,sumbuY);

Transform.nolkanTransformasi;
Transform.Rotasi(deltaX/10,sumbuY.posX,sumbuY.posY,sumbuY.posZ);
Transform.Transform(Kamera,Kamera);
Transform.Transform(atasKam,atasKam);
Transform.Transform(sumbuX,sumbuX);
end;
if sComboBox2.ItemIndex=1 then
begin
Transform.nolkanTransformasi;
Transform.Rotasi(deltaX,sumbuX.posX,0,sumbuX.posZ);
Transform.Transform(Kamera,Kamera);
Transform.Transform(atasKam,atasKam);
Transform.Transform(sumbuY,sumbuY);
Transform.Transform(sumbuX,sumbuX);
end;
if sComboBox2.ItemIndex=2 then
begin
Transform.nolkanTransformasi;
Transform.Rotasi(deltaX,0,1,0);
Transform.Transform(Kamera,Kamera);
Transform.Transform(atasKam,atasKam);
Transform.Transform(sumbuX,sumbuX);
Transform.Transform(sumbuY,sumbuY);
end;
if sComboBox2.ItemIndex=3 then
begin
Transform.nolkanTransformasi;
Transform.Rotasi(deltaX,kamera.posX,kamera.posY,kamera.posZ);
Transform.Transform(atasKam,atasKam);
Transform.Transform(sumbuY,sumbuY);
Transform.Transform(sumbuX,sumbuX);
end;
Transform.nolkanTransformasi;
Transform.Translasi(fokus.posX,fokus.posY,fokus.posZ);
Transform.Transform(kamera,kamera);
end;
//################ ROTASI TITIK FOKUS KAMERA
################################
if(mouseTurun=true)and(modeTransformasi=7)then
begin
if deltaX > 0 then dDump:=1;
if deltaX < 0 then dDump:=-1;

Transform.nolkanTransformasi;
Transform.Translasi(-kamera.posX,-kamera.posY,-kamera.posZ);
Transform.Transform(fokus,fokus);
if sComboBox2.ItemIndex=0 then
begin
Transform.nolkanTransformasi;
Transform.Rotasi(deltaY,sumbuX.posX,SumbuX.posY,sumbuX.posZ);
78

Transform.Transform(Fokus,Fokus);
Transform.Transform(atasKam,atasKam);
Transform.Transform(sumbuY,sumbuY);
Transform.nolkanTransformasi;
Transform.Rotasi(deltaX,sumbuY.posX,SumbuY.posY,sumbuY.posZ);
Transform.Transform(Fokus,Fokus);
Transform.Transform(atasKam,atasKam);
Transform.Transform(sumbuX,sumbuX);
end;
if sComboBox2.ItemIndex=1 then
begin
Transform.nolkanTransformasi;
Transform.Rotasi(-deltaX,sumbuX.posX,0,sumbuX.posZ);
Transform.Transform(fokus,fokus);
Transform.Transform(atasKam,atasKam);
Transform.Transform(sumbuY,sumbuY);
Transform.Transform(sumbuX,sumbuX);
end;
if sComboBox2.ItemIndex=2 then
begin
Transform.nolkanTransformasi;
Transform.Rotasi(-deltaX,0,1,0);
Transform.Transform(fokus,fokus);
Transform.Transform(atasKam,atasKam);
Transform.Transform(sumbuX,sumbuX);
Transform.Transform(sumbuY,sumbuY);
end;
if sComboBox2.ItemIndex=3 then
begin
Transform.nolkanTransformasi;
Transform.Rotasi(-deltaX,fokus.posX,fokus.posY,fokus.posZ);
Transform.Transform(atasKam,atasKam);
Transform.Transform(sumbuY,sumbuY);
Transform.Transform(sumbuX,sumbuX);
end;
Transform.nolkanTransformasi;
Transform.Translasi(kamera.posX,kamera.posY,kamera.posZ);
Transform.Transform(fokus,fokus);
end;
//################ HAND KAMERA ######################################
if(mouseTurun=true)and(modeTransformasi=8)then
begin
Transform.nolkanTransformasi;
Transform.Translasi(dx,dy,dz);
Transform.Transform(kamera,kamera);
Transform.Transform(fokus,fokus);
end;
//################### MENAMPILKAN POSISI MOUSE ##########################
sStatusBar1.Panels[0].Text:='Posisi World: x='+Format('%-
.2f',[titikPro3D[1]])+
' y='+Format('%-.2f',[titikPro3D[2]])+
' z='+Format('%-.2f',[titikPro3D[3]]);
sStatusBar1.Panels[1].Text:='Posisi Layar: X='+IntToStr(x)+
' Y='+IntToStr(Y);

sDecimalSpinEdit12.Text:=Format('%.2f',[kamera.posX]);
sDecimalSpinEdit13.Text:=Format('%.2f',[kamera.posY]);
sDecimalSpinEdit14.Text:=Format('%.2f',[kamera.posZ]);

sDecimalSpinEdit15.Text:=Format('%.2f',[fokus.posX]);
sDecimalSpinEdit16.Text:=Format('%.2f',[fokus.posY]);
sDecimalSpinEdit17.Text:=Format('%.2f',[fokus.posZ]);

X2:=X;
Y2:=Y;
79

awalX:=titikPro3d[1];
awalY:=titikPro3d[2];
awalZ:=titikPro3d[3];
end;

procedure TFormUtama.Panel1MouseUp(Sender: TObject; Button: TMouseButton;


Shift: TShiftState; X, Y: Integer);
begin
MouseTurun:=false;
end;

procedure TFormUtama.sComboBox1Change(Sender: TObject);


begin
if sComboBox1.Text='Depan' then
begin
sDecimalSpinEdit12.Text:='0';sDecimalSpinEdit13.Text:='0';
sDecimalSpinEdit14.Text:='6';
Kamera.posX:=0;Kamera.posY:=0;Kamera.posZ:=6;
SumbuX.posX:=1;SumbuX.posY:=0;SumbuX.posZ:=0;
SumbuY.posX:=0;SumbuY.posY:=1;SumbuY.posZ:=0;
end;
if sComboBox1.Text='Belakang'then
begin
sDecimalSpinEdit12.Text:='0';sDecimalSpinEdit13.Text:='0';
sDecimalSpinEdit14.Text:='-6';
Kamera.posX:=0;Kamera.posY:=0;Kamera.posZ:=-6;
SumbuX.posX:=-1;SumbuX.posY:=0;SumbuX.posZ:=0;
SumbuY.posX:=0;SumbuY.posY:=1;SumbuY.posZ:=0;
end;
if sComboBox1.Text='Atas' then
begin
sDecimalSpinEdit12.Text:='0';sDecimalSpinEdit13.Text:='6';
sDecimalSpinEdit14.Text:=FloatToStr(0.01);
Kamera.posX:=0;Kamera.posY:=6;Kamera.posZ:=0.01;
SumbuX.posX:=1;SumbuX.posY:=0;SumbuX.posZ:=0;
SumbuY.posX:=0;SumbuY.posY:=0;SumbuY.posZ:=-1;

end;
if sComboBox1.text='Bawah'then
begin
sDecimalSpinEdit12.Text:='0';sDecimalSpinEdit13.Text:='-6';
sDecimalSpinEdit14.Text:=FloatToStr(0.01);
Kamera.posX:=0;Kamera.posY:=-6;Kamera.posZ:=0.01;
SumbuX.posX:=1;SumbuX.posY:=0;SumbuX.posZ:=0;
SumbuY.posX:=0;SumbuY.posY:=0;SumbuY.posZ:=1;
end;
if sComboBox1.Text='Kiri'then
begin
sDecimalSpinEdit12.Text:='6';sDecimalSpinEdit13.Text:='0';
sDecimalSpinEdit14.Text:='0';
Kamera.posX:=-6;Kamera.posY:=0;Kamera.posZ:=0;
SumbuX.posX:=0;SumbuX.posY:=0;SumbuX.posZ:=1;
SumbuY.posX:=0;SumbuY.posY:=1;SumbuY.posZ:=0;
end;
if sComboBox1.Text='Kanan'then
begin
sDecimalSpinEdit12.Text:='6';sDecimalSpinEdit13.Text:='0';
sDecimalSpinEdit14.Text:='0';
Kamera.posX:=6;Kamera.posY:=0;Kamera.posZ:=0;
SumbuX.posX:=0;SumbuX.posY:=0;SumbuX.posZ:=-6;
SumbuY.posX:=0;SumbuY.posY:=1;SumbuY.posZ:=0;
end;
end;
80

function TFormUTama.DapatIndexObjek(x, y: integer): integer;


var
objectsFound: integer;
viewportCoords: array [0..3] of integer;
selectBuffer: array[0..511] of cardinal;
lowestDepth: cardinal;
selectedObject: GLuint;
i: integer;
begin
ZeroMemory(@viewportCoords, sizeof(viewportCoords));
ZeroMemory(@selectBuffer, sizeof(selectBuffer));

glSelectBuffer(512, @selectBuffer);
glRenderMode(GL_SELECT);

glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity(); // mereset matriks proyeksi

glGetIntegerv(GL_VIEWPORT, @viewportCoords);
gluPickMatrix(x, viewportCoords[3]-y, 1, 1, @viewportCoords);
gluPerspective(45.0, Panel1.Width/Panel1.Height, 1.0, 1000.0);

gluLookAt(Kamera.posX,Kamera.posY,Kamera.posZ,Fokus.posX,Fokus.posY,
Fokus.posZ,atasKam.posX,atasKam.posY,atasKam.posZ);
glMatrixMode(GL_MODELVIEW); // kembali
ke model view matriks

glDraw; // menggambarkan kembali objek


ke daerah objek pinpoint

glMatrixMode(GL_PROJECTION); // mengembalikan matriks


proyeksi ke normal
glPopMatrix(); //berhenti
mempengaruhi matriks proyeksi
glMatrixMode(GL_MODELVIEW); //kembali model view matriks

objectsFound := glRenderMode(GL_RENDER); // kembali ke


render mode dan mendapatkan jumlah objek
if (objectsFound > 0) then
begin
sMemo1.Lines.Add('Index: '+IntToStr(selectBuffer[3]));
lowestDepth := selectBuffer[1];
selectedObject := selectBuffer[3];
for i := 1 to objectsFound - 1 do
begin
if (selectBuffer[(i * 4) + 1] < lowestDepth) then
begin
lowestDepth := selectBuffer[(i * 4) + 1];
selectedObject := selectBuffer[(i * 4) + 3];
end
end;
result := selectedObject;
exit;
end;
result :=-1;
end;

procedure TFormUtama.Hapus1Click(Sender: TObject);


var index,jumlahGeometri:integer;
item:Tgeometri;
begin
index:=0;
jumlahGeometri:=DaftarGeometri.f.Count;
81

repeat
item:=DaftarGeometri.f.Items[index];
if item.Aktif=true then
begin
DaftarGeometri.f.Delete(index);
jumlahGeometri:=DaftarGeometri.f.Count;
index:=-1;
end;
inc(index);
until(index=jumlahGeometri);
end;
procedure TFormUtama.ToolButton7Click(Sender: TObject);
begin
modeTransformasi:=1;
sStatusBar1.Panels[2].Text:='Mode: Translasi';
end;

procedure TFormUtama.ToolButton8Click(Sender: TObject);


begin
ModeTransformasi:=2;
sStatusBar1.Panels[2].Text:='Mode: Penskalaan';
end;

procedure TFormUtama.ToolButton9Click(Sender: TObject);


begin
modeTransformasi:=3;
sStatusBar1.Panels[2].Text:='Mode: Rotasi';
end;

procedure TFormUtama.sMemo1DblClick(Sender: TObject);


begin
sMemo1.Clear;
end;

procedure TFormUtama.sButton2Click(Sender: TObject);


var
ObjekBaru:TGeometri;
titikPusat:Ttitik3d;
begin
titikPusat.posX:=StrToFloat(sDecimalSpinEdit24.Text);
titikPusat.posY:=StrToFloat(sDecimalSpinEdit25.Text);
titikPusat.posZ:=StrToFloat(sDecimalSpinEdit26.Text);

ObjekBaru:=nil;
ObjekBaru:=Tmeja.Create(titikPusat);
DaftarGeometri.TambahGeometri(ObjekBaru);
end;

procedure TFormUtama.ToolButton2Click(Sender: TObject);


begin
modeTransformasi:=5;
sStatusBar1.Panels[2].Text:='Mode: Zoom';
end;

procedure TFormUtama.ToolButton10Click(Sender: TObject);


begin
ModeTransformasi:=4;
sStatusBar1.Panels[2].Text:='Mode: Shearing';
end;

procedure TFormUtama.ToolButton3Click(Sender: TObject);


begin
82

modeTransformasi:=6;
sStatusBar1.Panels[2].Text:='Mode: Rotasi Kamera';
end;

procedure TFormUtama.ToolButton4Click(Sender: TObject);


begin
modeTransformasi:=7;
sStatusBar1.Panels[2].Text:='Mode: Rotasi Fokus Kamera';
end;

procedure TFormUtama.ToolButton5Click(Sender: TObject);


begin
modeTransformasi:=8;
sStatusBar1.Panels[2].Text:='Mode: Geser Kamera';
end;

procedure TFormUtama.ToolButton6Click(Sender: TObject);


var item:Tgeometri;
index:integer;
begin
for index:=0 to DaftarGeometri.f.Count-1 do
begin
item:=DaftarGeometri.f.Items[index];
if item.Aktif=true then
begin
sudut:=arcCos(DotProduct(fokus,item.titik[0]));
fokus.posX:=item.titik[0].posX;
fokus.posY:=item.titik[0].posY;
fokus.posZ:=item.titik[0].posZ;
sDecimalSpinEdit15.Text:=Format('%.2f',[item.titik[0].posX]);
sDecimalSpinEdit16.Text:=Format('%.2f',[item.titik[0].posY]);
sDecimalSpinEdit17.Text:=Format('%.2f',[item.titik[0].posZ]);
exit;
end;
end;
end;

procedure TFormUtama.Shearing1Click(Sender: TObject);


begin
TFormShearing.Create(self);
end;

procedure TFormUtama.sComboBox2Change(Sender: TObject);


begin
sStatusBar1.Panels[3].Text:='Sumbu Putar/Arah Vektor: '+
sComboBox2.text;
end;

procedure TFormUtama.sButton4Click(Sender: TObject);


Var ObjekBaru:Tgeometri;
begin
if sOpenDialog1.execute then
begin
ObjekBaru:=nil;
ObjekBaru:=TOBJLoader.create(sOpenDialog1.FileName);
DaftarGeometri.TambahGeometri(ObjekBaru);
end;
end;

procedure TFormUtama.ToolButton13Click(Sender: TObject);


begin
sDecimalSpinEdit12.Text:='0';
sDecimalSpinEdit13.Text:='2';
sDecimalSpinEdit14.Text:='6';
sDecimalSpinEdit15.Text:='0';
83

sDecimalSpinEdit16.Text:='0';
sDecimalSpinEdit17.Text:='0';
Kamera.posX:=0;Kamera.posy:=2;Kamera.posZ:=6;
Fokus.posX:=0;Fokus.posy:=0;Fokus.posZ:=0;
atasKam.posX:=0;atasKam.posY:=1;atasKam.posZ:=0;
sumbuX.posX:=1;sumbuX.posY:=0;sumbuX.posZ:=0;
sumbuY.posX:=0;sumbuY.posY:=1;sumbuY.posZ:=0;
end;

procedure TFormUtama.ToolButton15Click(Sender: TObject);


begin
modeTransformasi:=0;
sStatusBar1.Panels[2].Text:='Mode: Awal';
end;

procedure TFormUtama.Hapus2Click(Sender: TObject);


begin
Hapus1.Click;
end;

procedure TFormUtama.ranslasi2Click(Sender: TObject);


begin
ranslasi1.Click;
end;

procedure TFormUtama.Penskalaan2Click(Sender: TObject);


begin
Penskalaan1.Click;
end;

procedure TFormUtama.Rotasi2Click(Sender: TObject);


begin
Rotasi1.Click;
end;

procedure TFormUtama.Shearing2Click(Sender: TObject);


begin
Shearing1.Click;
end;

procedure TFormUtama.Timer1Timer(Sender: TObject);


begin
sStatusBar1.Panels.Items[4].Text:='Framerate: '+IntToStr(FPSCount)+'
FPS';
FPSCount:=0;

end;

procedure TFormUtama.About1Click(Sender: TObject);


begin
TFormAbout.Create(self);
end;

procedure TFormUtama.sButton6Click(Sender: TObject);


var sudut1,sudut2:real;
begin
kamera.posX:=StrToFloat(sDecimalSpinEdit12.Text);
kamera.posY:=StrToFloat(sDecimalSpinEdit13.Text);
kamera.posZ:=StrToFloat(sDecimalSpinEdit14.Text);
fokus.posX:=StrToFloat(sDecimalSpinEdit15.Text);
fokus.posY:=StrToFloat(sDecimalSpinEdit16.Text);
fokus.posZ:=StrToFloat(sDecimalSpinEdit17.Text);

sudut1:=arcTan(kamera.posX/kamera.posZ)*180/PI;
84

sudut2:=arcTan(kamera.posY/sqrt(sqr(Kamera.posX)+sqr(kamera.posZ)))*180/P
I;
sMemo1.Lines.Add('Sudut= '+FloatToStr(sudut1));

Transform.nolkanTransformasi;
Transform.Rotasi(sudut1,0,1,0);
sumbuX.posX:=1;SumbuX.posY:=0;SumbuX.posZ:=0;
Transform.Transform(sumbuX,sumbuX);

Transform.nolkanTransformasi;
Transform.Rotasi(sudut2,sumbuX.posX,0,sumbuX.posZ);
sumbuY.posX:=0;SumbuY.posY:=1;SumbuY.posZ:=0;
Transform.Transform(sumbuY,sumbuY);
end;

procedure TFormUtama.SaveAsBMP1Click(Sender: TObject);


var
bmp: TBitmap;
i: Integer;
dest: Pointer;
begin
bmp := TBitmap.Create;
bmp.PixelFormat := pf24bit;
bmp.Width := Panel1.Width;
bmp.Height := Panel1.Height;
for i := 0 to Panel1.Height-1 do
begin
dest := bmp.ScanLine[(Panel1.Height-1)-i];
glReadPixels(0,i,Panel1.Width,1,GL_BGR,GL_UNSIGNED_BYTE,dest);
end;

if SavePictureDialog1.Execute then
bmp.SaveToFile(SavePictureDialog1.FileName);
bmp.Free;
end;

procedure TFormUtama.FormClose(Sender: TObject; var Action:


TCloseAction);
begin
if Application.MessageBox('Apakah Anda ingin
keluar?','Konfirmasi',MB_YESNO
or MB_ICONINFORMATION)=IDNO then Action:=caNone;
end;

end.

Vektor.pas
unit vektor;

interface
uses sysutils,geometri,OBJLoader;

function DotProduct(va,vb:Ttitik3d):real;
function CrossProduct(va,vb:Ttitik3d):Ttitik3d;
function BuatVektor(x,y,z:real):Ttitik3d;
function Normalisasi(va:Ttitik3d):Ttitik3d;
function PanjangVektor(va:Ttitik3d):real;

implementation

uses unitUtama;

function BuatVektor(x,y,z:real):Ttitik3d;
var va:Ttitik3d;
85

begin
va.posX:=x; va.posY:=y; va.posZ:=z;
result:=va;
end;

function PanjangVektor(va:Ttitik3d):real;
begin
Result:=abs(sqrt(va.posx*va.posx+va.posy*va.posy+va.posz*va.posz));
end;

function Normalisasi(va:Ttitik3d):Ttitik3d;
var l:real; v:Ttitik3d;
begin
l:=PanjangVektor(va);
if l=0 then exit
raise ERangeError.CreateFmt(
'Panjang Vektor = %f tidak dapat dinormalisasi',[l])
else
begin
v.posx:=va.posx/l;
v.posy:=va.posy/l;
v.posz:=va.posz/l;
result:=v;
end;
end;

function DotProduct(va,vb:Ttitik3d):real;
var s:real;
begin
s:=va.posx*vb.posx+va.posy*vb.posy+va.posz*vb.posz;
result:=s;
end;

function CrossProduct(va,vb:Ttitik3d):Ttitik3d;
var vs:Ttitik3d;
begin
vs.posx:=(va.posy*vb.posz)-(va.posz*vb.posy);
vs.posy:=(va.posz*vb.posx)-(va.posx*vb.posz);
vs.posz:=(va.posx*vb.posy)-(va.posy*vb.posx);
result:=vs;
end;

end.

unitPensklaan.pas
unit unitPenskalaan;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, sSkinProvider, sSkinManager, StdCtrls, sButton, sEdit,
sSpinEdit, sLabel,OpenGL,Geometri,Transformasi;

type
TFormPenskalaan = class(TForm)
sSkinManager1: TsSkinManager;
sSkinProvider1: TsSkinProvider;
sLabel1: TsLabel;
sLabel2: TsLabel;
sLabel3: TsLabel;
sDecimalSpinEdit1: TsDecimalSpinEdit;
sDecimalSpinEdit2: TsDecimalSpinEdit;
sDecimalSpinEdit3: TsDecimalSpinEdit;
86

sButton1: TsButton;
sButton2: TsButton;
sLabel4: TsLabel;
sLabel5: TsLabel;
sDecimalSpinEdit4: TsDecimalSpinEdit;
sDecimalSpinEdit5: TsDecimalSpinEdit;
sDecimalSpinEdit6: TsDecimalSpinEdit;
sLabel6: TsLabel;
sLabel7: TsLabel;
sLabel8: TsLabel;
procedure sButton2Click(Sender: TObject);
procedure sButton1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
Transform:TTransformasi;
public
{ Public declarations }
end;

var
FormPenskalaan: TFormPenskalaan;

implementation

uses unitUtama;

{$R *.dfm}

procedure TFormPenskalaan.sButton2Click(Sender: TObject);


begin
close;
end;

procedure TFormPenskalaan.sButton1Click(Sender: TObject);


var sx,sy,sz,xc,yc,zc,tempX,tempY,tempZ:GLFloat;
i,index:integer;
item:Tgeometri;
begin
sx:=StrToFloat(sDecimalSpinEdit1.text);
sy:=StrToFloat(sDecimalSpinEdit2.text);
sz:=StrToFloat(sDecimalSpinEdit3.text);
xc:=StrToFloat(sDecimalSpinEdit4.text);
yc:=StrToFloat(sDecimalSpinEdit5.text);
zc:=StrToFloat(sDecimalSpinEdit6.text);

//Transformasi penskalaan
for index:=0 to FormUtama.DaftarGeometri.f.Count-1 do
begin
item:=FormUtama.DaftarGeometri.f.Items[index];
tempX:=item.titik[0].posX;
tempY:=item.titik[0].posY;
tempZ:=item.titik[0].posZ;
if item.Aktif=true then
for i:=0 to item.jumTitik do
begin
//Ditranslasi terlebih dahulu ke titik origin
Transform.nolkanTransformasi;
Transform.Translasi(-tempX,-tempY,-tempZ);
Transform.Transform(item.Titik[i],item.Titik[i]);
//Di dilatasikan
Transform.nolkanTransformasi;
Transform.Penskalaan(sx,sy,sz,xc,yc,zc);
Transform.Transform(item.Titik[i],item.Titik[i]);
//dikembalikan ke titik semula
87

Transform.nolkanTransformasi;
Transform.Translasi(tempX,tempY,tempZ);
Transform.Transform(item.Titik[i],item.Titik[i]);
FormUtama.sMemo1.Lines.Add('Titik'+IntToStr(i)+' ('+
Format('%.2f',[item.titik[i].posX])+' '+
Format('%.2f',[item.titik[i].posY])+' '+
Format('%.2f',[item.titik[i].posZ])+')');
end;
FormUtama.DaftarGeometri.f.Items[index]:=item;
end;
end;

procedure TFormPenskalaan.FormCreate(Sender: TObject);


begin
Transform:=TTransformasi.Create;
Transform.NolkanTransformasi;
end;

end.

unitRotasi.pas
unit unitRotasi;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, sSkinProvider, sSkinManager, StdCtrls, sLabel, sButton, sEdit,
sSpinEdit,Transformasi,openGL, sComboBox,Geometri;

type
TFormRotasi = class(TForm)
sSkinManager1: TsSkinManager;
sSkinProvider1: TsSkinProvider;
sLabel1: TsLabel;
sLabel5: TsLabel;
sDecimalSpinEdit4: TsDecimalSpinEdit;
sButton1: TsButton;
sButton2: TsButton;
sDecimalSpinEdit1: TsDecimalSpinEdit;
sDecimalSpinEdit2: TsDecimalSpinEdit;
sDecimalSpinEdit3: TsDecimalSpinEdit;
sLabel2: TsLabel;
sLabel3: TsLabel;
sLabel4: TsLabel;
procedure sButton1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure sButton2Click(Sender: TObject);
private
{ Private declarations }
public
Transform:Ttransformasi;
{ Public declarations }
end;

var
FormRotasi: TFormRotasi;

implementation

uses unitUtama;

{$R *.dfm}
88

procedure TFormRotasi.sButton1Click(Sender: TObject);


var sudut,sumbuX,sumbuY,sumbuZ,tempX,tempY,tempZ:real;
i,index:integer;
item:Tgeometri;
begin
sudut:=StrToFloat(sDecimalSpinEdit4.Text);
sumbuX:=StrToFloat(sDecimalspinEdit1.Text);
sumbuY:=StrToFloat(sDecimalspinEdit2.Text);
sumbuZ:=StrToFloat(sDecimalspinEdit3.Text);

for index:=0 to FormUtama.DaftarGeometri.f.Count-1 do


begin
item:=FormUtama.DaftarGeometri.f.Items[index];
tempX:=item.titik[0].posX;
tempY:=item.titik[0].posY;
tempZ:=item.titik[0].posZ;

if item.Aktif=true then
for i:=0 to item.jumTitik do
begin
//Ditranslasi terlebih dahulu ke titik origin
Transform.nolkanTransformasi;
Transform.Translasi(-tempX,-tempY,-tempZ);
Transform.Transform(item.Titik[i],item.Titik[i]);
//Dirotasi
Transform.nolkanTransformasi;
Transform.Rotasi(sudut,sumbuX,sumbuY,sumbuZ);
Transform.Transform(item.Titik[i],item.Titik[i]);
//dikembalikan ke titik semula
Transform.nolkanTransformasi;
Transform.Translasi(tempX,tempY,tempZ);
Transform.Transform(item.Titik[i],item.Titik[i]);
FormUtama.sMemo1.Lines.Add('Titik'+IntToStr(i)+' ('+
Format('%.2f',[item.titik[i].posX])+' '+
Format('%.2f',[item.titik[i].posY])+' '+
Format('%.2f',[item.titik[i].posZ])+')');
end;
FormUtama.DaftarGeometri.f.Items[index]:=item;
end;
end;

procedure TFormRotasi.FormCreate(Sender: TObject);


begin
Transform:=TTransformasi.Create;
Transform.NolkanTransformasi;
end;

procedure TFormRotasi.sButton2Click(Sender: TObject);


begin
Close;
end;

end.

unitShearing.pas
unit unitShearing;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, StdCtrls, sButton, sEdit, sSpinEdit, sComboBox, sLabel,
sSkinProvider, sSkinManager, Geometri,Transformasi;
89

type
TFormShearing = class(TForm)
sSkinManager1: TsSkinManager;
sSkinProvider1: TsSkinProvider;
sLabel1: TsLabel;
sLabel2: TsLabel;
sLabel3: TsLabel;
sComboBox1: TsComboBox;
sDecimalSpinEdit1: TsDecimalSpinEdit;
sDecimalSpinEdit2: TsDecimalSpinEdit;
sButton1: TsButton;
sButton2: TsButton;
sDecimalSpinEdit3: TsDecimalSpinEdit;
sLabel4: TsLabel;
procedure sButton2Click(Sender: TObject);
procedure sButton1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Transform:TTransformasi;
end;

var
FormShearing: TFormShearing;

implementation

uses unitUtama;

{$R *.dfm}

procedure TFormShearing.sButton2Click(Sender: TObject);


begin
close;
end;

procedure TFormShearing.sButton1Click(Sender: TObject);


var sumbu:integer;
Ref,shear1,shear2:real;
i,index:integer;
item:Tgeometri;
begin
sumbu:=sComboBox1.itemindex;
ref:=StrToFloat(sDecimalSpinEdit1.text);
shear1:=StrToFloat(sDecimalSpinEdit2.text);
shear2:=StrToFloat(sDecimalSpinEdit3.text);

for index:=0 to FormUtama.DaftarGeometri.f.Count-1 do


begin
item:=FormUtama.DaftarGeometri.f.Items[index];
if item.Aktif=true then
for i:=0 to item.jumTitik do
begin
Transform.nolkanTransformasi;
Transform.Shearing(sumbu+1,ref,shear1,shear2);
Transform.Transform(item.Titik[i],item.Titik[i]);
FormUtama.sMemo1.Lines.Add('Titik'+IntToStr(i)+' ('+
Format('%.2f',[item.titik[i].posX])+' '+
Format('%.2f',[item.titik[i].posY])+' '+
Format('%.2f',[item.titik[i].posZ])+')');
end;
FormUtama.DaftarGeometri.f.Items[index]:=item;
90

end;

end;

procedure TFormShearing.FormCreate(Sender: TObject);


begin
Transform:=TTransformasi.Create;
Transform.NolkanTransformasi;
end;

end.

unitTranslasi.pas
unit unitTranslasi;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, StdCtrls, sCheckBox, sEdit, sSpinEdit, sLabel, sSkinProvider,
sSkinManager, sButton, sComboBox,openGL,Transformasi;

type
TFormTranslasi = class(TForm)
sSkinManager1: TsSkinManager;
sSkinProvider1: TsSkinProvider;
sLabel1: TsLabel;
sLabel2: TsLabel;
sLabel3: TsLabel;
sDecimalSpinEdit1: TsDecimalSpinEdit;
sDecimalSpinEdit2: TsDecimalSpinEdit;
sDecimalSpinEdit3: TsDecimalSpinEdit;
sButton1: TsButton;
sButton2: TsButton;
procedure sButton1Click(Sender: TObject);
procedure sButton2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
Transform:TTransformasi;
public
{ Public declarations }
end;

var
FormTranslasi: TFormTranslasi;

implementation

uses unitUtama, Geometri;

{$R *.dfm}

procedure TFormTranslasi.sButton1Click(Sender: TObject);


var x,y,z:GLFloat;
i,index:integer;
item:Tgeometri;
begin
x:=StrToFloat(sDecimalSpinEdit1.text);
y:=StrToFloat(sDecimalSpinEdit2.text);
z:=StrToFloat(sDecimalSpinEdit3.text);

for index:=0 to FormUtama.DaftarGeometri.f.Count-1 do


begin
91

item:=FormUtama.DaftarGeometri.f.Items[index];
if item.Aktif=true then
for i:=0 to item.jumTitik do
begin
Transform.nolkanTransformasi;
Transform.Translasi(x,y,z);
Transform.Transform(item.Titik[i],item.Titik[i]);
FormUtama.sMemo1.Lines.Add('Titik'+IntToStr(i)+' ('+
Format('%.2f',[item.titik[i].posX])+' '+
Format('%.2f',[item.titik[i].posY])+' '+
Format('%.2f',[item.titik[i].posZ])+')');
end;
FormUtama.DaftarGeometri.f.Items[index]:=item;
end;
end;

procedure TFormTranslasi.sButton2Click(Sender: TObject);


begin
close;
end;

procedure TFormTranslasi.FormCreate(Sender: TObject);


begin
Transform:=TTransformasi.Create;
Transform.NolkanTransformasi;
end;

end.

unitAbout.pas
unit unitAbout;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
Dialogs, ExtCtrls, StdCtrls, sSkinProvider, sSkinManager;

type
TFormAbout = class(TForm)
Image1: TImage;
Label1: TLabel;
Shape1: TShape;
Label2: TLabel;
Label3: TLabel;
private
{ Private declarations }
public
{ Public declarations }
end;

var
FormAbout: TFormAbout;

implementation

{$R *.dfm}

end.

Geometri.pas
unit Geometri;

interface
92

uses OpenGL,classes,SysUtils,Math,OBJloader;

type
Ttitik3d = record
posX,posY,posZ:GLFloat;
end;

TArrTitik3d=Array[1..8]of Ttitik3d;

Tgeometri = class(Tobject)
public
nama:String;
index:integer;
jenis:string;
pusat:Ttitik3d;
jumTitik:integer;
titik:array of Ttitik3d;
sudut:GLFloat;
Aktif:Boolean;
warna:array [0..3] of GLfloat;
procedure Gambar;Virtual;
end;

Tpiramid = class(TGeometri)
public
tinggi,sisi:GLFloat;
Constructor create(pTinggi,pSisi:GLfloat;titikPusat:Ttitik3d);
procedure Gambar;override;
end;

Tkubus = class(Tgeometri)
public
sisi:GLfloat;
constructor create(pSisi:GLFloat;titikPusat:Ttitik3d);
procedure Gambar;override;
end;

TSilinder = class(Tgeometri)
public
Radius,tinggi:GLfloat;
constructor Create(pRadius,pTinggi:GLfloat;titikPusat:Ttitik3d);
procedure Gambar;override;
end;

Tmeja = class(Tgeometri)
public
constructor Create(titikPusat:TTitik3d);
procedure Gambar;override;
end;

Tkursi = class(Tgeometri)
public
constructor Create(titikPusat:TTitik3d);
procedure Gambar;override;
end;

TOBJLoader = class(Tgeometri)
private
titikMin,titikMax:Ttitik3d;
procedure hitungMinMax(i:integer);
procedure gambarKotak;
public
m:Tmodel;
berkas:string;
93

constructor create(fileObj:string);
procedure Gambar;override;
end;

TDaftarGeometri=class(TObject)
public
f:Tlist;
constructor Create(Owner:Tcomponent);
destructor Destroy;override;
procedure TambahGeometri(var O:TGeometri);
procedure Gambar;
end;

TGrid = class(Tobject)
public
warna:array [0..3] of GLfloat;
procedure Gambar;
end;

implementation

uses unitUtama;

procedure buatTitik(titik:Ttitik3d);
begin
glVertex3f(titik.posX,titik.posY,titik.posZ);
end;

procedure buatSisi(titik1,titik2,titik3,titik4:Ttitik3d);
begin
buatTitik(titik1);buatTitik(titik2);
buatTitik(titik3);buatTitik(titik4);
end;

procedure buatKotak(titik1,titik2,titik3,titik4,titik5,titik6,
titik7,titik8:Ttitik3d);
begin
buatSisi(titik1,titik2,titik3,titik4);//Atas
buatSisi(titik5,titik6,titik7,titik8);//Bawah
buatSisi(titik1,titik2,titik6,titik5);//Depan
buatSisi(titik3,titik4,titik8,titik7);//Belakang
buatSisi(titik1,titik5,titik8,titik4);//Kiri
buatSisi(titik2,titik3,titik7,titik6);//Kanan
end;

procedure TGeometri.Gambar;
begin
end;

procedure Tgrid.Gambar;
var i:integer;
warna:array [0..3] of GLfloat;
begin
warna[0]:=0.0;
warna[2]:=0.0;
warna[1]:=0.0;
warna[3]:=0.0;
glMaterialfv(GL_FRONT, GL_DIFFUSE, @warna);
glPushMAtrix();
for i:=-10 to 10 do
begin
if i<>0 then
begin
glBegin(GL_LINES);
glVertex(i,0,-10);glVertex(i,0,10);
94

glEnd;
glBegin(GL_LINES);
glVertex(-10,0,i);glVertex(10,0,i);
glEnd;
end;
end;
glBegin(GL_LINES);
glVertex(-10,0,0);glVertex(0,0,0);
glVertex(0,0,-10);glVertex(0,0,0);
glEnd;

warna[0]:=0.0;warna[1]:=0.0;warna[2]:=1.0;warna[3]:=1.0;
glMaterialfv(GL_FRONT, GL_DIFFUSE, @warna);
glBegin(GL_LINES);
glVertex(0,0,10);glVertex(0,0,0);

warna[0]:=0.0;warna[1]:=1.0;warna[2]:=0.0;warna[3]:=1.0;
glMaterialfv(GL_FRONT, GL_DIFFUSE, @warna);
glVertex(0,10,0);glVertex(0,0,0);

warna[0]:=1.0;warna[1]:=0.0;warna[2]:=0.0;warna[3]:=1.0;
glMaterialfv(GL_FRONT, GL_DIFFUSE, @warna);
glVertex(10,0,0);glVertex(0,0,0);
glEnd;
glPopMatrix();
end;

constructor Tpiramid.create(pTinggi,pSisi:GLfloat;titikPusat:Ttitik3d);
var stghSisi:GLfloat;
begin
self.tinggi:=pTinggi;
self.sisi:=pSisi;
self.pusat:=titikPusat;
self.jenis:='Piramid';
jumTitik:=6;
setLength(titik,jumTitik+1);

stghSisi:=sisi/2;
//buat titik pusat awal
titik[0].posX:=pusat.posX;
titik[0].posY:=pusat.posY;
titik[0].posZ:=pusat.posZ;
//buat titik puncak (titik 1) awal
titik[1].posX:=pusat.posX;
titik[1].posY:=Pusat.posY+tinggi/2;
titik[1].posZ:=pusat.posZ;
//buat titik 2 awal
titik[2].posX:=pusat.posX-stghSisi;
titik[2].posY:=Pusat.posY-tinggi/2;
titik[2].posZ:=pusat.posZ+stghSisi;
//buat titik3 awal
titik[3].posX:=pusat.posX+stghSisi;
titik[3].posY:=Pusat.posY-tinggi/2;
titik[3].posZ:=pusat.posZ+stghSisi;
//buat titik 4 awal
titik[4].posX:=pusat.posX+stghSisi;
titik[4].posY:=Pusat.posY-tinggi/2;
titik[4].posZ:=pusat.posZ-stghSisi;
//buat titik 5 awal
titik[5].posX:=pusat.posX-stghSisi;
titik[5].posY:=Pusat.posY-tinggi/2;
titik[5].posZ:=pusat.posZ-stghSisi;
//buat titik 6 awal
titik[6].posX:=pusat.posX-stghSisi;
titik[6].posY:=Pusat.posY-tinggi/2;
95

titik[6].posZ:=pusat.posZ+stghSisi;
end;

procedure TPiramid.Gambar;
var i,j:integer;
begin
// RED GREEN BLUE ALPHA
warna[0]:=0.0;warna[1]:=0.5;warna[2]:=0.0;warna[3]:=1.0;
//Gambar highlight jika objek terpilih
if aktif=true then
begin
// RED GREEN BLUE ALPHA
warna[0]:=0.0;warna[1]:=1.0;warna[2]:=0.0;warna[3]:=1.0;
end;
glPushMAtrix();
for j:=0 to 1 do
begin
if j= 1 then
begin
glLineWidth(1.5);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
warna[0]:=0.0;warna[1]:=0.0;warna[2]:=0.0;
end;
glMaterialfv(GL_FRONT, GL_DIFFUSE, @warna);
//Gambar atas
glBegin(GL_TRIANGLE_FAN);
for i:=1 to 6 do
glVertex3f(titik[i].posX,titik[i].posY,titik[i].posZ);
glEnd;
//Gambar alas
glBegin(GL_QUADS);
for i:=2 to 5 do
glVertex3f(titik[i].posX,titik[i].posY,titik[i].posZ);
glEnd;
if j= 1 then
begin
glLineWidth(1.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
end;
end;
glPopMAtrix();
end;

constructor Tkubus.create(pSisi:GLFloat;titikPusat:Ttitik3d);
var stghSisi:GLfloat;
begin
self.sisi:=pSisi;
self.pusat:=titikPusat;
jumTitik:=8;
setLength(titik,jumTitik+1);
self.jenis:='Kubus';

stghSisi:=sisi/2;
//titik pusat
titik[0].posX:=pusat.posX;
titik[0].posY:=pusat.posY;
titik[0].posZ:=pusat.posZ;
//titik 1
self.titik[1].posX:=pusat.posX-StghSisi;
titik[1].posY:=pusat.posY-StghSisi;
titik[1].posZ:=pusat.posZ+StghSisi;
//titik 2
titik[2].posX:=pusat.posX+StghSisi;
titik[2].posY:=pusat.posY-StghSisi;
titik[2].posZ:=pusat.posZ+StghSisi;
96

//titik 3
titik[3].posX:=pusat.posX+StghSisi;
titik[3].posY:=pusat.posY-StghSisi;
titik[3].posZ:=pusat.posZ-StghSisi;
//titik 4
titik[4].posX:=pusat.posX-StghSisi;
titik[4].posY:=pusat.posY-StghSisi;
titik[4].posZ:=pusat.posZ-StghSisi;
//titik 5
titik[5].posX:=pusat.posX-StghSisi;
titik[5].posY:=pusat.posY+StghSisi;
titik[5].posZ:=pusat.posZ+StghSisi;
//titik 6
titik[6].posX:=pusat.posX+StghSisi;
titik[6].posY:=pusat.posY+StghSisi;
titik[6].posZ:=pusat.posZ+StghSisi;
//titik 7
titik[7].posX:=pusat.posX+StghSisi;
titik[7].posY:=pusat.posY+StghSisi;
titik[7].posZ:=pusat.posZ-StghSisi;
//titik 8
titik[8].posX:=pusat.posX-StghSisi;
titik[8].posY:=pusat.posY+StghSisi;
titik[8].posZ:=pusat.posZ-StghSisi;
end;

procedure Tkubus.Gambar;
var j:integer;
begin
// RED GREEN BLUE ALPHA
warna[0]:=0.0;warna[1]:=0.0;warna[2]:=0.5;warna[3]:=1.0;
//Gambar highlight jika objek terpilih
if aktif=true then
begin
// RED GREEN BLUE ALPHA
warna[0]:=0.0;warna[1]:=0.0;warna[2]:=1.0;warna[3]:=1.0;
end;
glPushMAtrix();
for j:=0 to 1 do
begin
if j= 1 then
begin
glLineWidth(1.5);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
warna[0]:=0.0;warna[1]:=0.0;warna[2]:=0.0;
end;
glMaterialfv(GL_FRONT, GL_DIFFUSE, @warna);
glBegin(GL_QUADS);
//Sisi Depan
glVertex3f(titik[1].posX,titik[1].posY,titik[1].posZ);
glVertex3f(titik[2].posX,titik[2].posY,titik[2].posZ);
glVertex3f(titik[6].posX,titik[6].posY,titik[6].posZ);
glVertex3f(titik[5].posX,titik[5].posY,titik[5].posZ);
//Sisi Belakang
glVertex3f(titik[4].posX,titik[4].posY,titik[4].posZ);
glVertex3f(titik[3].posX,titik[3].posY,titik[3].posZ);
glVertex3f(titik[7].posX,titik[7].posY,titik[7].posZ);
glVertex3f(titik[8].posX,titik[8].posY,titik[8].posZ);
//sisi kiri
glVertex3f(titik[4].posX,titik[4].posY,titik[4].posZ);
glVertex3f(titik[1].posX,titik[1].posY,titik[1].posZ);
glVertex3f(titik[5].posX,titik[5].posY,titik[5].posZ);
glVertex3f(titik[8].posX,titik[8].posY,titik[8].posZ);
//sisi kanan
glVertex3f(titik[2].posX,titik[2].posY,titik[2].posZ);
97

glVertex3f(titik[3].posX,titik[3].posY,titik[3].posZ);
glVertex3f(titik[7].posX,titik[7].posY,titik[7].posZ);
glVertex3f(titik[6].posX,titik[6].posY,titik[6].posZ);
//sisi atas
glVertex3f(titik[5].posX,titik[5].posY,titik[5].posZ);
glVertex3f(titik[6].posX,titik[6].posY,titik[6].posZ);
glVertex3f(titik[7].posX,titik[7].posY,titik[7].posZ);
glVertex3f(titik[8].posX,titik[8].posY,titik[8].posZ);
//sisi bawah
glVertex3f(titik[1].posX,titik[1].posY,titik[1].posZ);
glVertex3f(titik[2].posX,titik[2].posY,titik[2].posZ);
glVertex3f(titik[3].posX,titik[3].posY,titik[3].posZ);
glVertex3f(titik[4].posX,titik[4].posY,titik[4].posZ);
glEnd;
if j= 1 then
begin
glLineWidth(1.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
end;
end;
glPopMatrix;
end;

constructor
Tsilinder.Create(pRadius,pTinggi:GLfloat;titikPusat:Ttitik3d);
var i:integer;
sudut,totalSudut,stghTinggi:real;
begin
//mengeset sudut yang dibentuk tiap potongan
self.Radius:=pRadius;
Self.tinggi:=pTinggi;
self.pusat:=TitikPusat;
jumTitik:=32;
self.jenis:='Silinder';
setLength(titik,jumTitik+1);

totalSudut:=0;
sudut:=360/16;
stghTinggi:=tinggi/2;

//memberi nilai x,y,z pada titik yang telah dibuat


//titik 0 = titik pusat
Titik[0].posX:=Pusat.posX;
Titik[0].posY:=Pusat.posY;
Titik[0].posZ:=Pusat.posZ;
//titik 1-2*potongan
for i:=1 to 16 do
begin
totalSudut:=totalSudut+sudut;
titik[i].posX:=titik[0].posX+Cos(totalSudut*2*PI/360)*radius;
titik[i].posY:=titik[0].posY+stghTinggi;
titik[i].posZ:=titik[0].posZ+Sin(totalSudut*2*PI/360)*radius;
end;

for i:=17 to 32 do
begin
totalSudut:=totalSudut+sudut;
titik[i].posX:=titik[0].posX+Cos(totalSudut*2*PI/360)*radius;
titik[i].posY:=titik[0].posY-stghTinggi;
titik[i].posZ:=titik[0].posZ+Sin(totalSudut*2*PI/360)*radius;
end;
end;

procedure TSilinder.Gambar;
var i,j:integer;
98

begin
// RED GREEN BLUE ALPHA
warna[0]:=0.5;warna[1]:=0.0;warna[2]:=0.0;warna[3]:=1.0;
//Gambar highlight jika objek terpilih
if aktif=true then
begin
// RED GREEN BLUE ALPHA
warna[0]:=1.0;warna[1]:=0.0;warna[2]:=0.0;warna[3]:=1.0;
end;
glPushMAtrix();
for j:=0 to 1 do
begin
if j= 1 then
begin
glLineWidth(1.5);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
warna[0]:=0.0;warna[1]:=0.0;warna[2]:=0.0;
end;
glMaterialfv(GL_FRONT, GL_DIFFUSE, @warna);
//Tutup silinder
glBegin(GL_POLYGON);
for i:=1 to 16 do
begin
glVertex3f(titik[i].posX,titik[i].posY,titik[i].posZ);
end;
glEnd;

//alas silinder
glBegin(GL_POLYGON);
for i:=17 to 32 do
begin
glVertex3f(titik[i].posX,titik[i].posY,titik[i].posZ);
end;
glEnd;

//Badan silinder
i:=1;
glBegin(GL_QUAD_STRIP);
while i<=16 do
begin
glVertex3f(titik[i].posX,titik[i].posY,titik[i].posZ);
glVertex3f(titik[i+16].posX,titik[i+16].posY,titik[i+16].posZ);
i:=i+1;
end;
glVertex3f(titik[1].posX,titik[1].posY,titik[1].posZ);
glVertex3f(titik[17].posX,titik[17].posY,titik[17].posZ);
glEnd;
if j= 1 then
begin
glLineWidth(1.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
end;
end;
glPopMatrix;
end;

constructor Tmeja.Create(titikPusat:TTitik3d);
begin
self.pusat:=titikPusat;
jumTitik:=40;
self.jenis:='Meja';
setLength(titik,jumTitik+1);
//TITIK PUAT MEJA================================================
//titik pusat
99

titik[0].posX:=pusat.posX;
titik[0].posY:=pusat.posY;
titik[0].posZ:=pusat.posZ;
//BAGIAN ATAS MEJA===============================================
//titik 1
titik[1].posX:=pusat.posX-0.5;
titik[1].posY:=pusat.posY+0.4;
titik[1].posZ:=pusat.posZ+0.5;
//titik 2
titik[2].posX:=pusat.posX+0.5;
titik[2].posY:=pusat.posY+0.4;
titik[2].posZ:=pusat.posZ+0.5;
//titik 3
titik[3].posX:=pusat.posX+0.5;
titik[3].posY:=pusat.posY+0.4;
titik[3].posZ:=pusat.posZ-0.5;
//titik 4
titik[4].posX:=pusat.posX-0.5;
titik[4].posY:=pusat.posY+0.4;
titik[4].posZ:=pusat.posZ-0.5;
//titik 5
titik[5].posX:=pusat.posX-0.5;
titik[5].posY:=pusat.posY+0.5;
titik[5].posZ:=pusat.posZ+0.5;
//titik 6
titik[6].posX:=pusat.posX+0.5;
titik[6].posY:=pusat.posY+0.5;
titik[6].posZ:=pusat.posZ+0.5;
//titik 7
titik[7].posX:=pusat.posX+0.5;
titik[7].posY:=pusat.posY+0.5;
titik[7].posZ:=pusat.posZ-0.5;
//titik 8
titik[8].posX:=pusat.posX-0.5;
titik[8].posY:=pusat.posY+0.5;
titik[8].posZ:=pusat.posZ-0.5;
//KAKI MEJA BAGIAN DEPAN KIRI======================================
//titik 9
titik[9].posX:=pusat.posX-0.4;
titik[9].posY:=pusat.posY-0.5;
titik[9].posZ:=pusat.posZ+0.4;
//titik 10
titik[10].posX:=pusat.posX-0.3;
titik[10].posY:=pusat.posY-0.5;
titik[10].posZ:=pusat.posZ+0.4;
//titik 11
titik[11].posX:=pusat.posX-0.3;
titik[11].posY:=pusat.posY-0.5;
titik[11].posZ:=pusat.posZ+0.3;
//titik 12
titik[12].posX:=pusat.posX-0.4;
titik[12].posY:=pusat.posY-0.5;
titik[12].posZ:=pusat.posZ+0.3;
//titik 13
titik[13].posX:=pusat.posX-0.4;
titik[13].posY:=pusat.posY+0.4;
titik[13].posZ:=pusat.posZ+0.4;
//titik 14
titik[14].posX:=pusat.posX-0.3;
titik[14].posY:=pusat.posY+0.4;
titik[14].posZ:=pusat.posZ+0.4;
//titik 15
titik[15].posX:=pusat.posX-0.3;
titik[15].posY:=pusat.posY+0.4;
titik[15].posZ:=pusat.posZ+0.3;
100

//titik 16
titik[16].posX:=pusat.posX-0.4;
titik[16].posY:=pusat.posY+0.4;
titik[16].posZ:=pusat.posZ+0.3;
//KAKI MEJA BAGIAN DEPAN KANAN======================================
//titik 17
titik[17].posX:=pusat.posX+0.4;
titik[17].posY:=pusat.posY-0.5;
titik[17].posZ:=pusat.posZ+0.4;
//titik 18
titik[18].posX:=pusat.posX+0.3;
titik[18].posY:=pusat.posY-0.5;
titik[18].posZ:=pusat.posZ+0.4;
//titik 19
titik[19].posX:=pusat.posX+0.3;
titik[19].posY:=pusat.posY-0.5;
titik[19].posZ:=pusat.posZ+0.3;
//titik 20
titik[20].posX:=pusat.posX+0.4;
titik[20].posY:=pusat.posY-0.5;
titik[20].posZ:=pusat.posZ+0.3;
//titik 21
titik[21].posX:=pusat.posX+0.4;
titik[21].posY:=pusat.posY+0.4;
titik[21].posZ:=pusat.posZ+0.4;
//titik 22
titik[22].posX:=pusat.posX+0.3;
titik[22].posY:=pusat.posY+0.4;
titik[22].posZ:=pusat.posZ+0.4;
//titik 23
titik[23].posX:=pusat.posX+0.3;
titik[23].posY:=pusat.posY+0.4;
titik[23].posZ:=pusat.posZ+0.3;
//titik 24
titik[24].posX:=pusat.posX+0.4;
titik[24].posY:=pusat.posY+0.4;
titik[24].posZ:=pusat.posZ+0.3;
//KAKI MEJA BAGIAN BELAKANG
KIRI======================================
//titik 25
titik[25].posX:=pusat.posX-0.4;
titik[25].posY:=pusat.posY-0.5;
titik[25].posZ:=pusat.posZ-0.4;
//titik 26
titik[26].posX:=pusat.posX-0.3;
titik[26].posY:=pusat.posY-0.5;
titik[26].posZ:=pusat.posZ-0.4;
//titik 27
titik[27].posX:=pusat.posX-0.3;
titik[27].posY:=pusat.posY-0.5;
titik[27].posZ:=pusat.posZ-0.3;
//titik 28
titik[28].posX:=pusat.posX-0.4;
titik[28].posY:=pusat.posY-0.5;
titik[28].posZ:=pusat.posZ-0.3;
//titik 29
titik[29].posX:=pusat.posX-0.4;
titik[29].posY:=pusat.posY+0.4;
titik[29].posZ:=pusat.posZ-0.4;
//titik 30
titik[30].posX:=pusat.posX-0.3;
titik[30].posY:=pusat.posY+0.4;
titik[30].posZ:=pusat.posZ-0.4;
//titik 31
titik[31].posX:=pusat.posX-0.3;
101

titik[31].posY:=pusat.posY+0.4;
titik[31].posZ:=pusat.posZ-0.3;
//titik 32
titik[32].posX:=pusat.posX-0.4;
titik[32].posY:=pusat.posY+0.4;
titik[32].posZ:=pusat.posZ-0.3;
//KAKI MEJA BAGIAN BELAKANG
KANAN======================================
//titik 33
titik[33].posX:=pusat.posX+0.4;
titik[33].posY:=pusat.posY-0.5;
titik[33].posZ:=pusat.posZ-0.4;
//titik 34
titik[34].posX:=pusat.posX+0.3;
titik[34].posY:=pusat.posY-0.5;
titik[34].posZ:=pusat.posZ-0.4;
//titik 35
titik[35].posX:=pusat.posX+0.3;
titik[35].posY:=pusat.posY-0.5;
titik[35].posZ:=pusat.posZ-0.3;
//titik 36
titik[36].posX:=pusat.posX+0.4;
titik[36].posY:=pusat.posY-0.5;
titik[36].posZ:=pusat.posZ-0.3;
//titik 37
titik[37].posX:=pusat.posX+0.4;
titik[37].posY:=pusat.posY+0.4;
titik[37].posZ:=pusat.posZ-0.4;
//titik 38
titik[38].posX:=pusat.posX+0.3;
titik[38].posY:=pusat.posY+0.4;
titik[38].posZ:=pusat.posZ-0.4;
//titik 39
titik[39].posX:=pusat.posX+0.3;
titik[39].posY:=pusat.posY+0.4;
titik[39].posZ:=pusat.posZ-0.3;
//titik 40
titik[40].posX:=pusat.posX+0.4;
titik[40].posY:=pusat.posY+0.4;
titik[40].posZ:=pusat.posZ-0.3;
end;

procedure Tmeja.Gambar;
var j:integer;
begin
// RED GREEN BLUE ALPHA
warna[0]:=0.0;warna[1]:=0.5;warna[2]:=0.5;warna[3]:=1.0;
//Gambar highlight jika objek terpilih
if aktif=true then
begin
// RED GREEN BLUE ALPHA
warna[0]:=0.0;warna[1]:=1.0;warna[2]:=1.0;warna[3]:=1.0;
end;

glPushMAtrix();
for j:=0 to 1 do
begin
if j= 1 then
begin
glLineWidth(1.5);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
warna[0]:=0.0;warna[1]:=0.0;warna[2]:=0.0;
end;
glMaterialfv(GL_FRONT, GL_DIFFUSE, @warna);
//Gambar meja bagian atas
102

glBegin(GL_QUADS);
buatKotak(titik[1],titik[2],titik[3],titik[4],titik[5],
titik[6],titik[7],titik[8]);
glEnd;
//Gambar Kaki meja kiri depan
glBegin(GL_QUADS);
buatKotak(titik[9],titik[10],titik[11],titik[12],titik[13],
titik[14],titik[15],titik[16]);
glEnd;
//Gambar Kaki meja kanan depan
glBegin(GL_QUADS);
buatKotak(titik[17],titik[18],titik[19],titik[20],titik[21],
titik[22],titik[23],titik[24]);
glEnd;
//Gambar Kaki meja kiri belakang
glBegin(GL_QUADS);
buatKotak(titik[25],titik[26],titik[27],titik[28],titik[29],
titik[30],titik[31],titik[32]);
glEnd;
//Gambar Kaki meja kanan belakang
glBegin(GL_QUADS);
buatKotak(titik[33],titik[34],titik[35],titik[36],titik[37],
titik[38],titik[39],titik[40]);
glEnd;
if j= 1 then
begin
glLineWidth(1.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
end;
end;
glPopMatrix;
end;

constructor Tkursi.Create(titikPusat:TTitik3d);
begin
self.pusat:=titikPusat;
jumTitik:=48;
self.jenis:='Kursi';
setLength(titik,jumTitik+1);
//TITIK PUSAT KURSI================================================
//titik pusat
titik[0].posX:=pusat.posX;
titik[0].posY:=pusat.posY;
titik[0].posZ:=pusat.posZ;
//BAGIAN ATAS KURSI===============================================
//titik 1
titik[1].posX:=pusat.posX-0.5;
titik[1].posY:=pusat.posY-0.1;
titik[1].posZ:=pusat.posZ+0.5;
//titik 2
titik[2].posX:=pusat.posX+0.5;
titik[2].posY:=pusat.posY-0.1;
titik[2].posZ:=pusat.posZ+0.5;
//titik 3
titik[3].posX:=pusat.posX+0.5;
titik[3].posY:=pusat.posY-0.1;
titik[3].posZ:=pusat.posZ-0.5;
//titik 4
titik[4].posX:=pusat.posX-0.5;
titik[4].posY:=pusat.posY-0.1;
titik[4].posZ:=pusat.posZ-0.5;
//titik 5
titik[5].posX:=pusat.posX-0.5;
titik[5].posY:=pusat.posY+0.0;
titik[5].posZ:=pusat.posZ+0.5;
103

//titik 6
titik[6].posX:=pusat.posX+0.5;
titik[6].posY:=pusat.posY+0.0;
titik[6].posZ:=pusat.posZ+0.5;
//titik 7
titik[7].posX:=pusat.posX+0.5;
titik[7].posY:=pusat.posY+0.0;
titik[7].posZ:=pusat.posZ-0.5;
//titik 8
titik[8].posX:=pusat.posX-0.5;
titik[8].posY:=pusat.posY+0.0;
titik[8].posZ:=pusat.posZ-0.5;
//KAKI KURSI BAGIAN DEPAN KIRI======================================
//titik 9
titik[9].posX:=pusat.posX-0.4;
titik[9].posY:=pusat.posY-0.5;
titik[9].posZ:=pusat.posZ+0.4;
//titik 10
titik[10].posX:=pusat.posX-0.3;
titik[10].posY:=pusat.posY-0.5;
titik[10].posZ:=pusat.posZ+0.4;
//titik 11
titik[11].posX:=pusat.posX-0.3;
titik[11].posY:=pusat.posY-0.5;
titik[11].posZ:=pusat.posZ+0.3;
//titik 12
titik[12].posX:=pusat.posX-0.4;
titik[12].posY:=pusat.posY-0.5;
titik[12].posZ:=pusat.posZ+0.3;
//titik 13
titik[13].posX:=pusat.posX-0.4;
titik[13].posY:=pusat.posY-0.1;
titik[13].posZ:=pusat.posZ+0.4;
//titik 14
titik[14].posX:=pusat.posX-0.3;
titik[14].posY:=pusat.posY-0.1;
titik[14].posZ:=pusat.posZ+0.4;
//titik 15
titik[15].posX:=pusat.posX-0.3;
titik[15].posY:=pusat.posY-0.1;
titik[15].posZ:=pusat.posZ+0.3;
//titik 16
titik[16].posX:=pusat.posX-0.4;
titik[16].posY:=pusat.posY-0.1;
titik[16].posZ:=pusat.posZ+0.3;
//KAKI MEJA BAGIAN DEPAN KANAN======================================
//titik 17
titik[17].posX:=pusat.posX+0.4;
titik[17].posY:=pusat.posY-0.5;
titik[17].posZ:=pusat.posZ+0.4;
//titik 18
titik[18].posX:=pusat.posX+0.3;
titik[18].posY:=pusat.posY-0.5;
titik[18].posZ:=pusat.posZ+0.4;
//titik 19
titik[19].posX:=pusat.posX+0.3;
titik[19].posY:=pusat.posY-0.5;
titik[19].posZ:=pusat.posZ+0.3;
//titik 20
titik[20].posX:=pusat.posX+0.4;
titik[20].posY:=pusat.posY-0.5;
titik[20].posZ:=pusat.posZ+0.3;
//titik 21
titik[21].posX:=pusat.posX+0.4;
titik[21].posY:=pusat.posY-0.1;
104

titik[21].posZ:=pusat.posZ+0.4;
//titik 22
titik[22].posX:=pusat.posX+0.3;
titik[22].posY:=pusat.posY-0.1;
titik[22].posZ:=pusat.posZ+0.4;
//titik 23
titik[23].posX:=pusat.posX+0.3;
titik[23].posY:=pusat.posY-0.1;
titik[23].posZ:=pusat.posZ+0.3;
//titik 24
titik[24].posX:=pusat.posX+0.4;
titik[24].posY:=pusat.posY-0.1;
titik[24].posZ:=pusat.posZ+0.3;
//KAKI KURSI BAGIAN BELAKANG
KIRI======================================
//titik 25
titik[25].posX:=pusat.posX-0.4;
titik[25].posY:=pusat.posY-0.5;
titik[25].posZ:=pusat.posZ-0.4;
//titik 26
titik[26].posX:=pusat.posX-0.3;
titik[26].posY:=pusat.posY-0.5;
titik[26].posZ:=pusat.posZ-0.4;
//titik 27
titik[27].posX:=pusat.posX-0.3;
titik[27].posY:=pusat.posY-0.5;
titik[27].posZ:=pusat.posZ-0.3;
//titik 28
titik[28].posX:=pusat.posX-0.4;
titik[28].posY:=pusat.posY-0.5;
titik[28].posZ:=pusat.posZ-0.3;
//titik 29
titik[29].posX:=pusat.posX-0.4;
titik[29].posY:=pusat.posY-0.1;
titik[29].posZ:=pusat.posZ-0.4;
//titik 30
titik[30].posX:=pusat.posX-0.3;
titik[30].posY:=pusat.posY-0.1;
titik[30].posZ:=pusat.posZ-0.4;
//titik 31
titik[31].posX:=pusat.posX-0.3;
titik[31].posY:=pusat.posY-0.1;
titik[31].posZ:=pusat.posZ-0.3;
//titik 32
titik[32].posX:=pusat.posX-0.4;
titik[32].posY:=pusat.posY-0.1;
titik[32].posZ:=pusat.posZ-0.3;
//KAKI KURSI BAGIAN BELAKANG
KANAN======================================
//titik 33
titik[33].posX:=pusat.posX+0.4;
titik[33].posY:=pusat.posY-0.5;
titik[33].posZ:=pusat.posZ-0.4;
//titik 34
titik[34].posX:=pusat.posX+0.3;
titik[34].posY:=pusat.posY-0.5;
titik[34].posZ:=pusat.posZ-0.4;
//titik 35
titik[35].posX:=pusat.posX+0.3;
titik[35].posY:=pusat.posY-0.5;
titik[35].posZ:=pusat.posZ-0.3;
//titik 36
titik[36].posX:=pusat.posX+0.4;
titik[36].posY:=pusat.posY-0.5;
titik[36].posZ:=pusat.posZ-0.3;
105

//titik 37
titik[37].posX:=pusat.posX+0.4;
titik[37].posY:=pusat.posY-0.1;
titik[37].posZ:=pusat.posZ-0.4;
//titik 38
titik[38].posX:=pusat.posX+0.3;
titik[38].posY:=pusat.posY-0.1;
titik[38].posZ:=pusat.posZ-0.4;
//titik 39
titik[39].posX:=pusat.posX+0.3;
titik[39].posY:=pusat.posY-0.1;
titik[39].posZ:=pusat.posZ-0.3;
//titik 40
titik[40].posX:=pusat.posX+0.4;
titik[40].posY:=pusat.posY-0.1;
titik[40].posZ:=pusat.posZ-0.3;
//BAGIAN SANDARAN
KURSI===============================================
//titik 41
titik[41].posX:=pusat.posX-0.5;
titik[41].posY:=pusat.posY-0.0;
titik[41].posZ:=pusat.posZ-0.4;
//titik 42
titik[42].posX:=pusat.posX+0.5;
titik[42].posY:=pusat.posY-0.0;
titik[42].posZ:=pusat.posZ-0.4;
//titik 43
titik[43].posX:=pusat.posX+0.5;
titik[43].posY:=pusat.posY-0.0;
titik[43].posZ:=pusat.posZ-0.5;
//titik 44
titik[44].posX:=pusat.posX-0.5;
titik[44].posY:=pusat.posY-0.0;
titik[44].posZ:=pusat.posZ-0.5;
//titik 45
titik[45].posX:=pusat.posX-0.5;
titik[45].posY:=pusat.posY+0.5;
titik[45].posZ:=pusat.posZ-0.4;
//titik 46
titik[46].posX:=pusat.posX+0.5;
titik[46].posY:=pusat.posY+0.5;
titik[46].posZ:=pusat.posZ-0.4;
//titik 47
titik[47].posX:=pusat.posX+0.5;
titik[47].posY:=pusat.posY+0.5;
titik[47].posZ:=pusat.posZ-0.5;
//titik 48
titik[48].posX:=pusat.posX-0.5;
titik[48].posY:=pusat.posY+0.5;
titik[48].posZ:=pusat.posZ-0.5;
end;

procedure Tkursi.Gambar;
var j:integer;
begin
// RED GREEN BLUE ALPHA
warna[0]:=0.7;warna[1]:=0.0;warna[2]:=0.5;warna[3]:=1.0;
//Gambar highlight jika objek terpilih
if aktif=true then
begin
// RED GREEN BLUE ALPHA
warna[0]:=1.0;warna[1]:=0.0;warna[2]:=1.0;warna[3]:=1.0;
end;

glPushMAtrix();
106

for j:=0 to 1 do
begin
if j= 1 then
begin
glLineWidth(1.5);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
warna[0]:=0.0;warna[1]:=0.0;warna[2]:=0.0;
end;
glMaterialfv(GL_FRONT, GL_DIFFUSE, @warna);
//Gambar kursi bagian atas
glBegin(GL_QUADS);
buatKotak(titik[1],titik[2],titik[3],titik[4],titik[5],
titik[6],titik[7],titik[8]);
glEnd;
//Gambar Kaki kursi kiri depan
glBegin(GL_QUADS);
buatKotak(titik[9],titik[10],titik[11],titik[12],titik[13],
titik[14],titik[15],titik[16]);
glEnd;
//Gambar Kaki kursi kanan depan
glBegin(GL_QUADS);
buatKotak(titik[17],titik[18],titik[19],titik[20],titik[21],
titik[22],titik[23],titik[24]);
glEnd;
//Gambar Kaki kursi kiri belakang
glBegin(GL_QUADS);
buatKotak(titik[25],titik[26],titik[27],titik[28],titik[29],
titik[30],titik[31],titik[32]);
glEnd;
//Gambar Kaki kursi kanan belakang
glBegin(GL_QUADS);
buatKotak(titik[33],titik[34],titik[35],titik[36],titik[37],
titik[38],titik[39],titik[40]);
glEnd;
//Gambar sandaran kursi
glBegin(GL_QUADS);
buatKotak(titik[41],titik[42],titik[43],titik[44],titik[45],
titik[46],titik[47],titik[48]);
glend;

if j= 1 then
begin
glLineWidth(1.0);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
end;
end;
glPopMatrix;

end;

constructor TDaftarGeometri.Create(Owner:Tcomponent);
begin
f:=TList.Create;
end;

destructor TDaftarGeometri.Destroy;
begin
f.Free;
end;

procedure TDaftarGeometri.TambahGeometri(var O:TGeometri);


var item:TGeometri;i:integer;
begin
i:=f.Add(O);
FormUtama.sMemo1.Lines.add('Index Objek: '+IntToStr(i));
107

item:=f.Items[i];
item.index:=i;
f.Items[i]:=item;
end;

procedure TDaftarGeometri.Gambar;
var index:integer;
item:Tgeometri;
begin
for index:=0 to f.Count-1 do
begin
item:=f.Items[index];
glLoadName(item.index+100);
item.Gambar;
glEnd();
end;
end;

Constructor TOBJLoader.create(fileObj:string);
var i:integer;
begin
berkas:=fileObj;
m:=LoadModel(berkas);
self.jenis:='OBJ';
jumTitik:=m.Vertices;
setLength(titik,jumTitik+1);

for i:=0 to m.Vertices do


begin
titik[i].posX:=m.vertex[i].X;
titik[i].posY:=m.vertex[i].Y;
titik[i].posZ:=m.vertex[i].Z;
end;
end;
procedure TOBJLoader.hitungMinMax(i:integer);
begin
if titik[i].posX>titikMax.posX then titikMax.posX:=titik[i].posX;
if titik[i].posY>titikMax.posY then titikMax.posY:=titik[i].posY;
if titik[i].posZ>titikMax.posZ then titikMax.posZ:=titik[i].posZ;
if titik[i].posX<titikMin.posX then titikMin.posX:=titik[i].posX;
if titik[i].posY<titikMin.posY then titikMin.posY:=titik[i].posY;
if titik[i].posZ<titikMin.posZ then titikMin.posZ:=titik[i].posZ;
end;

procedure TOBJLoader.gambarKotak;
begin
// RED GREEN BLUE ALPHA
warna[0]:=1.0;warna[1]:=1.0;warna[2]:=1.0;warna[3]:=1.0;
glMaterialfv(GL_FRONT, GL_DIFFUSE, @warna);
glBegin(GL_QUADS);
//Sisi Depan
glVertex3f(titikMin.posX,titikMin.posY,titikMax.posZ);
glVertex3f(titikMax.posX,titikMin.posY,titikMax.posZ);
glVertex3f(titikMax.posX,titikMax.posY,titikMax.posZ);
glVertex3f(titikMin.posX,titikMax.posY,titikMAx.posZ);
//Sisi Belakang
glVertex3f(titikMin.posX,titikmin.posY,titikmin.posZ);
glVertex3f(titikMax.posX,titikMin.posY,titikMin.posZ);
glVertex3f(titikMax.posX,titikMax.posY,titikMin.posZ);
glVertex3f(titikMin.posX,titikMax.posY,titikMin.posZ);
//sisi kiri
glVertex3f(titikMin.posX,titikmin.posY,titikMin.posZ);
glVertex3f(titikMin.posX,titikMin.posY,titikMax.posZ);
glVertex3f(titikMin.posX,titikMax.posY,titikMax.posZ);
glVertex3f(titikMin.posX,titikMax.posY,titikMin.posZ);
108

//sisi kanan
glVertex3f(titikMax.posX,titikmin.posY,titikMin.posZ);
glVertex3f(titikMax.posX,titikMin.posY,titikMax.posZ);
glVertex3f(titikMax.posX,titikMax.posY,titikMax.posZ);
glVertex3f(titikMax.posX,titikMax.posY,titikMin.posZ);
//sisi atas
glVertex3f(titikMin.posX,titikMax.posY,titikMax.posZ);
glVertex3f(titikMax.posX,titikMax.posY,titikMax.posZ);
glVertex3f(titikMax.posX,titikMax.posY,titikMin.posZ);
glVertex3f(titikMin.posX,titikMax.posY,titikMin.posZ);
//sisi bawah
glVertex3f(titikMin.posX,titikMin.posY,titikMax.posZ);
glVertex3f(titikMax.posX,titikMin.posY,titikMax.posZ);
glVertex3f(titikMax.posX,titikMin.posY,titikMin.posZ);
glVertex3f(titikMin.posX,titikMin.posY,titikMin.posZ);
glEnd;
end;

procedure TOBJLoader.Gambar;
var i:integer;
begin
for i:=0 to m.vertices do
begin
hitungMinMax(i);
m.Vertex[i].X:=titik[i].posX;
m.Vertex[i].Y:=titik[i].posY;
m.Vertex[i].Z:=titik[i].posZ;
end;
DrawModel(m);
if self.Aktif=true then
begin
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
self.gambarKotak;
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
self.titikMin.posX:=titik[0].posX;
self.titikMin.posY:=titik[0].posY;
self.titikMin.posZ:=titik[0].posZ;
self.titikMax.posX:=titik[0].posX;;
self.titikMax.posY:=titik[0].posY;
self.titikMax.posZ:=titik[0].posZ;
end;
end;

end.

Transformasi.pas
unit Transformasi;
interface
uses OpenGL,Geometri,vektor,Math,classes,SysUtils,OBJLoader;

Type
Matriks4x4=array[0..3,0..3] of double;
MAtriks1x4=array[0..3] of double;
TArTitik3D=array[1..3] of Double;

TTransformasi = class(TObject)
private
Matriks:MAtriks4x4;
procedure PerkalianMatriks(Matriks1,Matriks2:Matriks4x4;
var Matriks3:Matriks4x4);
public
procedure MatriksIdentitas(var m:Matriks4x4);
procedure Translasi(x,y,z:real);
procedure Penskalaan(sx,sy,sz,xc,yc,zc:real);
109

Procedure Rotasi(sudut:real;xr,yr,zr:real);
Procedure Shearing(sumbu:integer;ref,shear1,shear2:real);
procedure Transform(P:Ttitik3d;var Q:TTitik3d);
procedure nolkanTransformasi;
procedure ambilPos3d(X,Y:integer;var titik:TArTitik3d);
end;

implementation

uses unitUtama;

procedure TTransformasi.MatriksIdentitas(var m:Matriks4x4);


begin
m[0,0]:=1;m[0,1]:=0;m[0,2]:=0;m[0,3]:=0;
m[1,0]:=0;m[1,1]:=1;m[1,2]:=0;m[1,3]:=0;
m[2,0]:=0;m[2,1]:=0;m[2,2]:=1;m[2,3]:=0;
m[3,0]:=0;m[3,1]:=0;m[3,2]:=0;m[3,3]:=1;
end;

procedure TTransformasi.PerkalianMatriks(Matriks1,Matriks2:Matriks4x4;
var Matriks3:Matriks4x4);
var
baris,kolom:byte;
matriksTemp:Matriks4x4;
begin
for baris:=0 to 3 do
begin
for kolom:=0 to 3 do
begin
matriksTemp[baris,kolom]:=Matriks1[baris,0]*Matriks2[0,kolom]+
Matriks1[baris,1]*Matriks2[1,kolom]+
Matriks1[baris,2]*Matriks2[2,kolom]+
Matriks1[baris,3]*Matriks2[3,kolom];
end;
end;
for baris:=0 to 3 do
for kolom:=0 to 3 do
Matriks3[baris,kolom]:=matriksTemp[baris,kolom];
end;

procedure TTransformasi.Translasi(x,y,z:real);
var matriksTranslasi:Matriks4x4;
begin
MatriksIdentitas(MatriksTranslasi);
MAtriksTranslasi[3,0]:=x;
MAtriksTranslasi[3,1]:=y;
MAtriksTranslasi[3,2]:=z;
PerkalianMatriks(MAtriks,MAtriksTranslasi,MAtriks);
end;

procedure TTransformasi.Penskalaan(sx,sy,sz,xc,yc,zc:real);
var matriksPenskalaan:Matriks4x4;
begin
MatriksIdentitas(matriksPenskalaan);
Translasi(-xc,-yc,-zc);
matriksPenskalaan[0,0]:=sx;
matriksPenskalaan[1,1]:=sy;
matriksPenskalaan[2,2]:=sz;
PerkalianMatriks(Matriks,matriksPenskalaan,Matriks);
Translasi(xc,yc,zc);
end;

procedure TTransformasi.Rotasi(sudut:real;xr,yr,zr:real);
var
alpha,betha,radian:real;
110

ryb,rza,ryb_1,rza_1,ry:Matriks4x4;
u,u1,u2,s:Ttitik3d;
begin
MatriksIdentitas(ryb);
MatriksIdentitas(rza);
MatriksIdentitas(ry);
MatriksIdentitas(ryb_1);
MatriksIdentitas(rza_1);
MatriksIdentitas(Matriks);

radian:=sudut*PI/180;
if zr<0 then radian:=-radian;

u1:=Normalisasi(BuatVektor(1,0,0));
u2:=Normalisasi(buatVektor(0,1,0));
s :=Normalisasi(BuatVektor(xr,yr,zr));

u :=BuatVektor(xr,0,zr);
if PanjangVektor(u)=0 then betha:=0 //Sumbu putar berhimpit dengan
sumbu Y
else
begin
u:=normalisasi(u);
betha:=arcCos(DotProduct(u,u1));
if u.posZ<0 then betha:=-betha;
end;

alpha:=arcCos(DotProduct(u2,s));
ryb[0,0]:=cos(betha);ryb[0,2]:=-sin(betha);
ryb[2,0]:=sin(betha);ryb[2,2]:=cos(betha);
//Ry(-betha)
perkalianMatriks(Matriks,ryb,Matriks);

rza[0,0]:=cos(alpha);rza[0,1]:=sin(alpha);
rza[1,0]:=-sin(alpha);rza[1,1]:=cos(alpha);
//Ry(-betha)*Rz(-alpha)
PerkalianMatriks(MAtriks,rza,Matriks);

ry[0,0]:=cos(radian);ry[0,2]:=-sin(radian);
ry[2,0]:=sin(radian);ry[2,2]:=cos(radian);
//Ry(Degree)
PerkalianMatriks(Matriks,ry,Matriks);

rza_1[0,0]:=cos(-alpha);rza_1[0,1]:=sin(-alpha);
rza_1[1,0]:=-sin(-alpha);rza_1[1,1]:=cos(-alpha);
//Rz(degree)
PerkalianMAtriks(Matriks,rza_1,MAtriks);

ryb_1[0,0]:=cos(-betha);ryb_1[0,2]:=-sin(-betha);
ryb_1[2,0]:=sin(-betha);ryb_1[2,2]:=cos(-betha);
//Ry(betha)
PerkalianMatriks(Matriks,ryb_1,MAtriks);
end;

Procedure TTransformasi.Shearing(sumbu:integer;ref,shear1,shear2:real);
var matriksShearing:Matriks4x4;
begin
MatriksIdentitas(matriksShearing);
if sumbu=1 then
begin
matriksShearing[3,1]:=-shear1*ref;
matriksShearing[3,2]:=-shear2*ref;
matriksShearing[0,1]:=shear1;
matriksShearing[0,2]:=shear2;
end;
111

if sumbu=2 then
begin
matriksShearing[3,0]:=-shear1*ref;
matriksShearing[3,2]:=-shear2*ref;
matriksShearing[1,0]:=shear1;
matriksShearing[1,2]:=shear2;
end;
if sumbu=3 then
begin
matriksShearing[3,0]:=-shear1*ref;
matriksShearing[3,1]:=-shear2*ref;
matriksShearing[2,0]:=shear1;
matriksShearing[2,1]:=shear2;
end;
PerkalianMatriks(Matriks,matriksShearing,Matriks);
end;

procedure TTransformasi.Transform(P:Ttitik3d;var Q:Ttitik3d);


begin
Q.posX:=P.posX*Matriks[0,0]+P.posY*Matriks[1,0]+
P.posZ*MAtriks[2,0]+1*Matriks[3,0];
Q.posY:=P.posX*Matriks[0,1]+P.posY*Matriks[1,1]+
P.posZ*MAtriks[2,1]+1*Matriks[3,1];
Q.posZ:=P.posX*Matriks[0,2]+P.posY*Matriks[1,2]+
P.posZ*MAtriks[2,2]+1*Matriks[3,2];
end;

procedure TTransformasi.nolkanTransformasi;
begin
MatriksIdentitas(MAtriks);
end;

Procedure TTransformasi.ambilPos3d(X,Y:integer;var titik:TArTitik3D);


var viewport : array[1..4] of Integer;
modelview: array[1..16] of Double;
proyeksi : array[1..16] of Double;
winZ : Single;
begin
glGetDoublev(GL_MODELVIEW_MATRIX, @modelview);
glGetDoublev(GL_PROJECTION_MATRIX,@proyeksi);
glGetIntegerv(GL_VIEWPORT,@viewport);

//pada delphi jika nilai sama dengan 0 mengembalikan nilai unknown


if Y=0 then Y:=1;

glReadPixels(X,-Y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,@winZ);
gluUnProject(X,viewport[4]-Y,winZ,@modelview,@proyeksi,@viewport,
titik[1],titik[2],titik[3]);
end;

end.
LAMPIRAN B

WAVEFRONT OBJ FILE FORMAT SUMMARY

Wavefront OBJ File Format Summary

Also Known As: Wavefront Object, OBJ

Type 3D Vector
Colors Unlimited
Compression Uncompressed
Maximum Image Size Unlimited
Multiple Images Per File Yes
Numerical Format NA
Originator Wavefront
Platform UNIX
Supporting Applications Advanced Visualizer
See Also Wavefront RLA

Usage
Used to store and exchange 3D data.

Comments
The Wavefront OBJ format is a useful standard for representing polygonal data in ASCII form.

Vendor specifications are available for this format.

Wavefront OBJ (object) files are used by Wavefront's Advanced Visualizer application to store
geometric objects composed of lines, polygons, and free-form curves and surfaces. Wavefront is
best known for its high-end computer graphics tools, including modeling, animation, and image
compositing tools. These programs run on powerful workstations such as those made by Silicon
Graphics, Inc.

Wavefront OBJ files are often stored with the extension ".obj" following the UNIX convention of
lowercase letters for filenames. The most recently documented version of OBJ is v3.0, superseding
the previous v2.11 release.

Contents:
File Organization
File Details
For Further Information

112
113

In Wavefront's 3D software, geometric object files may be stored in ASCII format (using the
".obj" file extension) or in binary format (using the .MOD extension). The binary format is
proprietary and undocumented, so only the ASCII format is described here.

The OBJ file format supports lines, polygons, and free-form curves and surfaces. Lines and
polygons are described in terms of their points, while curves and surfaces are defined with control
points and other information depending on the type of curve. The format supports rational and
non-rational curves, including those based on Bezier, B-spline, Cardinal (Catmull-Rom splines),
and Taylor equations.

File Organization

OBJ files do not require any sort of header, although it is common to begin the file with a
comment line of some kind. Comment lines begin with a hash mark (#). Blank space and blank
lines can be freely added to the file to aid in formatting and readability. Each non-blank line begins
with a keyword and may be followed on the same line with the data for that keyword. Lines are
read and processed until the end of the file. Lines can be logically joined with the line continuation
character ( \ ) at the end of a line.

The following keywords may be included in an OBJ file. In this list, keywords are arranged by
data type, and each is followed by a brief description.

Vertex data:
v Geometric vertices
vt Texture vertices
vn Vertex normals
vp Parameter space vertices
Free-form curve/surface attributes:
deg Degree
bmat Basis matrix
step Step size
cstype Curve or surface type
Elements:
p Point
l Line
f Face
curv Curve
curv2 2D curve
surf Surface
Free-form curve/surface body statements:
parm Parameter values
trim Outer trimming loop
hole Inner trimming loop
scrv Special curve
sp Special point
end End statement
Connectivity between free-form surfaces:
con Connect
Grouping:
g Group name
s Smoothing group
114

mg Merging group
o Object name
Display/render attributes:
bevel Bevel interpolation
c_interp Color interpolation
d_interp Dissolve interpolation
lod Level of detail
usemtl Material name
mtllib Material library
shadow_obj Shadow casting
trace_obj Ray tracing
ctech Curve approximation technique
stech Surface approximation technique

File Details

The most commonly encountered OBJ files contain only polygonal faces. To describe a polygon,
the file first describes each point with the "v" keyword, then describes the face with the "f"
keyword. The line of a face command contains the enumerations of the points in the face, as 1-
based indices into the list of points, in the order they occurred in the file. For example, the
following describes a simple triangle:

# Simple Wavefront file


v 0.0 0.0 0.0
v 0.0 1.0 0.0
v 1.0 0.0 0.0
f123

It is also possible to reference points using negative indices. This makes it easy to describe the
points in a face, then the face, without the need to store a large list of points and their indexes. In
this way, "v" commands and "f" commands can be interspersed.

v -0.500000 0.000000 0.400000


v -0.500000 0.000000 -0.800000
v -0.500000 1.000000 -0.800000
v -0.500000 1.000000 0.400000
f -4 -3 -2 -1

OBJ files do not contain color definitions for faces, although they can reference materials that are
stored in a separate material library file. The material library can be loaded using the "mtllib"
keyword. The material library contains the definitions for the RGB values for the material's
diffuse, ambient, and specular colors, along with other characteristics such as specularity,
refraction, transparency, etc.

The OBJ file references materials by name with the "usemtl" keyword. All faces that follow are
given the attributes of this material until the next "usemtl" command is encountered.

Faces and surfaces can be assigned into named groups with the "g" keyword. This is used to create
convenient sub-objects to make it easier to edit and animate 3D models. Faces can belong to more
than one group.

The following demonstrate more complicated examples of smooth surfaces of different types,
material assignment, line continuation, and grouping.

Cube with Materials


# This cube has a different material
115

# applied to each of its faces.


mtllib master.mtl
v 0.000000 2.000000 2.000000
v 0.000000 0.000000 2.000000
v 2.000000 0.000000 2.000000
v 2.000000 2.000000 2.000000
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
# 8 vertices
g front
usemtl red
f1234
g back
usemtl blue
f8765
g right
usemtl green
f4378
g top
usemtl gold
f5148
g left
usemtl orange
f5621
g bottom
usemtl purple
f2673
# 6 elements

Bezier Patch
# 3.0 Bezier patch
v -5.000000 -5.000000 0.000000
v -5.000000 -1.666667 0.000000
v -5.000000 1.666667 0.000000
v -5.000000 5.000000 0.000000
v -1.666667 -5.000000 0.000000
v -1.666667 -1.666667 0.000000
v -1.666667 1.666667 0.000000
v -1.666667 5.000000 0.000000
v 1.666667 -5.000000 0.000000
v 1.666667 -1.666667 0.000000
v 1.666667 1.666667 0.000000
v 1.666667 5.000000 0.000000
v 5.000000 -5.000000 0.000000
v 5.000000 -1.666667 0.000000
v 5.000000 1.666667 0.000000
v 5.000000 5.000000 0.000000
# 16 vertices
cstype bezier
deg 3 3
# Example of line continuation
surf 0.000000 1.000000 0.000000 1.000000 13 14 \
15 16 9 10 11 12 5 6 7 8 1 2 3 4
parm u 0.000000 1.000000
parm v 0.000000 1.000000
end
# 1 element

Cardinal Curve
# 3.0 Cardinal curve
v 0.940000 1.340000 0.000000
v -0.670000 0.820000 0.000000
v -0.770000 -0.940000 0.000000
v 1.030000 -1.350000 0.000000
v 3.070000 -1.310000 0.000000
# 6 vertices
cstype cardinal
deg 3
curv 0.000000 3.000000 1 2 3 4 5 6
parm u 0.000000 1.000000 2.000000 3.000000 end
116

# 1 element

Texture-Mapped Square
# A 2 x 2 square mapped with a 1 x 1 square
# texture stretched to fit the square exactly.
mtllib master.mtl
v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 0.000000 0.000000
vt 1.000000 0.000000 0.000000
vt 1.000000 1.000000 0.000000
# 4 vertices
usemtl wood
# The first number is the point,
# then the slash,
# and the second is the texture point
f 1/1 2/2 3/3 4/4
# 1 element

For Further Information

For further information about the Wavefront OBJ format, see the specification.

You can also contact:

Wavefront Technologies
530 East Montecito Street
Santa Barbara, CA 93103
Voice: 805-962-8117
FAX: 805-963-0410
WWW: http://www.aw.sgi.com/

Wavefront also maintains a toll-free support number and a BBS for its customers. There are many
Wavefront user groups, too.

This page is taken from the Encyclopedia of Graphics File Formats and is licensed by O'Reilly
under the Creative Common/Attribution license.

More Resources

Diambil dari http://www.fileformat.info/resource/book/1565921615/index.htm


LAMPIRAN C

PERINTAH OPENGL PADA APLIKASI

GRAFIKA KOMPUTER UNTUK TRANSFORMASI 3D

1. glClearColor(R, G, B, A);
Perintah untuk memberihkan layar dengan warna R, G, B, dan A.
2. glShadeModel(jenisShading);
Jenis shading yang digunakan, yaitu GL_FLAT untuk flat shading dan
GL_SMOOTH untuk gouround shading.
3. glClearDepth(1.0);
Depth value yang digunakan ketika membersihkan depth buffer.
4. glEnable(GL_DEPTH_TEST);
Mengaktifkan pengujian depth.
5. glEnable(GL_NORMALIZE);
Mengaktifkan nomalisasi vektor normal.
6. glDepthFunc(GL_LESS);
Jenis pengujian depth yang akan dilakukan. GL_LESS hanya akan
melewatkan nilai z yang kurang dari nilai z yang disimpan pada depth buffer.
7. glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
Meningkatkan kualitas interpolasi warna dan koordinat tekstur pada proyeksi
perspektif.
8. glEnable(GL_LIGHTING);
Mengaktifkan pencahayaan.
9. glEnable(GL_LIGHT0);
Mengaktifkan sumber cahaya 0.
10. glLightfv(GL_LIGHT0,GL_POSITION,@light_position);
Menempatkan sumber cahaya 0 pada posisi light_position.
11. glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
Membersihkan bit-bit pada color buffer dan depth buffer.
12. glLoadIdentity();
Memuat matriks identitas.
13. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

105
106

Mode ransterisasi poligon. GL_FRONT_AND_BACK untuk rasterisasi


bagian muka dan belakang poligon. GL_LINE untuk mode wireframe,
GL_FILL untuk mode rasterisasi penuh, dan GL_POINT untuk mode titik-
titik.
14. glViewport(0, 0, 800,600);
Membuat viewport dengan ukuran lebar 800 dan tinggi 600 dari posisi 0, 0.
15. glMatrixMode(GL_PROJECTION);
Mengubah mode matriks ke mode proyeksi. GL_MODELVIEW untuk mode
pemodelan–membentuk objek geometri.
16. gluPerspective(45.0, Width/ Height, 1.0, 500.0);
Menggunakan proyeksi perspektif dengan sudut 45o, rasio width/height,
Znear=1, dan Zfar=500.
17. gluLookAt(xs, ys, zs, xf, yf, zf, 0.0,1.0,0.0);
Menggunakan kamera sintetis dengan arah kamera dari titik xs,ys,zs ke titik
fokus xf,yf,zf. Sumbu Y+ sebagai sumbu kamera.
18. glSelectBuffer(512, @selectBuffer);
Membuat buffer untuk mode seleksi.
19. glRenderMode(GL_SELECT);
Memilih mode rasterisasi. GL_SELECT untuk mode seleksi. Model ini
menembalikan nama-nama objek yang digambar pada mode GL_RENDER.
GL_RENDER untuk mode render.
20. glPushMatrix();
Untuk melakukan push pada matrix stack yang sedang aktif.
21. glPopMatrix();
Untuk melakukan pop pada matrix stack yang sedang aktif.
22. glGetIntegerv(GL_VIEWPORT, @viewportCoords);
Mengembalikan nilai pada viewport matrix stack. Ada 4 nilai yang
dikembalikan.
23. gluPickMatrix(x, viewportCoords[3]-y, 1, 1, @viewportCoords);
Mendefinisikan daerah untuk picking.
24. glMaterialfv(GL_FRONT, GL_DIFFUSE, @warna);
Memberikan warna diffuse dengan spesifikasi @warna pada sisi depan
poligon objek.
25. glBegin(param);
107

Awal untuk menggambar objek geometri. Param mendefinisikan mode cara


menggambar, yaitu GL_POINTS, GL_LINES, GL_LINE_STRIP,
GL_LINE_LOOP, GL_TRIANGLES, GL_TRIANGLE_STRIP,
GL_TRIANGLE_FAN, GL_QUADS, GL_QUAD_STRIP, and
GL_POLYGON.
26. glVertex3f(X,Y,Z);
Menggambar verteks pada posisi X,Y,Z.
27. glEnd;
Akhir untuk mengambar objek geometri. GlEnd berpasangan dengan glBegin.
28. glGetDoublev(GL_MODELVIEW_MATRIX, @modelview);
Mengmbalikan nilai matriks pada modelview matrix stack. Ada 16 nilai yang
dikembalikan.
29. glGetDoublev(GL_PROJECTION_MATRIX,@proyeksi);
Mengembalikan nilai pada projection matrix stack. Ada 4 nilai yang
dikembalikan.
30. glReadPixels(X,-
Y,1,1,GL_DEPTH_COMPONENT,GL_FLOAT,@winZ);
Membaca blok pixel dari frame buffer.
31. glLineWidth(x);
Perintah ini digunakan untuk mengatur ketebalan garis.
32. gluUnProject(X,viewport[4]-
Y,winZ,@modelview,@proyeksi,@viewport,titik[1],titik[2],titik[3]);
Memetakan koordinat window dengan koordinat objek.
Makalah Seminar Tugas Akhir

Aplikasi Grafika Komputer untuk Transformasi 3 Dimensi


Alfa Ryano1, Agung B.P.2, Eko Handoyo2
1
Mahasiswa dan 2Dosen Jurusan Teknik Elektro, Fakultas Teknik, Universitas Diponegoro,
Jl. Prof. Sudharto, Tembalang, Semarang, Indonesia

Abstrak
Transformasi memiliki bagian yang penting pada grafika komputer. Dengan transformasi, suatu objek dapat
dipindahkan dapat berubah posisi dan atau bentuk.Tugas akhir ini mengimplementasikan transformasi 3 dimensi dalam
bentuk suatu aplikasi studio. Aplikasi dapat membuat suatu objek yang kemudian dapat ditransformasikan. Transformasi
yang dapat dilakukan berupa translasi, penskalaan, rotasi, dan shearing. Analisis dan desain aplikasi menggunakan
pendekatan berorientasi objek. Aplikasi dibuat menggunakan bahasa pemrograman Delphi dan OpenGL.
Aplikasi yang dibuat diharapkan dapat mentransformasi objek 3 dimensi melalui antarmuka aplikasi.

Kata kunci: transformasi, rotasi, penskalaan, translasi, shearing, OpenGL

1. Pendahuluan 1.5 Kegunaan Hasil Penelitian


1.1 Latar Belakang Masalah 1. Mengetahui bagaimana mengimplementasikan
Grafika komputer–salah satu cabang ilmu transformasi 3 dimensi Pada aplikasi 3 dimensi
komputer–berkembang cukup pesat. Ini terbukti dengan menggunakan OpenGL dan Delphi dengan pendekatan
banyaknya bidang yang menerapkan grafika komputer berorientasi objek.
seperti video game, CAD (Computer Aided Design), 2. Menghasilkan suatu aplikasi yang dapat melakukan
animasi, simulasi, dan lain-lain. transformasi 3 dimensi. Aplikasi ini dapat
Transformasi 3 dimensi memiliki bagian yang dikembangkan lebih untuk fungsi-fungsi yang lebih luas
penting pada grafika komputer. Dengan transformasi, yang berkaitan dengan Grafika Komputer, seperti
ukuran dan bentuk suatu objek geometri dapat diubah. pewarnaan, texture mapping, rendering, dan animasi.
Tugas akhir ini mencoba mengimplementasikan
transformasi 3 dimensi dalam bentuk suatu aplikasi studio. 2. Transformasi Geometri pada Ruang 3 Dimensi
Transformasi yang dapat dilakukan, yaitu translasi, Untuk membangun suatu aplikasi studio yang
penskalaan, rotasi, dan shearing. Pertama-tama, aplikasi mendukung fungsi transformasi 3 dimensi setidaknya
dimodelkan terlebih dahulu melalui pendekatan berorientasi dibutuhan tiga bagian penting. Bagian-bagian tersebut,
objek menggunakan UML kemudian aplikasi dibuat yaitu pemahaman teori transformasi 3 dimensi, transformasi
menggunakan bahasa pemrograman Delphi dan OpenGL. 3 dimensi menggunakan OpenGL, dan penggunaan
OpenGL API pada bahasa pemrograman Delphi.
1.2 Identifikasi Masalah
Dalam pembuatan aplikasi terdapat 3 masalah utama, yaitu: 2.1 Transformasi 3 Dimensi
1. Bagaimana merepresentasikan objek geometri yang Teori transformasi 3 dimensi memegang peranan
terdiri dari verkteks-verkteks sehingga dapat penting karena bagian ini merupakan ilmu dasar yang akan
ditampilkan di layar. diimplentasikan pada program aplikasi.
2. Bagaimana mentransformasi objek 3 dimensi pada Pada tugas akhir ini digunakan sistem koordinat
aplikasi tersebut. Tansformasi meliputi translasi, homogen. Sistem koordinat homogen menggunakan empat
penskalaan, shearing, dan rotasi. ordinat untuk menyatakan titik-titiknya. Ordinat keempat
3. Antarmuka pengguna dengan program sehingga menyatakan faktor skala.
pengguna dapat melakukan transformasi pada objek. P = [px py pz s]
Titik hasil transformasi dapat diperoleh melalui persamaan
1.3 Batasan Masalah 2.1:
1. Tugas Akhir ini membahas mengenai implementasi Q = P*M (2.1)
transformasi 3 dimensi dalam bentuk suatu aplikasi dengan :
studio. Q = [qx,qy,qz,1] menyatakan matriks 1x4 yang
2. Implementasi transformasi 3 dimensi menggunakan berisi titik hasil transformasi.
bahasa pemrograman Delphi dan API OpenGL. P = [px,py,pz,1] menyatakan matriks 1x4 yang berisi
3. Analisis dan desain aplikasi menggunakan pendekatan titik yang akan ditransformasikan
berorientasi objek. M = Matriks transformasi berukuran 4x4 seperti
pada persamaan 2.2.
1.4 Tujuan Penelitian m00 m01 m02 m03 
Tujuan penelitian adalah implementasi transformasi 3 m m11 m12 m13  (2.2)
dimensi dalam bentuk suatu aplikasi studio. M =  10
m20 m21 m22 m23 
 
m30 m31 m32 m33 

1
Transformasi 3 dimensi terdiri dari beberapa fungsi PROJECTION, dan TEXTURE. MODELVIEW adalah
transformasi, yaitu translasi, rotasi, penskalaan, dan matriks yang digunakan untuk melakukan transformasi.
shearing. Matriks masing-masing transformasi adalah PROJECTION adalah matriks yang digunakan untuk
sebagai berikut. proyeksi, dan TEXTURE adalah mariks yang digunakan
untuk mengatur tekstur/tampilan permukaan.
1 0 0 0
0 1 0 0 (2.3) glLoadIndentity;
MT =  Procedure glTranslate(x,y,z);
0 0 1 0 Procedure glRotate(degree,x,y,z);
 
tx ty tz 1 Procedure glScale(x,y,z);

 sx 0 0 0 Perintah pertama mengatur agar matriks yang digunakan


 0 sy 0 0 (2.5) diisi dengan matriks identitas. Perintah kedua digunakan
MS =  
untuk melakukan translasi sebesar x, y, dan z. Perintah
 0 0 sz 0
  ketiga digunakan untuk rotasi sebesar sudut degree dengan
 0 0 0 1
sumbu x, y, dan z. Perintah keempat digunakan untuk
penskalaan sebesar x, y, dan z..
1 0 0 0 Pada pembuatan aplikasi, penyusun tidak
0 Cos (θ ) Sin(θ ) 0 (2.6) menggunakan prosedur transformasi bawaan OpenGL
M Rx =
0 − Sin(θ ) Cos (θ ) 0 karena OpenGL tidak memiliki prosedur untuk shearing.
  Penyusun membuat prosedur transformasi sendiri.
0 0 0 1

Cos (θ ) 0 − Sin (θ ) 0 2.3 Penggunaan OpenGL dan Delphi untuk


 0 1 0 0
Transformasi 3 Dimensi
(2.7)
M Ry = OpenGL dan Delphi perlu dihubungkan sehingga
 Sin(θ ) 0 Cos (θ ) 0 transformasi 3 dimensi yang menggunakan Delphi dan
 
 0 0 0 1 OpenGL dapat dilakukan. OpenGL dapat digunakan dengan
menambahkan klausa openGL pada bagian Uses kode
 Cos(θ ) Sin(θ ) 0 0 sumber.
− Sin(θ ) Cos (θ ) 0 0 OpenGL bukan merupakan bagian dari system operasi
(2.8)
M Rz = Windows sehingga diperlukan memberitahu Windows
 0 0 1 0
  bahwa program menggunakan API dari OpenGL. Informasi
 0 0 0 1
yang perlu disampaikan, yaitu:
1. Format Pixel yang disampaikan melalui struktur data
1 Sh Sh 0 TPixelFormatDescriptor. Format Pixel memberikan
0 1 0 0 (2.9)
M xsh = informasi mengenai jumlah warna dalam bit per pixel,
0 0 1 0 kedalaman sumbu z, serta tipe pixel.
 
0 − Sh ⋅ Xref − Sh ⋅ Xref 1 2. Device Context yang menyatakan perangkat (device)
yang akan digunakan oleh OpenGL untuk menggambar
 1 0 0 0 di layer. Perangkat yang disediakan oleh Windows dan
 Sh 1 Sh 0 (2.10) perangkat yang disediakan oleh OpenGL harus
M ysh = dihubungkan sehingga apa yang digambar oleh OpenGL
 0 0 1 0
  akan ditampilkan oleh Windows.
 − Sh ⋅ Yref 0 − Sh ⋅ Yref 1

3. Pemodelan Aplikasi Grafika Komputer untuk


 1 0 0 0
 Transformasi 3D
0 1 0 0 (2.11)
M zsh = Pemodelan aplikasi grafika komputer untuk
 Sh Sh 1 0
  transformasi objek 3 dimensi menggunakan pendekatan
− Sh ⋅ Zref − Sh ⋅ Zref 0 1 berorientasi objek (objek oriented analysis and design).
Langkah-langkah yang dilakukan seperti model yang
Matriks-matriks di atas kemudian diubah ke dalam bentuk diutarakan oleh Pressman[6], yaitu:
prosedur-prosedur bahasa pemrograman Delphi. Prosedur- 1. Use case,
prosedur tersbut akan digunakan untuk mentransformasi 2. Kartu Index CRC,
verteks-verteks penyusun objek geometri. 3. Diagram Kelas,
4. Model Hubungan Objek (Object Relationship), dan
2.2 Transformasi 3 Dimensi pada OpenGL 5. Model Tingkah Laku Objek (Object Behaviour).
OpenGL sendiri sudah menyediakan perintah-perintah Langkah-langkah tersebut kemudian dibuat dalam bentuk
untuk melakukan transformasi. Perintah-perintah yang diagram UML seperti berikut.
berhubungan dengan transformasi adalah:
3.1. Use Case
Procedure glMatriksMode(m:GLenum); Aplikasi yang akan dibangun paling sedikit memiliki 3
use case utama, yaitu membuat objek, menghapus objek
Untuk mengatur pemakaian matriks, ada tiga macam ,dan mentransformasi. Use case transformasi sendiri
matriks yang dapat digunakan, yaitu: MODELVIEW, merupakan generaliasi dari use case translasi, penskalaan,

2
rotasi, dan shearing. Use case buat objek merupakan • Tinggi
include dari use case hapus objek dan transformasi karena Operasi:
• Gambar
sebelum melakukan rotasi dan hapus objek perlu membuat
• Create
objek terlebih dahulu. Diagramnya dapat dilihat pada
gambar 3.1. Tabel 3.5 Kartu index CRC kelas meja.
Kelas: Meja
Tanggung Jawab: Kolaborator:
Atribut:
Buat Objek • - • -
Operasi:
Translasi
<<include>> • Gambar
• Create
Penskalaan
Tabel 3.6 Kartu index CRC kelas kursi.
<<include>> Kelas: kursi
Transformasi Tanggung Jawab: Kolaborator:
Pengguna
Atribut:
Rotasi
• - • -
Operasi:
• Gambar
Hapus Objek Shearing • Create

Tabel 3.7 Kartu index CRC Transformasi.


Gambar 3.1 Diagram use case aplikasi grafika komputer untuk Kelas: Transformasi
transformasi objek 3 dimensi. Tanggung Jawab: Kolaborator:
Atribut:
3.2. Kartu Index CRC • Matriks • Objek Geometri
Dari use case pada subbab 3.1, aplikasi paling sedikit Operasi:
• PerkalianMatriks
membutuhkan 2 buah kelas utama, yaitu kelas transformasi • MatriksIdentitas
dan kelas geometri. Kelas geometri kemudian diturunkan • Translasi
sehingga terbentuk anak kelas objek kubus, piramida, • Penskalaan
silinder, meja, dan kursi. • Rotasi
• Shearing
Tabel 3.1 Kartu index CRC kelas geometri. • Transform
Kelas: Geometri • nolkanTransformasi
Tanggung Jawab: Kolaborator: • ambilPos3d
Atribut:
• nama • - 3.3. Diagram Kelas
• index Dari kartu index CRC pada subbab 3.2, penyusun
• jenis
membuat diagram kelas-nya seperti pada gambar 3.2. Kelas
• pusat
• jumTitik objek kubus, piramida, silinder, meja, dan kursi memiliki
• titik parent kelas geometri. Kelas transformasi dan kelas
• sudut geometri memiliki hubungan dari satu ke satu atau banyak.
• Aktif Artinya satu objek transformasi dapat mentransformasi satu
Operasi: atau lebih objek geometri.
• Gambar
Transformasi
Geometri Matriks
Tabel 3.2 Kartu index CRC kelas kubus. nama : String
perkalianMatriks()
Kelas: Kubus index : Integer
jenis : String Mentransformasi
MatriksIdentitas()
Translasi()
Tanggung Jawab: Kolaborator: posisi : Single
sudut : Single 1..*
Penskalaan()
1 Rotasi()
Atribut: pusat : Single
Shearing()

• Sisi • - gambar()
Transform()
nolkanTransformasi()
ambilPos3d()
Operasi:
• Create
• Gambar
Kubus Piramid Meja Kursi
Silinder
Tabel 3.3 Kartu index CRC kelas piramid. sisi : Single
radius : Single tinggi : Single
sisi : Single gambar() gambar()
Kelas: Piramid gambar()
tinggi : Single
create() create()
create() gambar()
Tanggung Jawab: Kolaborator: gambar()
create()
Atribut:
• Tinggi • - Gambar 3.2 Diagram kelas aplikasi grafika komputer untuk
• Sisi transformasi objek 3 dimensi.
Operasi:
• Gambar 3.4. Model Hubungan Objek (Object Relationship)
• Create
Model hubungan objek (object relationship model)
Tabel 3.4 Kartu index CRC kelas silinder. dapat digambarkan dengan menggunakan diagram runtun
Kelas: Silinder (sequence diagram). Pada gambar 3.3 terdapat 3 skenario,
Tanggung Jawab: Kolaborator: yaitu menciptakan objek geometri, mentransformasi objek
Atribut: geometri, dan menghapus objek geometri.
• Radius • -

3
4. Implementasi dan Pengujian Aplikasi Grafika
Komputer untuk Transformasi 3D
: Pengguna
Panel : Transformasi : Geometri Layar Hasil pembuatan aplikasi dapat dilihat pada gambar
Memilih objek
4.1-4.6. Gambar 4.1 merupakan tampilan form utama
yang akan dibuat
dan nilai atributnya aplikasi grafika komputer untuk transformasi 3 dimensi.
gambar objek
Membuat objek geometri
pada layar

Menampilkan objek geometri

Memilih jenis
transformasi dan
nilainya Memberi nilai sesuai input Gambar
Mentransformasi objek pada
objek geometri layar

Menampilkan
objek geometri
hasil
transformasi
Memilih
objek yang
akan Menghapus objek geometri Hapus
dihapus
objek pada
layar

Meampilkan hasil menghapus objek geometri

Gambar 4.1 Tampilan aplikasi grafika komputer


untuk transformasi 3 dimensi.

Gambar 3.3 Diagram runtun aplikasi grafika komputer untuk


Toolbar (gambar 4.2) digunakan untuk meemilih jenis
transformasi objek 3 dimensi. transformasi yang akan dilakukan, mengubah arah kamera,
dan memilih sumbu.
3.5. Model Tingkah Laku Objek (Object Behaviour)
Gambar 3.4 merupakan diagram statechart yang
menggambarkan perilaku 2 objek, yaitu objek transformasi
(a) dan objek geometri (b). Model tingkah laku objek
menunjukkan bagaimana system akan merespon kejadian Gambar 4.2 Toolbar dan menu aplikasi.
atau stimulus eksternal.
Tab-tab objek (gambar 4.3) digunakan untuk membuat
Mulai
objek geometri seperti kubus, dilinder, piramida, meja, dan
Mentransform asi
kursi.
Membuat objek geometri
objek
transform asi

Objek transformasi Menunggu


tercipta perintah transformasi selanjutnya

Menghapus
objek
geometri

Selesai
Objek transformasi
terhapus

(a)
Mulai Posisi, sudut, dan
bentuk yang baru

Membuat objek geometri Mentransformasi


objek geom etri

Objek geometri
Menunggu transformasi
tercipta
selanjutnya

Gambar 4.3 Tampilan tab-tab untuk objek kubus, kursi, meja, piramida,
Menghapus
objek geometri
silinder, dan kamera.

Objek geometri
Status bar (gambar 4.4) digunakan untuk menampilkan
Selesai
terhapus informasi mode transformasi yang sedang aktif, posisi
kursor pada koordinat world, posisi kursor pada layar, dan
(b) sumbu putar yang sedang aktif
.
Gambar 3.4 Diagram statechart aplikasi grafika komputer
untuk transformasi objek 3 dimensi: (a) diagram statechart objek
transformasi (b) diagram statechart objek geometri. Gambar 4.4 Status Bar.

4
Popup menu (gambar 4.5) digunakan untuk menampilkan
form-form transformasi (gambar 4.6) dan menghapus objek
yang aktif terpilih.

(b)

Gambar 4.7 Pengujian transformasi: (a) keadaan awal;


(b) hasil translasi (1 1 -1); (c) hasil penskalaan (2 2 2);
Gambar 4.5 Tampilan popup menu klik kanan. (d) hasil rotasi (30o 0 1 0); (e) hasil shearing (X 1 1).

Form-form transformasi (gambar 4.6) digunakan untuk Tabel 4.1. Perbandingan antara hasil perhitungan dan hasil
aplikasi untuk translasi (1,00 1,00 -1,00);
mentransformasi objek geometri. Transformasi melalui Hasil Transformasi
Koordinat
form transformasi dapat dilakukan lebih presisi daripada Titik
Awal Aplikasi Perhitungan
menggunakan mouse karena nilai-nilai untuk parameter 0 0,00 0,00 0,00 1,00 1,00 -1,00 1,00 1,00 -1,00
transformasi diberikan dengan angka. 1 0,00 0,50 0,00 1,00 1,50 -1,00 1,00 1,50 -1,00
2 -0,50 -0,50 0,50 0,50 0,50 -0,50 0,50 0,50 -0,50
3 0,50 -0,50 0,50 1,50 0,50 -0,50 1,50 0,50 -0,50
4 0,50 -0,50 -0,50 1,50 0,50 -1,50 1,50 0,50 -1,50
5 -0,50 -0,50 -0,50 0,50 0,50 -1,50 0,50 0,50 -1,50
6 -0,50 -0,50 0,50 0,50 0,50 -0,50 0,50 0,50 -0,50

Tabel 4.2. Perbandingan antara hasil perhitungan dan hasil


aplikasi untuk transformasi penskalaan (2,00 2,00 2,00);
Koordinat Hasil Transformasi
Titik
Awal Aplikasi Perhitungan
0 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00
1 0,00 0,50 0,00 0,00 1,00 0,00 0,00 1,00 0,00
2 -0,50 -0,50 0,50 -1,00 -1,00 1,00 -1,00 -1,00 1,00
3 0,50 -0,50 0,50 1,00 -1,00 1,00 1,00 -1,00 1,00
4 0,50 -0,50 -0,50 1,00 -1,00 -1,00 1,00 -1,00 -1,00
5 -0,50 -0,50 -0,50 -1,00 -1,00 -1,00 -1,00 -1,00 -1,00
Gambar 4.6 Form untuk transformasi translasi, penskalaan, rotasi dan 6 -0,50 -0,50 0,50 -1,00 -1,00 1,00 -1,00 -1,00 1,00
shearing.
Tabel 4.3. Perbandingan antara hasil perhitungan dan hasil
Transformasi-transformasi 3D pada aplikasi diuji. aplikasi untuk transformasi rotasi (30o 0,00 1,00 0,00).
Pengujian dilakukan dengan membandingkan hasil Koordinat Hasil Transformasi
Titik
transformasi aplikasi dengan hasil transformasi melalui Awal Aplikasi Perhitungan
perhitungan. Pengujian dilakukan pada objek geometri 0 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00 0,00
piramida yang memiliki 7 titik. Gambar 4.7a menunjukkan 1 0,00 0,50 0,00 0,00 0,50 0,00 0,00 0,50 0,00
2 -0,50 -0,50 0,50 -0,18 -0,50 0,68 -0,18 -0,50 0,68
posisi awal piramida ketika dibuat pada aplikasi. Untuk 3 0,50 -0,50 0,50 0,68 -0,50 0,18 0,68 -0,50 0,18
translasi digunakan translasi (1 1 -1) (gambar 4.7b).Untuk 4 0,50 -0,50 -0,50 0,18 -0,50 -0,68 0,18 -0,50 -0,68
penskalaan digunakan penskalaan (2 2 2) (gambar 4.7c). 5 -0,50 -0,50 -0,50 -0,68 -0,50 -0,18 -0,68 -0,50 -0,18
Untuk rotasi digunakan rotasi (30o 0 1 0). Untuk shearing 6 -0,50 -0,50 0,50 -0,18 -0,50 0,68 -0,18 -0,50 0,68
digunakan shearing (X 1 1).
Tabel 4.4 Perbandingan antara hasil perhitungan dan hasil
aplikasi untuk transformasi shearing (X 1,00 1,00).
Koordinat Hasil Transformasi
Titik
Awal Aplikasi Perhitungan
0 0,00 0,00 0,00 0,00 -1,00 -1,00 0,00 -1,00 -1,00
1 0,00 0,50 0,00 0,00 -0,50 -1,00 0,00 -0,50 -1,00
2 -0,50 -0,50 0,50 -0,50 -2,00 -1,00 -0,50 -2,00 -1,00
3 0,50 -0,50 0,50 0,50 -1,00 0,00 0,50 -1,00 0,00
4 0,50 -0,50 -0,50 0,50 -1,00 -1,00 0,50 -1,00 -1,00
5 -0,50 -0,50 -0,50 -0,50 -2,00 -2,00 -0,50 -2,00 -2,00
(a) (b) 6 -0,50 -0,50 0,50 -0,50 -2,00 -2,00 -0,50 -2,00 -2,00

Hasil pengujian pada tabel 4.1-4.4 memperlihatkan


kesamaan antara hasil aplikasi dan hasil melalui
perhitungan. Dengan demikian, jika dilihat dari pengujian,
aplikasi dapat melakukan transformasi dengan tepat.

(c) (d)

5
5. Kesimpulan dan Saran [13] ---, Tutorial on UML, Chapter 12, TIMe Electronic
Kesimpulan Textbook version 4.0, SINTEF, July 16th, 1999.
1. Fleksibilitas fungsi-fungsi transformasi yang dibuat
sendiri lebih tinggi daripada menggunakan fungsi-
fungsi bawaan OpenGL karena OpenGL hanya BIOGRAFI PENULIS
mendukung transformasi translasi, rotasi, dan
penskalaan tetapi tidak untuk shearing. Fungsi-fungsi Alfa Ryano Yohannis, lahir di Kendari,
transformasi yang dibuat sendiri juga dapat dimodifikasi Sulawesi Tenggara, 16 juli 1984.
dengan mudah sesuai kebutuhan. Menempuh pendidikan di SD Kristen
2. Rotasi pada suatu objek geometri yang menggunakan Kendari, SLTP Negeri 1 Kendari, dan
sumbu putar yang tidak melewati titik origin dapat SMU Negeri 1 Makassar. Saat ini sedang
dilakukan dengan mentranslasikan terlebih dahulu menyelesaikan pendidikan program
sumbu tersebut ke titik origin. Kemudian objek dirotasi Strata 1 Jurusan Teknik Elektro
sesuai dengan sudut yang ditentukan. Setelah itu, Universitas Diponegoro dengan
sumbu ditranslasikan kembali ke posisi semula. mengambil konsentrasi teknik informatika dan komputer.
3. Perbandingan antara hasil perhitungan dan hasil Topik Tugas Akhir yang diambil tentang transformasi objek
transformasi aplikasi menunjukkan bahwa aplikasi 3 dimensi pada grafika komputer.
grafika komputer untuk transformasi 3 dimensi ini dapat
melakukan transformasi dengan tepat.
4. Untuk beberapa komputer dan sistem operasi, aplikasi Menyetujui dan mengesahkan,
grafika komputer untuk transformasi 3 dimensi ini
hanya dapat berjalan jika regional and language options Dosen Pembimbing I
diubah ke regional dan bahasa Indoensia. Ini terjadi
karena format penulisan angka yang digunakan
menggunakan koma (,) untuk desimal.
Agung B. P., S.T., M.I.T.
Saran NIP. 132 137 932
1. Aplikasi dapat dikembangkan lebih lanjut dengan Tanggal………………...
menambahkan fasilitas pewarnaan (coloring) dan
texture mapping sehingga warna suatu objek dapat
diubah sesuai kehendak pengguna dan objek memiliki Dosen Pembimbing II
tekstur yang membuat tampilannya menjadi lebih
realistis.
2. Aplikasi dapat dikembangkan lebih lanjut dengan
menambahkan fasilitas untuk memuat objek geometri Eko Handoyo, S.T., M.T.
dari berkas berekstensi .obj sehingga objek yang dapat NIP. 132 309 142
ditampilkan lebih bervariasi. Tanggal………………...

6. Referensi
[1] Baker, H., Computer Graphics with OpenGL, Third
Edition, Prentice Hall, New Jersey, 2004.
[2] Bambang, H., Grafik komputer dengan C, Penerbit
ANDI, 2004.
[3] Dharwiyanti S., Wahono R.S., Pengantar Unified
Modelling Language (UML), ilmukomputer.com,
2003.
[4] Maksimchuk, R.A., Naiburg, E.J., UML for Mere
Mortals, Addison Wesley Proffesional, October 26th,
2004.
[5] Nugroho, Edi., Teori dan Praktek gafika Komputer
Menggunakan Delphi dan OpenGL, Penerbit Graha
ilmu, 2005.
[6] Pressman, R.S., Rekayasa Perangkat Lunak
Pendekatan Praktisi, Buku Satu dan Dua, McGraw-
Hil Book Co., Penerbit ANDI, 2003.
[7] Susilo, D., Gafika Komputer dengan Delphi, Penerbit
Graha ilmu, 2005.
[8] ---, http://www.autodesk.com/, Maret 2006.
[9] ---, http://www.caperaven.co.za/, Maret 2006.
[10] ---, http://www.blender.org/, Maret 2006.
[11] ---, http://www.delphi3d.net/, Maret 2006.
[12] ---, http://www.sulaco.co.za/, Maret 2006.

Anda mungkin juga menyukai