Sie sind auf Seite 1von 85

PRAKTIKUM GRAFIKA KOMPUTER

Pertemuan ke-7 (Kurva Spline)

Syifa Fauziah
2006133

JURUSAN ILMU KOMPUTER


PROGRAM STUDI TEKNIK INFORMATIKA
INSTITUT TEKNOLOGI GARUT
JL. MAYOR SYAMSU NO. 1 JAYARAGA GARUT 44151 INDONESIA

1
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

I. PENDAHULUAN
Kurva spline
merupakan kurva yang digambar secara fleksibel untuk menghasilkan kurva yang smooth melalui
titik-titik kontrolnya. Untuk menjaga agar kurva tetap smooth maka diperlukan kontinuitas di titik-
titik kontrolnya. Kurva spline mempunyai ciri khas yaitu mempunyai titik control yang ditentukan
user dan titik control tersebut yang akan di interpolasi menjadi kurva. Jenis-jenis kurva spline
diantaranya:
Kubik spline menggunakan fungsi polynomial pangkat tiga dengan masukan 4 titik control. Untuk
membuat kurva sebelumnya harus diketahui terlebih dahulu koefisien polynomial dari keempat titik
kontrol tadi.

Catmull-Rom Spline
Catmull-Rom spline menginterpolasi titik tengah pada titik control. Bila diberikan 4 titik control 0,
1, 2, 3 maka yang diinterpolasi titik tengahnya saja.
- (0)= 1
- (1)= 2
Hitung tangent
- ′(0)≈ 2− 02
- ′(1)≈ 3− 12
Rumus catmull-rom spline dapat dituliskan
= dimana

2
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

Bezier Spline
Bezier spline menggunakan titik ujung dari titik control untuk interpolasi kemudian menghitung arah
tangen untuk menentukan arah kurva. Bila diketahui 2 titik control 0 dan 3.

3
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

II. PEMBAHASAN

A. Source Code 1

kurva spline cubic

#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// header untuk GLUT
#include <gl/glut.h>
using namespace std;
#define PHI 3.141592654
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 480
// container untuk membuat tipe data 3D (X, Y, Z)
struct Vec3
{
float X; float Y; float Z;
Vec3(float x, float y, float z) { X = x; Y = y; Z = z; }
//
Vec3() { }
~Vec3() { }
};
// inisialisasi variabel untuk kecepatan pergerakan kamera
// (akan digunakan di praktikum ke-5 tentang Proyeksi)
float fov = 45; // sudut proyeksi
float moveSpeed = 0.5f; // kecepatan pergerakan kamera
float rotateSpeed = 0.05f; // kecepatan rotasi kamera
// inisialisasi variabel untuk proyeksi
// (akan digunakan di praktikum ke-5 tentang Proyeksi)
// posisi kamera
Vec3 camPosition = Vec3(0.0f, 0.0f, 5.0f);
Vec3 camLookAt = Vec3(0.0f, 0.0f, -1.0f);
Vec3 camUp = Vec3(0.0f, 1.0f, 0.0f);
// sudut transformasi kamera
float camAngle = 0.0f;
// inisialisasi variabel untuk proyeksi dengan mouse
bool firstMouse = true;
float yaw = -90.0f;
float pitch = 0.0f;
float lastX = SCREEN_WIDTH / 2.0f;
float lastY = SCREEN_HEIGHT / 2.0f;
// inisialisasi variabel untuk transformasi
// seperti translasi, rotasi atau scaling

4
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// (akan digunakan di praktikum ke-4 tentang transformasi 2D/3D)


float objectAngle = 0.0f; // sudut tranformasi obyek
Vec3 objectRotation = Vec3(0.0f, 1.0f, 0.0f); // posisi rotasi
Vec3 objectPosition = Vec3(0.0f, 0.0f, 0.0f); // posisi obyek
// fungsi untuk melakukan normalisasi koordinat posisi
Vec3 normalize(Vec3 value)
{
Vec3 result;
float lengths = sqrt((value.X * value.X) + (value.Y * value.Y)
+ (value.Z * value.Z));
result.X = value.X / lengths;
result.Y = value.Y / lengths;
result.Z = value.Z / lengths;
return result;
}
// fungsi untuk melakukan operasi perkalian cross
Vec3 cross(Vec3 value1, Vec3 value2)
{
Vec3 result;
result.X = value1.Y * value2.Z - value2.Y * value1.Z;
result.Y = value1.Z * value2.X - value2.Z * value1.X;
result.Z = value1.X * value2.Y - value2.X * value1.Y;
return result;
}
// menggambar setiap titik kontrol kurva
void markPoint(Vec3 points, Vec3 colors, float width)
{
// tandai setiap titik dengan warna
glPushMatrix();
glColor3f(colors.X, colors.Y, colors.Z);
glBegin(GL_QUADS);
glVertex3f(points.X - width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y + width, points.Z);
glVertex3f(points.X - width, points.Y + width, points.Z);
glEnd();
glPopMatrix();
}
// fungsi untuk menghitung invers matriks ordo 4x4
bool inverse(float inMat[16], float outMat[16])
{
float inv[16], det;
int i;
inv[0] =
inMat[5] * inMat[10] * inMat[15] -
inMat[5] * inMat[11] * inMat[14] -
inMat[9] * inMat[6] * inMat[15] +
inMat[9] * inMat[7] * inMat[14] +

5
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[13] * inMat[6] * inMat[11] -


inMat[13] * inMat[7] * inMat[10];
inv[4] =
-inMat[4] * inMat[10] * inMat[15] +
inMat[4] * inMat[11] * inMat[14] +
inMat[8] * inMat[6] * inMat[15] -
inMat[8] * inMat[7] * inMat[14] -
inMat[12] * inMat[6] * inMat[11] +
inMat[12] * inMat[7] * inMat[10];
inv[8] =
inMat[4] * inMat[9] * inMat[15] -
inMat[4] * inMat[11] * inMat[13] -
inMat[8] * inMat[5] * inMat[15] +
inMat[8] * inMat[7] * inMat[13] +
inMat[12] * inMat[5] * inMat[11] -
inMat[12] * inMat[7] * inMat[9];
inv[12] =
-inMat[4] * inMat[9] * inMat[14] +
inMat[4] * inMat[10] * inMat[13] +
inMat[8] * inMat[5] * inMat[14] -
inMat[8] * inMat[6] * inMat[13] -
inMat[12] * inMat[5] * inMat[10] +
inMat[12] * inMat[6] * inMat[9];
inv[1] =
-inMat[1] * inMat[10] * inMat[15] +
inMat[1] * inMat[11] * inMat[14] +
inMat[9] * inMat[2] * inMat[15] -
inMat[9] * inMat[3] * inMat[14] -
inMat[13] * inMat[2] * inMat[11] +
inMat[13] * inMat[3] * inMat[10];
inv[5] =
inMat[0] * inMat[10] * inMat[15] -
inMat[0] * inMat[11] * inMat[14] -
inMat[8] * inMat[2] * inMat[15] +
inMat[8] * inMat[3] * inMat[14] +
inMat[12] * inMat[2] * inMat[11] -
inMat[12] * inMat[3] * inMat[10];
inv[9] =
-inMat[0] * inMat[9] * inMat[15] +
inMat[0] * inMat[11] * inMat[13] +
inMat[8] * inMat[1] * inMat[15] -
inMat[8] * inMat[3] * inMat[13] -
inMat[12] * inMat[1] * inMat[11] +
inMat[12] * inMat[3] * inMat[9];
inv[13] =
inMat[0] * inMat[9] * inMat[14] -
inMat[0] * inMat[10] * inMat[13] -
inMat[8] * inMat[1] * inMat[14] +

6
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[8] * inMat[2] * inMat[13] +


inMat[12] * inMat[1] * inMat[10] -
inMat[12] * inMat[2] * inMat[9];
inv[2] =
inMat[1] * inMat[6] * inMat[15] -
inMat[1] * inMat[7] * inMat[14] -
inMat[5] * inMat[2] * inMat[15] +
inMat[5] * inMat[3] * inMat[14] +
inMat[13] * inMat[2] * inMat[7] -
inMat[13] * inMat[3] * inMat[6];
inv[6] =
-inMat[0] * inMat[6] * inMat[15] +
inMat[0] * inMat[7] * inMat[14] +
inMat[4] * inMat[2] * inMat[15] -
inMat[4] * inMat[3] * inMat[14] -
inMat[12] * inMat[2] * inMat[7] +
inMat[12] * inMat[3] * inMat[6];
inv[10] =
inMat[0] * inMat[5] * inMat[15] -
inMat[0] * inMat[7] * inMat[13] -
inMat[4] * inMat[1] * inMat[15] +
inMat[4] * inMat[3] * inMat[13] +
inMat[12] * inMat[1] * inMat[7] -
inMat[12] * inMat[3] * inMat[5];
inv[14] =
-inMat[0] * inMat[5] * inMat[14] +
inMat[0] * inMat[6] * inMat[13] +
inMat[4] * inMat[1] * inMat[14] -
inMat[4] * inMat[2] * inMat[13] -
inMat[12] * inMat[1] * inMat[6] +
inMat[12] * inMat[2] * inMat[5];
inv[3] =
-inMat[1] * inMat[6] * inMat[11] +
inMat[1] * inMat[7] * inMat[10] +
inMat[5] * inMat[2] * inMat[11] -
inMat[5] * inMat[3] * inMat[10] -
inMat[9] * inMat[2] * inMat[7] +
inMat[9] * inMat[3] * inMat[6];
inv[7] =
inMat[0] * inMat[6] * inMat[11] -
inMat[0] * inMat[7] * inMat[10] -
inMat[4] * inMat[2] * inMat[11] +
inMat[4] * inMat[3] * inMat[10] +
inMat[8] * inMat[2] * inMat[7] -
inMat[8] * inMat[3] * inMat[6];
inv[11] =
-inMat[0] * inMat[5] * inMat[11] +
inMat[0] * inMat[7] * inMat[9] +

7
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[4] * inMat[1] * inMat[11] -


inMat[4] * inMat[3] * inMat[9] -
inMat[8] * inMat[1] * inMat[7] +
inMat[8] * inMat[3] * inMat[5];
inv[15] =
inMat[0] * inMat[5] * inMat[10] -
inMat[0] * inMat[6] * inMat[9] -
inMat[4] * inMat[1] * inMat[10] +
inMat[4] * inMat[2] * inMat[9] +
inMat[8] * inMat[1] * inMat[6] -
inMat[8] * inMat[2] * inMat[5];
det = inMat[0] * inv[0] + inMat[1] * inv[4] + inMat[2] * inv[8] + inMat[3] * inv[12];
if (det == 0)
return false;
det = 1.0 / det;
for (i = 0; i < 16; i++)
outMat[i] = inv[i] * det;
return true;
}
// fungsi untuk perkalian matriks 4x4 dengan 4x1
void DotMatrix(float inMat1[16], float inMat2[4], float outMat[4])
{
outMat[0] = inMat1[0] * inMat2[0] + inMat1[1] * inMat2[1] +
inMat1[2] * inMat2[2] + inMat1[3] * inMat2[3];
outMat[1] = inMat1[4] * inMat2[0] + inMat1[5] * inMat2[1] +
inMat1[6] * inMat2[2] + inMat1[7] * inMat2[3];
outMat[2] = inMat1[8] * inMat2[0] + inMat1[9] * inMat2[1] +
inMat1[10] * inMat2[2] + inMat1[11] * inMat2[3];
outMat[3] = inMat1[12] * inMat2[0] + inMat1[13] * inMat2[1] +
inMat1[14] * inMat2[2] + inMat1[15] * inMat2[3];
}
// fungsi untuk membuat kurva spline cubic dari 4 titik kontrol
// point1 sampai point4 = titik kontrol
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineCubic(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) + abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) / utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.00f, 0.00f, 0.00f, 0.00f,
1.00f, u2, pow(u2, 2), pow(u2, 3),
1.00f, u3, pow(u3, 2), pow(u3, 3),

8
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

1.00f, 1.00f, 1.00f, 1.00f };


bool status = inverse(coeffMat, inverseMat);
// hitung koefisien cubic au^3 + bu^2 + cu + d
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point2.X, point3.X, point4.X };
float inMatY[4] = { point1.Y, point2.Y, point3.Y, point4.Y };
float inMatZ[4] = { point1.Z, point2.Z, point3.Z, point4.Z };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva cubic spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan persamaan diatas
for (int i=0; i<nPoint; i++)
{
float step = 1.0f / nPoint; // jeda setiap titik pd bobot u
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva cubic spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] * pow(u, 2)
+ outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] * pow(u, 2)
+ outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] * pow(u, 2)
+ outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}
void drawSplineBezier(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) + abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) / utotal;
float u4 = 1;

9
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// hitung inverse matriks dari koefisien u (lihat slide kuliah)


float inverseMat[16];
float coeffMat[16] = {
1.00f, 0.00f, 0.00f, 0.00f,
1.00f, 1.00f, 1.00f, 1.00f,
0.00f, 1.00f, 0.00f, 0.00f,
0.00f, 1.00f, 2.00f, 3.00f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien cubic au^3 + bu^2 + cu + d
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
// rumus bezier
float inMatX[4] = { point1.X, point4.X,
1.0f/(u3-u1)*(point3.X - point1.X),
1.0f/(u4-u2)*(point4.X - point2.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u3-u1)*(point3.Y - point1.Y),
1.0f/(u4-u2)*(point4.Y - point2.Y) };
float inMatZ[4] = { point1.Z, point4.Z,
1.0f/(u3-u1)*(point3.Z - point1.Z),
1.0f/(u4-u2)*(point4.Z - point2.Z) };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva cubic spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan persamaan diatas
for (int i=0; i<nPoint; i++)
{
float step = 1.0f / nPoint; // jeda setiap titik pd bobot u
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva cubic spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] * pow(u, 2)
+ outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] * pow(u, 2)
+ outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] * pow(u, 2)
+ outMatZ[1] * u + outMatZ[0];

10
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

glVertex3f(pX, pY, pZ); // gambar titik akhir


}
}
}
}
// fungsi untuk membuat kurva spline catmull-rom dari 4 titik kontrol
// point1 dan point4 = titik kontrol awal dan akhir
// point2 dan point3 = titik kontrol pembentuk kurva
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineCatmullRom(Vec3 point1, Vec3 point2, Vec3 point3,
Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) +
abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) /
utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.0000f, 0.0000f, 0.0000f, 0.0000f,
1.0000f, 1.0000f, 1.0000f, 1.0000f,
0.0000f, 1.0000f, 0.0000f, 0.0000f,
0.0000f, 1.0000f, 2.0000f, 3.0000f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point4.X,
1.0f/(u3-u1)*(point3.X - point1.X),
1.0f/(u4-u2)*(point4.X - point2.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u3-u1)*(point3.Y - point1.Y),
1.0f/(u4-u2)*(point4.Y - point2.Y) };
float inMatZ[4] = { point1.Z, point4.Z,
1.0f/(u3-u1)*(point3.Z - point1.Z),
1.0f/(u4-u2)*(point4.Z - point2.Z) };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan
// persamaan diatas
for (int i=0; i<nPoint; i++)

11
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

{
// jeda setiap titik pd bobot u
float step = 1.0f / nPoint;
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] *
pow(u, 2) + outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] *
pow(u, 2) + outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] *
pow(u, 2) + outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}
// fungsi ini digunakan untuk menggambar obyek
void drawObject()
{
glPushMatrix();
glRotatef(objectAngle, objectRotation.X, objectRotation.Y, objectRotation.Z);
// membuat 4 titik kontrol kurva
Vec3 point1 = Vec3(-150.0f, -70.0f, 0.0f);
Vec3 point2 = Vec3( -50.0f, 50.0f, 0.0f);
Vec3 point3 = Vec3( 50.0f, 10.0f, 0.0f);
Vec3 point4 = Vec3( 150.0f, -50.0f, 0.0f);
// tandai setiap titik kontrol kurva dengan warna
markPoint(point1, Vec3(0.0f, 1.0f, 0.0f), 5.0f);
markPoint(point2, Vec3(1.0f, 0.0f, 0.0f), 5.0f);
markPoint(point3, Vec3(1.0f, 0.0f, 1.0f), 5.0f);
markPoint(point4, Vec3(1.0f, 1.0f, 0.0f), 5.0f);
// mengatur warna obyek menjadi berwarna putih
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_LINES);
// membuat kurva spline cubic dari titik kontrol diatas
drawSplineCubic(point1, point2, point3, point4, 30);
glEnd();
glPopMatrix();

12
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

}
// taruh semua fungsi obyek yang akan digambar di fungsi display()
void display()
{
// bersihkan dan reset layar dan buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// posisikan pandangan kamera
// dalam hal ini sumbu Y kamera ada di atas
// dan posisi kamera di camPosition
gluLookAt(camPosition.X, camPosition.Y, camPosition.Z,
camPosition.X + camLookAt.X,
camPosition.Y + camLookAt.Y,
camPosition.Z + camLookAt.Z,
camUp.X, camUp.Y, camUp.Z);
// panggil fungsi untuk menggambar obyek
drawObject();
// tampilkan obyek ke layar
// gunakan glFlush() bila memakai single buffer
// gunakan glutSwapBuffers() bila memakai double buffer
glutSwapBuffers();
}
// inisialisasikan variabel, pencahayaan, tekstur,
// pengaturan pandangan kamera dan sebagainya di fungsi init()
void init(void)
{
// inisialisasi warna latar belakang layar
// dalam hal ini warna putih warna hitam (0.0, 0.0, 0.0, 0.0)
glClearColor(0.0, 0.0, 0.0, 0.0);
// mengaktifkan depth buffer
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// set proyeksi ke proyeksi perspektif
//gluPerspective(fov, 1.0, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// inisialisasi kamera pandang
// kamera berada di posisi (0.0f, 0.0f, 0.0f)
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
// fungsi ini digunakan bila layar akan diresize (default)
// (akan dijelaskan pada praktikum ke-5)
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);

13
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(fov, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
// fungsi untuk mengatur masukan dari keyboard
void keyboard(unsigned char key, int x, int y)
{
Vec3 result = normalize(cross(camLookAt, camUp));
switch (key)
{
case 'w': // bila tombol 'w' pada keyboard ditekan
// geser pandangan kamera ke depan
camPosition.X += moveSpeed * camLookAt.X;
camPosition.Y += moveSpeed * camLookAt.Y;
camPosition.Z += moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;
case 's': // bila tombol 's' pada keyboard ditekan
// geser pandangan kamera ke belakang
camPosition.X -= moveSpeed * camLookAt.X;
camPosition.Y -= moveSpeed * camLookAt.Y;
camPosition.Z -= moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;
case 'a': // bila tombol 'a' pada keyboard ditekan
// geser pandangan kamera ke ke kiri
camPosition.X -= moveSpeed * result.X;
camPosition.Y -= moveSpeed * result.Y;
camPosition.Z -= moveSpeed * result.Z;
glutPostRedisplay();
break;
case 'd': // bila tombol 'd' pada keyboard ditekan
// geser pandangan kamera ke kanan
camPosition.X += moveSpeed * result.X;
camPosition.Y += moveSpeed * result.Y;
camPosition.Z += moveSpeed * result.Z;
glutPostRedisplay();
break;
case 'f': // bila tombol 'f' pada keyboard ditekan
// percepat laju pergerakan kamera
moveSpeed = moveSpeed + 0.5f;
glutPostRedisplay();
break;
case 'g': // bila tombol 'g' pada keyboard ditekan
// perlambat laju pergerakan kamera

14
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

moveSpeed = moveSpeed - 0.5f > 0.5f ? moveSpeed - 0.5f : 0.5f;


glutPostRedisplay();
break;
case 27: // bila tombol 'esc' pada keyboard ditekan
// keluar program
exit(0);
break;
}
}
// fungsi untuk mengatur masukan tombol dari mouse
void mousebutton(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_UP)
firstMouse = false;
else
firstMouse = true;
}
}
// fungsi untuk mengatur masukan pergerakan dari mouse
void mousemove(int x, int y)
{
if (firstMouse)
{
lastX = x; lastY =
y; firstMouse =
false;
}
GLfloat xoffset = x - lastX;
GLfloat yoffset = lastY - y;
lastX = x;
lastY = y;
GLfloat sensitivity = 0.05;
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
Vec3 front;
front.X = cos(yaw * PHI / 180) * cos(pitch * PHI / 180);
front.Y = sin(pitch * PHI / 180);
front.Z = sin(yaw * PHI / 180) * cos(pitch * PHI / 180);
camLookAt = normalize(front);
glutPostRedisplay();

15
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

}
// timer untuk animasi (gunakan bila perlu)
void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(55, timer, 0);
}
// program utama
int main(int argc, char** argv)
{
// inisialisasi jendela OpenGL
// GLUT_SINGLE berarti memakai single buffer
// GLUT_DOUBLE berarti memakai double buffer
// GLUT_RGB berarti mode tampilan yang dipakai RGB
// GLUT_RGBA berarti mode tampilan yang dipakai RGBA
// GLUT_DEPTH berarti memakai depth buffer
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
// set ukuran jendela tampilan
// besarnya jendela dalam piksel dalam hal ini 480x480
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
// posisi jendela dilayar komputer dalam piksel
glutInitWindowPosition(100, 100);
// judul jendela (wajib diubah dengan informasi
// NAMA / NIM - JUDUL PRAKTIKUM masing-masing)
glutCreateWindow("Syifa Fauziah_2006133_Grafkom -Cubic");
// panggil fungsi init untuk melakukan inisialisasi awal
init();
// event handler untuk display, reshape dan keyboard
glutDisplayFunc(display); // display
glutReshapeFunc(reshape); // reshape
glutKeyboardFunc(keyboard); // keyboard
glutMouseFunc(mousebutton); // mouse button
glutMotionFunc(mousemove); // mouse movement
//glutTimerFunc(0, timer, 0); // aktifkan timer bila perlu
// looping
glutMainLoop();
return 0;
}

16
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

bezier
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// header untuk GLUT
#include <gl/glut.h>
using namespace std;
#define PHI 3.14
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 480
// container untuk membuat tipe data 3D (X, Y, Z)
struct Vec3
{
float X; float Y; float Z;
Vec3(float x, float y, float z) { X = x; Y = y; Z = z; }
//
Vec3() { }
~Vec3() { }
};
// inisialisasi variabel untuk kecepatan pergerakan kamera
// (akan digunakan di praktikum ke-5 tentang Proyeksi)
float fov = 45; // sudut proyeksi
float moveSpeed = 0.5f; // kecepatan pergerakan kamera
float rotateSpeed = 0.05f; // kecepatan rotasi kamera
// inisialisasi variabel untuk proyeksi

17
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// (akan digunakan di praktikum ke-5 tentang Proyeksi)


// posisi kamera
Vec3 camPosition = Vec3(0.0f, 0.0f, 5.0f);
Vec3 camLookAt = Vec3(0.0f, 0.0f, -1.0f);
Vec3 camUp = Vec3(0.0f, 1.0f, 0.0f);
// sudut transformasi kamera
float camAngle = 0.0f;
// inisialisasi variabel untuk proyeksi dengan mouse
bool firstMouse = true;
float yaw = -90.0f;
float pitch = 0.0f;
float lastX = SCREEN_WIDTH / 2.0f;
float lastY = SCREEN_HEIGHT / 2.0f;
// inisialisasi variabel untuk transformasi
// seperti translasi, rotasi atau scaling
// (akan digunakan di praktikum ke-4 tentang transformasi 2D/3D)
float objectAngle = 0.0f; // sudut tranformasi obyek
Vec3 objectRotation = Vec3(0.0f, 1.0f, 0.0f); // posisi rotasi
Vec3 objectPosition = Vec3(0.0f, 0.0f, 0.0f); // posisi obyek
// fungsi untuk melakukan normalisasi koordinat posisi
Vec3 normalize(Vec3 value)
{
Vec3 result;
float lengths = sqrt((value.X * value.X) + (value.Y * value.Y)
+ (value.Z * value.Z));
result.X = value.X / lengths;
result.Y = value.Y / lengths;
result.Z = value.Z / lengths;
return result;
}
// fungsi untuk melakukan operasi perkalian cross
Vec3 cross(Vec3 value1, Vec3 value2)
{
Vec3 result;
result.X = value1.Y * value2.Z - value2.Y * value1.Z;
result.Y = value1.Z * value2.X - value2.Z * value1.X;
result.Z = value1.X * value2.Y - value2.X * value1.Y;
return result;
}
// menggambar setiap titik kontrol kurva
void markPoint(Vec3 points, Vec3 colors, float width)
{
// tandai setiap titik dengan warna
glPushMatrix();
glColor3f(colors.X, colors.Y, colors.Z);
glBegin(GL_QUADS);
glVertex3f(points.X - width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y + width, points.Z);

18
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

glVertex3f(points.X - width, points.Y + width, points.Z);


glEnd();
glPopMatrix();
}
// fungsi untuk menghitung invers matriks ordo 4x4
bool inverse(float inMat[16], float outMat[16])
{
float inv[16], det;
int i;
inv[0] =
inMat[5] * inMat[10] * inMat[15] -
inMat[5] * inMat[11] * inMat[14] -
inMat[9] * inMat[6] * inMat[15] +
inMat[9] * inMat[7] * inMat[14] +
inMat[13] * inMat[6] * inMat[11] -
inMat[13] * inMat[7] * inMat[10];
inv[4] =
-inMat[4] * inMat[10] * inMat[15] +
inMat[4] * inMat[11] * inMat[14] +
inMat[8] * inMat[6] * inMat[15] -
inMat[8] * inMat[7] * inMat[14] -
inMat[12] * inMat[6] * inMat[11] +
inMat[12] * inMat[7] * inMat[10];
inv[8] =
inMat[4] * inMat[9] * inMat[15] -
inMat[4] * inMat[11] * inMat[13] -
inMat[8] * inMat[5] * inMat[15] +
inMat[8] * inMat[7] * inMat[13] +
inMat[12] * inMat[5] * inMat[11] -
inMat[12] * inMat[7] * inMat[9];
inv[12] =
-inMat[4] * inMat[9] * inMat[14] +
inMat[4] * inMat[10] * inMat[13] +
inMat[8] * inMat[5] * inMat[14] -
inMat[8] * inMat[6] * inMat[13] -
inMat[12] * inMat[5] * inMat[10] +
inMat[12] * inMat[6] * inMat[9];
inv[1] =
-inMat[1] * inMat[10] * inMat[15] +
inMat[1] * inMat[11] * inMat[14] +
inMat[9] * inMat[2] * inMat[15] -
inMat[9] * inMat[3] * inMat[14] -
inMat[13] * inMat[2] * inMat[11] +
inMat[13] * inMat[3] * inMat[10];
inv[5] =
inMat[0] * inMat[10] * inMat[15] -
inMat[0] * inMat[11] * inMat[14] -
inMat[8] * inMat[2] * inMat[15] +
inMat[8] * inMat[3] * inMat[14] +

19
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[12] * inMat[2] * inMat[11] -


inMat[12] * inMat[3] * inMat[10];
inv[9] =
-inMat[0] * inMat[9] * inMat[15] +
inMat[0] * inMat[11] * inMat[13] +
inMat[8] * inMat[1] * inMat[15] -
inMat[8] * inMat[3] * inMat[13] -
inMat[12] * inMat[1] * inMat[11] +
inMat[12] * inMat[3] * inMat[9];
inv[13] =
inMat[0] * inMat[9] * inMat[14] -
inMat[0] * inMat[10] * inMat[13] -
inMat[8] * inMat[1] * inMat[14] +
inMat[8] * inMat[2] * inMat[13] +
inMat[12] * inMat[1] * inMat[10] -
inMat[12] * inMat[2] * inMat[9];
inv[2] =
inMat[1] * inMat[6] * inMat[15] -
inMat[1] * inMat[7] * inMat[14] -
inMat[5] * inMat[2] * inMat[15] +
inMat[5] * inMat[3] * inMat[14] +
inMat[13] * inMat[2] * inMat[7] -
inMat[13] * inMat[3] * inMat[6];
inv[6] =
-inMat[0] * inMat[6] * inMat[15] +
inMat[0] * inMat[7] * inMat[14] +
inMat[4] * inMat[2] * inMat[15] -
inMat[4] * inMat[3] * inMat[14] -
inMat[12] * inMat[2] * inMat[7] +
inMat[12] * inMat[3] * inMat[6];
inv[10] =
inMat[0] * inMat[5] * inMat[15] -
inMat[0] * inMat[7] * inMat[13] -
inMat[4] * inMat[1] * inMat[15] +
inMat[4] * inMat[3] * inMat[13] +
inMat[12] * inMat[1] * inMat[7] -
inMat[12] * inMat[3] * inMat[5];
inv[14] =
-inMat[0] * inMat[5] * inMat[14] +
inMat[0] * inMat[6] * inMat[13] +
inMat[4] * inMat[1] * inMat[14] -
inMat[4] * inMat[2] * inMat[13] -
inMat[12] * inMat[1] * inMat[6] +
inMat[12] * inMat[2] * inMat[5];
inv[3] =
-inMat[1] * inMat[6] * inMat[11] +
inMat[1] * inMat[7] * inMat[10] +
inMat[5] * inMat[2] * inMat[11] -
inMat[5] * inMat[3] * inMat[10] -

20
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[9] * inMat[2] * inMat[7] +


inMat[9] * inMat[3] * inMat[6];
inv[7] =
inMat[0] * inMat[6] * inMat[11] -
inMat[0] * inMat[7] * inMat[10] -
inMat[4] * inMat[2] * inMat[11] +
inMat[4] * inMat[3] * inMat[10] +
inMat[8] * inMat[2] * inMat[7] -
inMat[8] * inMat[3] * inMat[6];
inv[11] =
-inMat[0] * inMat[5] * inMat[11] +
inMat[0] * inMat[7] * inMat[9] +
inMat[4] * inMat[1] * inMat[11] -
inMat[4] * inMat[3] * inMat[9] -
inMat[8] * inMat[1] * inMat[7] +
inMat[8] * inMat[3] * inMat[5];
inv[15] =
inMat[0] * inMat[5] * inMat[10] -
inMat[0] * inMat[6] * inMat[9] -
inMat[4] * inMat[1] * inMat[10] +
inMat[4] * inMat[2] * inMat[9] +
inMat[8] * inMat[1] * inMat[6] -
inMat[8] * inMat[2] * inMat[5];
det = inMat[0] * inv[0] + inMat[1] * inv[4] + inMat[2] * inv[8] + inMat[3] * inv[12];
if (det == 0)
return false;
det = 1.0 / det;
for (i = 0; i < 16; i++)
outMat[i] = inv[i] * det;
return true;
}
// fungsi untuk perkalian matriks 4x4 dengan 4x1
void DotMatrix(float inMat1[16], float inMat2[4], float outMat[4])
{
outMat[0] = inMat1[0] * inMat2[0] + inMat1[1] * inMat2[1] +
inMat1[2] * inMat2[2] + inMat1[3] * inMat2[3];
outMat[1] = inMat1[4] * inMat2[0] + inMat1[5] * inMat2[1] +
inMat1[6] * inMat2[2] + inMat1[7] * inMat2[3];
outMat[2] = inMat1[8] * inMat2[0] + inMat1[9] * inMat2[1] +
inMat1[10] * inMat2[2] + inMat1[11] * inMat2[3];
outMat[3] = inMat1[12] * inMat2[0] + inMat1[13] * inMat2[1] +
inMat1[14] * inMat2[2] + inMat1[15] * inMat2[3];
}
// fungsi untuk membuat kurva spline cubic dari 4 titik kontrol
// point1 sampai point4 = titik kontrol
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineCubic(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik

21
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) + abs(point4.X - point3.X));


float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) / utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.00f, 0.00f, 0.00f, 0.00f,
1.00f, u2, pow(u2, 2), pow(u2, 3),
1.00f, u3, pow(u3, 2), pow(u3, 3),
1.00f, 1.00f, 1.00f, 1.00f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien cubic au^3 + bu^2 + cu + d
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point2.X, point3.X, point4.X };
float inMatY[4] = { point1.Y, point2.Y, point3.Y, point4.Y };
float inMatZ[4] = { point1.Z, point2.Z, point3.Z, point4.Z };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva cubic spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan persamaan diatas
for (int i=0; i<nPoint; i++)
{
float step = 1.0f / nPoint; // jeda setiap titik pd bobot u
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva cubic spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] * pow(u, 2)
+ outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] * pow(u, 2)
+ outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] * pow(u, 2)
+ outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}

22
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

}
}

// fungsi untuk membuat kurva spline bezier dari 4 titik kontrol


// point1 dan point4 = titik kontrol awal dan akhir
// point2 dan point3 = titik kontrol pembentuk kurva
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineBezier(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) +
abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) /
utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.0000f, 0.0000f, 0.0000f, 0.0000f,
1.0000f, 1.0000f, 1.0000f, 1.0000f,
0.0000f, 1.0000f, 0.0000f, 0.0000f,
0.0000f, 1.0000f, 2.0000f, 3.0000f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point4.X,
1.0f/(u2-u1)*(point2.X - point1.X),
1.0f/(u4-u3)*(point4.X - point3.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u2-u1)*(point2.Y - point1.Y),
1.0f/(u4-u3)*(point4.Y - point3.Y) };
float inMatZ[4] = { point1.Z, point4.Z,
1.0f/(u2-u1)*(point2.Z - point1.Z),
1.0f/(u4-u3)*(point4.Z - point3.Z) };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva cubic spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan
// persamaan diatas
for (int i=0; i<nPoint; i++)
{
// jeda setiap titik pd bobot u
float step = 1.0f / nPoint;
// titik awal

23
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

float pX = point1.X, pY = point1.Y, pZ = point1.Z;


//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] *
pow(u, 2) + outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] *
pow(u, 2) + outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] *
pow(u, 2) + outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}

void drawSplineCatmullRom(Vec3 point1, Vec3 point2, Vec3 point3,


Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) +
abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) /
utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.0000f, 0.0000f, 0.0000f, 0.0000f,
1.0000f, 1.0000f, 1.0000f, 1.0000f,
0.0000f, 1.0000f, 0.0000f, 0.0000f,
0.0000f, 1.0000f, 2.0000f, 3.0000f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point4.X,

24
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

1.0f/(u3-u1)*(point3.X - point1.X),
1.0f/(u4-u2)*(point4.X - point2.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u3-u1)*(point3.Y - point1.Y),
1.0f/(u4-u2)*(point4.Y - point2.Y) };
float inMatZ[4] = { point1.Z, point4.Z,
1.0f/(u3-u1)*(point3.Z - point1.Z),
1.0f/(u4-u2)*(point4.Z - point2.Z) };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan
// persamaan diatas
for (int i=0; i<nPoint; i++)
{
// jeda setiap titik pd bobot u
float step = 1.0f / nPoint;
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] *
pow(u, 2) + outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] *
pow(u, 2) + outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] *
pow(u, 2) + outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}
// fungsi ini digunakan untuk menggambar obyek
void drawObject()
{
glPushMatrix();
glRotatef(objectAngle, objectRotation.X, objectRotation.Y, objectRotation.Z);
// membuat 4 titik kontrol kurva
Vec3 point1 = Vec3(-150.0f, -70.0f, 0.0f);
Vec3 point2 = Vec3( -50.0f, 50.0f, 0.0f);

25
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

Vec3 point3 = Vec3( 50.0f, 10.0f, 0.0f);


Vec3 point4 = Vec3( 150.0f, -50.0f, 0.0f);
// tandai setiap titik kontrol kurva dengan warna
markPoint(point1, Vec3(0.0f, 1.0f, 0.0f), 5.0f);
markPoint(point2, Vec3(1.0f, 0.0f, 0.0f), 5.0f);
markPoint(point3, Vec3(1.0f, 0.0f, 1.0f), 5.0f);
markPoint(point4, Vec3(1.0f, 1.0f, 0.0f), 5.0f);
// mengatur warna obyek menjadi berwarna putih
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_LINES);
// membuat kurva spline cubic dari titik kontrol diatas
//drawSplineCatmullRom(point1,point2,point3,point4,30);
drawSplineBezier(point1,point2,point3,point4,30);
//drawSplineCubic(point1, point2, point3, point4, 30);
glEnd();
glPopMatrix();
}
// taruh semua fungsi obyek yang akan digambar di fungsi display()

void display()
{
// bersihkan dan reset layar dan buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// posisikan pandangan kamera
// dalam hal ini sumbu Y kamera ada di atas
// dan posisi kamera di camPosition
gluLookAt(camPosition.X, camPosition.Y, camPosition.Z,
camPosition.X + camLookAt.X,
camPosition.Y + camLookAt.Y,
camPosition.Z + camLookAt.Z,
camUp.X, camUp.Y, camUp.Z);
// panggil fungsi untuk menggambar obyek
drawObject();
// tampilkan obyek ke layar
// gunakan glFlush() bila memakai single buffer
// gunakan glutSwapBuffers() bila memakai double buffer
glutSwapBuffers();
}
// inisialisasikan variabel, pencahayaan, tekstur,
// pengaturan pandangan kamera dan sebagainya di fungsi init()
void init(void)
{
// inisialisasi warna latar belakang layar
// dalam hal ini warna putih warna hitam (0.0, 0.0, 0.0, 0.0)
glClearColor(0.0, 0.0, 0.0, 0.0);
// mengaktifkan depth buffer
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);

26
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

glLoadIdentity();
// set proyeksi ke proyeksi perspektif
//gluPerspective(fov, 1.0, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// inisialisasi kamera pandang
// kamera berada di posisi (0.0f, 0.0f, 0.0f)
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
// fungsi ini digunakan bila layar akan diresize (default)
// (akan dijelaskan pada praktikum ke-5)
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(fov, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
// fungsi untuk mengatur masukan dari keyboard
void keyboard(unsigned char key, int x, int y)
{
Vec3 result = normalize(cross(camLookAt, camUp));
switch (key)
{
case 'w': // bila tombol 'w' pada keyboard ditekan
// geser pandangan kamera ke depan
camPosition.X += moveSpeed * camLookAt.X;
camPosition.Y += moveSpeed * camLookAt.Y;
camPosition.Z += moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;
case 's': // bila tombol 's' pada keyboard ditekan
// geser pandangan kamera ke belakang
camPosition.X -= moveSpeed * camLookAt.X;
camPosition.Y -= moveSpeed * camLookAt.Y;
camPosition.Z -= moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;
case 'a': // bila tombol 'a' pada keyboard ditekan
// geser pandangan kamera ke ke kiri
camPosition.X -= moveSpeed * result.X;
camPosition.Y -= moveSpeed * result.Y;
camPosition.Z -= moveSpeed * result.Z;
glutPostRedisplay();

27
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

break;
case 'd': // bila tombol 'd' pada keyboard ditekan
// geser pandangan kamera ke kanan
camPosition.X += moveSpeed * result.X;
camPosition.Y += moveSpeed * result.Y;
camPosition.Z += moveSpeed * result.Z;
glutPostRedisplay();
break;
case 'f': // bila tombol 'f' pada keyboard ditekan
// percepat laju pergerakan kamera
moveSpeed = moveSpeed + 0.5f;
glutPostRedisplay();
break;
case 'g': // bila tombol 'g' pada keyboard ditekan
// perlambat laju pergerakan kamera
moveSpeed = moveSpeed - 0.5f > 0.5f ? moveSpeed - 0.5f : 0.5f;
glutPostRedisplay();
break;
case 27: // bila tombol 'esc' pada keyboard ditekan
// keluar program
exit(0);
break;
}
}
// fungsi untuk mengatur masukan tombol dari mouse
void mousebutton(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_UP)
firstMouse = false;
else
firstMouse = true;
}
}
// fungsi untuk mengatur masukan pergerakan dari mouse
void mousemove(int x, int y)
{
if (firstMouse)
{
lastX = x; lastY =
y; firstMouse =
false;
}
GLfloat xoffset = x - lastX;
GLfloat yoffset = lastY - y;
lastX = x;
lastY = y;
GLfloat sensitivity = 0.05;

28
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
Vec3 front;
front.X = cos(yaw * PHI / 180) * cos(pitch * PHI / 180);
front.Y = sin(pitch * PHI / 180);
front.Z = sin(yaw * PHI / 180) * cos(pitch * PHI / 180);
camLookAt = normalize(front);
glutPostRedisplay();
}
// timer untuk animasi (gunakan bila perlu)
void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(55, timer, 0);
}
// program utama
int main(int argc, char** argv)
{
// inisialisasi jendela OpenGL
// GLUT_SINGLE berarti memakai single buffer
// GLUT_DOUBLE berarti memakai double buffer
// GLUT_RGB berarti mode tampilan yang dipakai RGB
// GLUT_RGBA berarti mode tampilan yang dipakai RGBA
// GLUT_DEPTH berarti memakai depth buffer
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
// set ukuran jendela tampilan
// besarnya jendela dalam piksel dalam hal ini 480x480
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
// posisi jendela dilayar komputer dalam piksel
glutInitWindowPosition(100, 100);
// judul jendela (wajib diubah dengan informasi
// NAMA / NIM - JUDUL PRAKTIKUM masing-masing)
glutCreateWindow("2006133_Syifa Fauziah");
// panggil fungsi init untuk melakukan inisialisasi awal
init();
// event handler untuk display, reshape dan keyboard
glutDisplayFunc(display); // display
glutReshapeFunc(reshape); // reshape
glutKeyboardFunc(keyboard); // keyboard
glutMouseFunc(mousebutton); // mouse button
glutMotionFunc(mousemove); // mouse movement
//glutTimerFunc(0, timer, 0); // aktifkan timer bila perlu

29
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// looping
glutMainLoop();
return 0;
}

Catmull-rom

#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// header untuk GLUT
#include <gl/glut.h>
using namespace std;
#define PHI 3.141592654
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 480
// container untuk membuat tipe data 3D (X, Y, Z)
struct Vec3
{
float X; float Y; float Z;
Vec3(float x, float y, float z) { X = x; Y = y; Z = z; }
//
Vec3() { }
~Vec3() { }
};
// inisialisasi variabel untuk kecepatan pergerakan kamera
// (akan digunakan di praktikum ke-5 tentang Proyeksi)

30
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

float fov = 45; // sudut proyeksi


float moveSpeed = 0.5f; // kecepatan pergerakan kamera
float rotateSpeed = 0.05f; // kecepatan rotasi kamera
// inisialisasi variabel untuk proyeksi
// (akan digunakan di praktikum ke-5 tentang Proyeksi)
// posisi kamera
Vec3 camPosition = Vec3(0.0f, 0.0f, 5.0f);
Vec3 camLookAt = Vec3(0.0f, 0.0f, -1.0f);
Vec3 camUp = Vec3(0.0f, 1.0f, 0.0f);
// sudut transformasi kamera
float camAngle = 0.0f;
// inisialisasi variabel untuk proyeksi dengan mouse
bool firstMouse = true;
float yaw = -90.0f;
float pitch = 0.0f;
float lastX = SCREEN_WIDTH / 2.0f;
float lastY = SCREEN_HEIGHT / 2.0f;
// inisialisasi variabel untuk transformasi
// seperti translasi, rotasi atau scaling
// (akan digunakan di praktikum ke-4 tentang transformasi 2D/3D)
float objectAngle = 0.0f; // sudut tranformasi obyek
Vec3 objectRotation = Vec3(0.0f, 1.0f, 0.0f); // posisi rotasi
Vec3 objectPosition = Vec3(0.0f, 0.0f, 0.0f); // posisi obyek
// fungsi untuk melakukan normalisasi koordinat posisi
Vec3 normalize(Vec3 value)
{
Vec3 result;
float lengths = sqrt((value.X * value.X) + (value.Y * value.Y)
+ (value.Z * value.Z));
result.X = value.X / lengths;
result.Y = value.Y / lengths;
result.Z = value.Z / lengths;
return result;
}
// fungsi untuk melakukan operasi perkalian cross
Vec3 cross(Vec3 value1, Vec3 value2)
{
Vec3 result;
result.X = value1.Y * value2.Z - value2.Y * value1.Z;
result.Y = value1.Z * value2.X - value2.Z * value1.X;
result.Z = value1.X * value2.Y - value2.X * value1.Y;
return result;
}
// menggambar setiap titik kontrol kurva
void markPoint(Vec3 points, Vec3 colors, float width)
{
// tandai setiap titik dengan warna
glPushMatrix();
glColor3f(colors.X, colors.Y, colors.Z);

31
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

glBegin(GL_QUADS);
glVertex3f(points.X - width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y + width, points.Z);
glVertex3f(points.X - width, points.Y + width, points.Z);
glEnd();
glPopMatrix();
}
// fungsi untuk menghitung invers matriks ordo 4x4
bool inverse(float inMat[16], float outMat[16])
{
float inv[16], det;
int i;
inv[0] =
inMat[5] * inMat[10] * inMat[15] -
inMat[5] * inMat[11] * inMat[14] -
inMat[9] * inMat[6] * inMat[15] +
inMat[9] * inMat[7] * inMat[14] +
inMat[13] * inMat[6] * inMat[11] -
inMat[13] * inMat[7] * inMat[10];
inv[4] =
-inMat[4] * inMat[10] * inMat[15] +
inMat[4] * inMat[11] * inMat[14] +
inMat[8] * inMat[6] * inMat[15] -
inMat[8] * inMat[7] * inMat[14] -
inMat[12] * inMat[6] * inMat[11] +
inMat[12] * inMat[7] * inMat[10];
inv[8] =
inMat[4] * inMat[9] * inMat[15] -
inMat[4] * inMat[11] * inMat[13] -
inMat[8] * inMat[5] * inMat[15] +
inMat[8] * inMat[7] * inMat[13] +
inMat[12] * inMat[5] * inMat[11] -
inMat[12] * inMat[7] * inMat[9];
inv[12] =
-inMat[4] * inMat[9] * inMat[14] +
inMat[4] * inMat[10] * inMat[13] +
inMat[8] * inMat[5] * inMat[14] -
inMat[8] * inMat[6] * inMat[13] -
inMat[12] * inMat[5] * inMat[10] +
inMat[12] * inMat[6] * inMat[9];
inv[1] =
-inMat[1] * inMat[10] * inMat[15] +
inMat[1] * inMat[11] * inMat[14] +
inMat[9] * inMat[2] * inMat[15] -
inMat[9] * inMat[3] * inMat[14] -
inMat[13] * inMat[2] * inMat[11] +
inMat[13] * inMat[3] * inMat[10];
inv[5] =

32
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[0] * inMat[10] * inMat[15] -


inMat[0] * inMat[11] * inMat[14] -
inMat[8] * inMat[2] * inMat[15] +
inMat[8] * inMat[3] * inMat[14] +
inMat[12] * inMat[2] * inMat[11] -
inMat[12] * inMat[3] * inMat[10];
inv[9] =
-inMat[0] * inMat[9] * inMat[15] +
inMat[0] * inMat[11] * inMat[13] +
inMat[8] * inMat[1] * inMat[15] -
inMat[8] * inMat[3] * inMat[13] -
inMat[12] * inMat[1] * inMat[11] +
inMat[12] * inMat[3] * inMat[9];
inv[13] =
inMat[0] * inMat[9] * inMat[14] -
inMat[0] * inMat[10] * inMat[13] -
inMat[8] * inMat[1] * inMat[14] +
inMat[8] * inMat[2] * inMat[13] +
inMat[12] * inMat[1] * inMat[10] -
inMat[12] * inMat[2] * inMat[9];
inv[2] =
inMat[1] * inMat[6] * inMat[15] -
inMat[1] * inMat[7] * inMat[14] -
inMat[5] * inMat[2] * inMat[15] +
inMat[5] * inMat[3] * inMat[14] +
inMat[13] * inMat[2] * inMat[7] -
inMat[13] * inMat[3] * inMat[6];
inv[6] =
-inMat[0] * inMat[6] * inMat[15] +
inMat[0] * inMat[7] * inMat[14] +
inMat[4] * inMat[2] * inMat[15] -
inMat[4] * inMat[3] * inMat[14] -
inMat[12] * inMat[2] * inMat[7] +
inMat[12] * inMat[3] * inMat[6];
inv[10] =
inMat[0] * inMat[5] * inMat[15] -
inMat[0] * inMat[7] * inMat[13] -
inMat[4] * inMat[1] * inMat[15] +
inMat[4] * inMat[3] * inMat[13] +
inMat[12] * inMat[1] * inMat[7] -
inMat[12] * inMat[3] * inMat[5];
inv[14] =
-inMat[0] * inMat[5] * inMat[14] +
inMat[0] * inMat[6] * inMat[13] +
inMat[4] * inMat[1] * inMat[14] -
inMat[4] * inMat[2] * inMat[13] -
inMat[12] * inMat[1] * inMat[6] +
inMat[12] * inMat[2] * inMat[5];
inv[3] =

33
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

-inMat[1] * inMat[6] * inMat[11] +


inMat[1] * inMat[7] * inMat[10] +
inMat[5] * inMat[2] * inMat[11] -
inMat[5] * inMat[3] * inMat[10] -
inMat[9] * inMat[2] * inMat[7] +
inMat[9] * inMat[3] * inMat[6];
inv[7] =
inMat[0] * inMat[6] * inMat[11] -
inMat[0] * inMat[7] * inMat[10] -
inMat[4] * inMat[2] * inMat[11] +
inMat[4] * inMat[3] * inMat[10] +
inMat[8] * inMat[2] * inMat[7] -
inMat[8] * inMat[3] * inMat[6];
inv[11] =
-inMat[0] * inMat[5] * inMat[11] +
inMat[0] * inMat[7] * inMat[9] +
inMat[4] * inMat[1] * inMat[11] -
inMat[4] * inMat[3] * inMat[9] -
inMat[8] * inMat[1] * inMat[7] +
inMat[8] * inMat[3] * inMat[5];
inv[15] =
inMat[0] * inMat[5] * inMat[10] -
inMat[0] * inMat[6] * inMat[9] -
inMat[4] * inMat[1] * inMat[10] +
inMat[4] * inMat[2] * inMat[9] +
inMat[8] * inMat[1] * inMat[6] -
inMat[8] * inMat[2] * inMat[5];
det = inMat[0] * inv[0] + inMat[1] * inv[4] + inMat[2] * inv[8] + inMat[3] * inv[12];
if (det == 0)
return false;
det = 1.0 / det;
for (i = 0; i < 16; i++)
outMat[i] = inv[i] * det;
return true;
}
// fungsi untuk perkalian matriks 4x4 dengan 4x1
void DotMatrix(float inMat1[16], float inMat2[4], float outMat[4])
{
outMat[0] = inMat1[0] * inMat2[0] + inMat1[1] * inMat2[1] +
inMat1[2] * inMat2[2] + inMat1[3] * inMat2[3];
outMat[1] = inMat1[4] * inMat2[0] + inMat1[5] * inMat2[1] +
inMat1[6] * inMat2[2] + inMat1[7] * inMat2[3];
outMat[2] = inMat1[8] * inMat2[0] + inMat1[9] * inMat2[1] +
inMat1[10] * inMat2[2] + inMat1[11] * inMat2[3];
outMat[3] = inMat1[12] * inMat2[0] + inMat1[13] * inMat2[1] +
inMat1[14] * inMat2[2] + inMat1[15] * inMat2[3];
}
// fungsi untuk membuat kurva spline cubic dari 4 titik kontrol
// point1 sampai point4 = titik kontrol

34
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// nPoint = jumlah titik interpolasi antara point1 sampai point4


// fungsi untuk membuat kurva spline bezier dari 4 titik kontrol
// point1 sampai point4 = titik kontrol
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineBezier(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = 1.0f;
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = abs(point3.X - point2.X) / utotal;
float u4 = 1;

// hitung inverse matriks dari koefisien u (lihat slide kuliah)


float inverseMat[16];
float coeffMat[16] = {
-1.0f, 3.0f, -3.0f, 1.0f,
3.0f, -6.0f, 3.0f, 0.0f,
-3.0f, 3.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 0.0f
};

bool status = inverse(coeffMat, inverseMat);

// hitung koefisien bezier


if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];

float inMatX[4] = { point1.X, point2.X, point3.X, point4.X };


float inMatY[4] = { point1.Y, point2.Y, point3.Y, point4.Y };
float inMatZ[4] = { point1.Z, point2.Z, point3.Z, point4.Z };

DotMatrix(inverseMat, inMatX, outMatX);


DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);

// gambar kurva bezier dengan titik kontrol diatas


// hitung posisi y untuk setiap x di setiap point dengan persamaan diatas
for (int i = 0; i < nPoint; i++)
{
float step = 1.0f / nPoint; // jeda setiap titik pd bobot u
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;

float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva bezier sebanyak nPoint

35
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal

// koordinat X pada kurva


pX = outMatX[3] * pow(u, 3) + outMatX[2] * pow(u, 2) + outMatX[1] * u +
outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] * pow(u, 2) + outMatY[1] * u +
outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] * pow(u, 2) + outMatZ[1] * u +
outMatZ[0];

glVertex3f(pX, pY, pZ); // gambar titik akhir


}
}
}
}
void drawSplineCubic(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) + abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) / utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.00f, 0.00f, 0.00f, 0.00f,
1.00f, 1.00f, 1.00f, 1.00f,
0.00f, 1.00f, 0.00f, 0.00f,
0.00f, 1.00f, 2.00f, 3.00f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien cubic au^3 + bu^2 + cu + d
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
// rumus bezier
float inMatX[4] = { point1.X, point4.X,
1.0f/(u3-u1)*(point3.X - point1.X),
1.0f/(u4-u2)*(point4.X - point2.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u3-u1)*(point3.Y - point1.Y),
1.0f/(u4-u2)*(point4.Y - point2.Y) };
float inMatZ[4] = { point1.Z, point4.Z,
1.0f/(u3-u1)*(point3.Z - point1.Z),
1.0f/(u4-u2)*(point4.Z - point2.Z) };
DotMatrix(inverseMat, inMatX, outMatX);

36
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

DotMatrix(inverseMat, inMatY, outMatY);


DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva cubic spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan persamaan diatas
for (int i=0; i<nPoint; i++)
{
float step = 1.0f / nPoint; // jeda setiap titik pd bobot u
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva cubic spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] * pow(u, 2)
+ outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] * pow(u, 2)
+ outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] * pow(u, 2)
+ outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}
// fungsi untuk membuat kurva spline catmull-rom dari 4 titik kontrol
// point1 dan point4 = titik kontrol awal dan akhir
// point2 dan point3 = titik kontrol pembentuk kurva
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineCatmullRom(Vec3 point1, Vec3 point2, Vec3 point3,
Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) +
abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) /
utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.0000f, 0.0000f, 0.0000f, 0.0000f,

37
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

1.0000f, 1.0000f, 1.0000f, 1.0000f,


0.0000f, 1.0000f, 0.0000f, 0.0000f,
0.0000f, 1.0000f, 2.0000f, 3.0000f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point4.X,
1.0f/(u3-u1)*(point3.X - point1.X),
1.0f/(u4-u2)*(point4.X - point2.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u3-u1)*(point3.Y - point1.Y),
1.0f/(u4-u2)*(point4.Y - point2.Y) };
float inMatZ[4] = { point1.Z, point4.Z,
1.0f/(u3-u1)*(point3.Z - point1.Z),
1.0f/(u4-u2)*(point4.Z - point2.Z) };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan
// persamaan diatas
for (int i=0; i<nPoint; i++)
{
// jeda setiap titik pd bobot u
float step = 1.0f / nPoint;
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] *
pow(u, 2) + outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] *
pow(u, 2) + outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] *
pow(u, 2) + outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}

38
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

}
// fungsi ini digunakan untuk menggambar obyek
void drawObject()
{
glPushMatrix();
glRotatef(objectAngle, objectRotation.X, objectRotation.Y, objectRotation.Z);
// membuat 4 titik kontrol kurva
Vec3 point1 = Vec3(-150.0f, -70.0f, 0.0f);
Vec3 point2 = Vec3( -50.0f, 50.0f, 0.0f);
Vec3 point3 = Vec3( 50.0f, 10.0f, 0.0f);
Vec3 point4 = Vec3( 150.0f, -50.0f, 0.0f);
// tandai setiap titik kontrol kurva dengan warna
markPoint(point1, Vec3(0.0f, 1.0f, 0.0f), 5.0f);
markPoint(point2, Vec3(1.0f, 0.0f, 0.0f), 5.0f);
markPoint(point3, Vec3(1.0f, 0.0f, 1.0f), 5.0f);
markPoint(point4, Vec3(1.0f, 1.0f, 0.0f), 5.0f);
// mengatur warna obyek menjadi berwarna putih
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_LINES);
// membuat kurva spline cubic dari titik kontrol diatas
drawSplineCubic(point1, point2, point3, point4, 30);
glEnd();
glPopMatrix();
}
// taruh semua fungsi obyek yang akan digambar di fungsi display()
void display()
{
// bersihkan dan reset layar dan buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// posisikan pandangan kamera
// dalam hal ini sumbu Y kamera ada di atas
// dan posisi kamera di camPosition
gluLookAt(camPosition.X, camPosition.Y, camPosition.Z,
camPosition.X + camLookAt.X,
camPosition.Y + camLookAt.Y,
camPosition.Z + camLookAt.Z,
camUp.X, camUp.Y, camUp.Z);
// panggil fungsi untuk menggambar obyek
drawObject();
// tampilkan obyek ke layar
// gunakan glFlush() bila memakai single buffer
// gunakan glutSwapBuffers() bila memakai double buffer
glutSwapBuffers();
}
// inisialisasikan variabel, pencahayaan, tekstur,
// pengaturan pandangan kamera dan sebagainya di fungsi init()
void init(void)
{

39
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// inisialisasi warna latar belakang layar


// dalam hal ini warna putih warna hitam (0.0, 0.0, 0.0, 0.0)
glClearColor(0.0, 0.0, 0.0, 0.0);
// mengaktifkan depth buffer
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// set proyeksi ke proyeksi perspektif
//gluPerspective(fov, 1.0, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// inisialisasi kamera pandang
// kamera berada di posisi (0.0f, 0.0f, 0.0f)
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
// fungsi ini digunakan bila layar akan diresize (default)
// (akan dijelaskan pada praktikum ke-5)
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(fov, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
// fungsi untuk mengatur masukan dari keyboard
void keyboard(unsigned char key, int x, int y)
{
Vec3 result = normalize(cross(camLookAt, camUp));
switch (key)
{
case 'w': // bila tombol 'w' pada keyboard ditekan
// geser pandangan kamera ke depan
camPosition.X += moveSpeed * camLookAt.X;
camPosition.Y += moveSpeed * camLookAt.Y;
camPosition.Z += moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;
case 's': // bila tombol 's' pada keyboard ditekan
// geser pandangan kamera ke belakang
camPosition.X -= moveSpeed * camLookAt.X;
camPosition.Y -= moveSpeed * camLookAt.Y;
camPosition.Z -= moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;

40
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

case 'a': // bila tombol 'a' pada keyboard ditekan


// geser pandangan kamera ke ke kiri
camPosition.X -= moveSpeed * result.X;
camPosition.Y -= moveSpeed * result.Y;
camPosition.Z -= moveSpeed * result.Z;
glutPostRedisplay();
break;
case 'd': // bila tombol 'd' pada keyboard ditekan
// geser pandangan kamera ke kanan
camPosition.X += moveSpeed * result.X;
camPosition.Y += moveSpeed * result.Y;
camPosition.Z += moveSpeed * result.Z;
glutPostRedisplay();
break;
case 'f': // bila tombol 'f' pada keyboard ditekan
// percepat laju pergerakan kamera
moveSpeed = moveSpeed + 0.5f;
glutPostRedisplay();
break;
case 'g': // bila tombol 'g' pada keyboard ditekan
// perlambat laju pergerakan kamera
moveSpeed = moveSpeed - 0.5f > 0.5f ? moveSpeed - 0.5f : 0.5f;
glutPostRedisplay();
break;
case 27: // bila tombol 'esc' pada keyboard ditekan
// keluar program
exit(0);
break;
}
}
// fungsi untuk mengatur masukan tombol dari mouse
void mousebutton(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_UP)
firstMouse = false;
else
firstMouse = true;
}
}
// fungsi untuk mengatur masukan pergerakan dari mouse
void mousemove(int x, int y)
{
if (firstMouse)
{
lastX = x; lastY =
y; firstMouse =
false;

41
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

}
GLfloat xoffset = x - lastX;
GLfloat yoffset = lastY - y;
lastX = x;
lastY = y;
GLfloat sensitivity = 0.05;
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
Vec3 front;
front.X = cos(yaw * PHI / 180) * cos(pitch * PHI / 180);
front.Y = sin(pitch * PHI / 180);
front.Z = sin(yaw * PHI / 180) * cos(pitch * PHI / 180);
camLookAt = normalize(front);
glutPostRedisplay();
}
// timer untuk animasi (gunakan bila perlu)
void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(55, timer, 0);
}
// program utama
int main(int argc, char** argv)
{
// inisialisasi jendela OpenGL
// GLUT_SINGLE berarti memakai single buffer
// GLUT_DOUBLE berarti memakai double buffer
// GLUT_RGB berarti mode tampilan yang dipakai RGB
// GLUT_RGBA berarti mode tampilan yang dipakai RGBA
// GLUT_DEPTH berarti memakai depth buffer
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
// set ukuran jendela tampilan
// besarnya jendela dalam piksel dalam hal ini 480x480
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
// posisi jendela dilayar komputer dalam piksel
glutInitWindowPosition(100, 100);
// judul jendela (wajib diubah dengan informasi
// NAMA / NIM - JUDUL PRAKTIKUM masing-masing)
glutCreateWindow("Syifa Fauziah_2006133");
// panggil fungsi init untuk melakukan inisialisasi awal
init();
// event handler untuk display, reshape dan keyboard

42
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

glutDisplayFunc(display); // display
glutReshapeFunc(reshape); // reshape
glutKeyboardFunc(keyboard); // keyboard
glutMouseFunc(mousebutton); // mouse button
glutMotionFunc(mousemove); // mouse movement
//glutTimerFunc(0, timer, 0); // aktifkan timer bila perlu
// looping
glutMainLoop();
return 0;
}

B. Source Code 2 (Berbeda warna tiap titik)

Kurva spline cubic


#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// header untuk GLUT
#include <gl/glut.h>
using namespace std;
#define PHI 3.141592654
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 480

43
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// container untuk membuat tipe data 3D (X, Y, Z)


struct Vec3
{
float X; float Y; float Z;
Vec3(float x, float y, float z) { X = x; Y = y; Z = z; }
//
Vec3() { }
~Vec3() { }
};
// inisialisasi variabel untuk kecepatan pergerakan kamera
// (akan digunakan di praktikum ke-5 tentang Proyeksi)
float fov = 45; // sudut proyeksi
float moveSpeed = 0.5f; // kecepatan pergerakan kamera
float rotateSpeed = 0.05f; // kecepatan rotasi kamera
// inisialisasi variabel untuk proyeksi
// (akan digunakan di praktikum ke-5 tentang Proyeksi)
// posisi kamera
Vec3 camPosition = Vec3(0.0f, 0.0f, 5.0f);
Vec3 camLookAt = Vec3(0.0f, 0.0f, -1.0f);
Vec3 camUp = Vec3(0.0f, 1.0f, 0.0f);
// sudut transformasi kamera
float camAngle = 0.0f;
// inisialisasi variabel untuk proyeksi dengan mouse
bool firstMouse = true;
float yaw = -90.0f;
float pitch = 0.0f;
float lastX = SCREEN_WIDTH / 2.0f;
float lastY = SCREEN_HEIGHT / 2.0f;
// inisialisasi variabel untuk transformasi
// seperti translasi, rotasi atau scaling
// (akan digunakan di praktikum ke-4 tentang transformasi 2D/3D)
float objectAngle = 0.0f; // sudut tranformasi obyek
Vec3 objectRotation = Vec3(0.0f, 1.0f, 0.0f); // posisi rotasi
Vec3 objectPosition = Vec3(0.0f, 0.0f, 0.0f); // posisi obyek
// fungsi untuk melakukan normalisasi koordinat posisi
Vec3 normalize(Vec3 value)
{
Vec3 result;
float lengths = sqrt((value.X * value.X) + (value.Y * value.Y)
+ (value.Z * value.Z));
result.X = value.X / lengths;
result.Y = value.Y / lengths;
result.Z = value.Z / lengths;
return result;
}
// fungsi untuk melakukan operasi perkalian cross
Vec3 cross(Vec3 value1, Vec3 value2)
{
Vec3 result;

44
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

result.X = value1.Y * value2.Z - value2.Y * value1.Z;


result.Y = value1.Z * value2.X - value2.Z * value1.X;
result.Z = value1.X * value2.Y - value2.X * value1.Y;
return result;
}
// menggambar setiap titik kontrol kurva
void markPoint(Vec3 points, Vec3 colors, float width)
{
// tandai setiap titik dengan warna
glPushMatrix();
glColor3f(colors.X, colors.Y, colors.Z);
glBegin(GL_QUADS);
glVertex3f(points.X - width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y + width, points.Z);
glVertex3f(points.X - width, points.Y + width, points.Z);
glEnd();
glPopMatrix();
}
// fungsi untuk menghitung invers matriks ordo 4x4
bool inverse(float inMat[16], float outMat[16])
{
float inv[16], det;
int i;
inv[0] =
inMat[5] * inMat[10] * inMat[15] -
inMat[5] * inMat[11] * inMat[14] -
inMat[9] * inMat[6] * inMat[15] +
inMat[9] * inMat[7] * inMat[14] +
inMat[13] * inMat[6] * inMat[11] -
inMat[13] * inMat[7] * inMat[10];
inv[4] =
-inMat[4] * inMat[10] * inMat[15] +
inMat[4] * inMat[11] * inMat[14] +
inMat[8] * inMat[6] * inMat[15] -
inMat[8] * inMat[7] * inMat[14] -
inMat[12] * inMat[6] * inMat[11] +
inMat[12] * inMat[7] * inMat[10];
inv[8] =
inMat[4] * inMat[9] * inMat[15] -
inMat[4] * inMat[11] * inMat[13] -
inMat[8] * inMat[5] * inMat[15] +
inMat[8] * inMat[7] * inMat[13] +
inMat[12] * inMat[5] * inMat[11] -
inMat[12] * inMat[7] * inMat[9];
inv[12] =
-inMat[4] * inMat[9] * inMat[14] +
inMat[4] * inMat[10] * inMat[13] +
inMat[8] * inMat[5] * inMat[14] -

45
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[8] * inMat[6] * inMat[13] -


inMat[12] * inMat[5] * inMat[10] +
inMat[12] * inMat[6] * inMat[9];
inv[1] =
-inMat[1] * inMat[10] * inMat[15] +
inMat[1] * inMat[11] * inMat[14] +
inMat[9] * inMat[2] * inMat[15] -
inMat[9] * inMat[3] * inMat[14] -
inMat[13] * inMat[2] * inMat[11] +
inMat[13] * inMat[3] * inMat[10];
inv[5] =
inMat[0] * inMat[10] * inMat[15] -
inMat[0] * inMat[11] * inMat[14] -
inMat[8] * inMat[2] * inMat[15] +
inMat[8] * inMat[3] * inMat[14] +
inMat[12] * inMat[2] * inMat[11] -
inMat[12] * inMat[3] * inMat[10];
inv[9] =
-inMat[0] * inMat[9] * inMat[15] +
inMat[0] * inMat[11] * inMat[13] +
inMat[8] * inMat[1] * inMat[15] -
inMat[8] * inMat[3] * inMat[13] -
inMat[12] * inMat[1] * inMat[11] +
inMat[12] * inMat[3] * inMat[9];
inv[13] =
inMat[0] * inMat[9] * inMat[14] -
inMat[0] * inMat[10] * inMat[13] -
inMat[8] * inMat[1] * inMat[14] +
inMat[8] * inMat[2] * inMat[13] +
inMat[12] * inMat[1] * inMat[10] -
inMat[12] * inMat[2] * inMat[9];
inv[2] =
inMat[1] * inMat[6] * inMat[15] -
inMat[1] * inMat[7] * inMat[14] -
inMat[5] * inMat[2] * inMat[15] +
inMat[5] * inMat[3] * inMat[14] +
inMat[13] * inMat[2] * inMat[7] -
inMat[13] * inMat[3] * inMat[6];
inv[6] =
-inMat[0] * inMat[6] * inMat[15] +
inMat[0] * inMat[7] * inMat[14] +
inMat[4] * inMat[2] * inMat[15] -
inMat[4] * inMat[3] * inMat[14] -
inMat[12] * inMat[2] * inMat[7] +
inMat[12] * inMat[3] * inMat[6];
inv[10] =
inMat[0] * inMat[5] * inMat[15] -
inMat[0] * inMat[7] * inMat[13] -
inMat[4] * inMat[1] * inMat[15] +

46
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[4] * inMat[3] * inMat[13] +


inMat[12] * inMat[1] * inMat[7] -
inMat[12] * inMat[3] * inMat[5];
inv[14] =
-inMat[0] * inMat[5] * inMat[14] +
inMat[0] * inMat[6] * inMat[13] +
inMat[4] * inMat[1] * inMat[14] -
inMat[4] * inMat[2] * inMat[13] -
inMat[12] * inMat[1] * inMat[6] +
inMat[12] * inMat[2] * inMat[5];
inv[3] =
-inMat[1] * inMat[6] * inMat[11] +
inMat[1] * inMat[7] * inMat[10] +
inMat[5] * inMat[2] * inMat[11] -
inMat[5] * inMat[3] * inMat[10] -
inMat[9] * inMat[2] * inMat[7] +
inMat[9] * inMat[3] * inMat[6];
inv[7] =
inMat[0] * inMat[6] * inMat[11] -
inMat[0] * inMat[7] * inMat[10] -
inMat[4] * inMat[2] * inMat[11] +
inMat[4] * inMat[3] * inMat[10] +
inMat[8] * inMat[2] * inMat[7] -
inMat[8] * inMat[3] * inMat[6];
inv[11] =
-inMat[0] * inMat[5] * inMat[11] +
inMat[0] * inMat[7] * inMat[9] +
inMat[4] * inMat[1] * inMat[11] -
inMat[4] * inMat[3] * inMat[9] -
inMat[8] * inMat[1] * inMat[7] +
inMat[8] * inMat[3] * inMat[5];
inv[15] =
inMat[0] * inMat[5] * inMat[10] -
inMat[0] * inMat[6] * inMat[9] -
inMat[4] * inMat[1] * inMat[10] +
inMat[4] * inMat[2] * inMat[9] +
inMat[8] * inMat[1] * inMat[6] -
inMat[8] * inMat[2] * inMat[5];
det = inMat[0] * inv[0] + inMat[1] * inv[4] + inMat[2] * inv[8] + inMat[3] * inv[12];
if (det == 0)
return false;
det = 1.0 / det;
for (i = 0; i < 16; i++)
outMat[i] = inv[i] * det;
return true;
}
// fungsi untuk perkalian matriks 4x4 dengan 4x1
void DotMatrix(float inMat1[16], float inMat2[4], float outMat[4])
{

47
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

outMat[0] = inMat1[0] * inMat2[0] + inMat1[1] * inMat2[1] +


inMat1[2] * inMat2[2] + inMat1[3] * inMat2[3];
outMat[1] = inMat1[4] * inMat2[0] + inMat1[5] * inMat2[1] +
inMat1[6] * inMat2[2] + inMat1[7] * inMat2[3];
outMat[2] = inMat1[8] * inMat2[0] + inMat1[9] * inMat2[1] +
inMat1[10] * inMat2[2] + inMat1[11] * inMat2[3];
outMat[3] = inMat1[12] * inMat2[0] + inMat1[13] * inMat2[1] +
inMat1[14] * inMat2[2] + inMat1[15] * inMat2[3];
}
// fungsi untuk membuat kurva spline cubic dari 4 titik kontrol
// point1 sampai point4 = titik kontrol
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineCubic(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) + abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) / utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.00f, 0.00f, 0.00f, 0.00f,
1.00f, u2, pow(u2, 2), pow(u2, 3),
1.00f, u3, pow(u3, 2), pow(u3, 3),
1.00f, 1.00f, 1.00f, 1.00f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien cubic au^3 + bu^2 + cu + d
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point2.X, point3.X, point4.X };
float inMatY[4] = { point1.Y, point2.Y, point3.Y, point4.Y };
float inMatZ[4] = { point1.Z, point2.Z, point3.Z, point4.Z };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva cubic spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan persamaan diatas
for (int i=0; i<nPoint; i++)
{
float step = 1.0f / nPoint; // jeda setiap titik pd bobot u
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{

48
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// bentuk segment kurva cubic spline sebanyak nPoint


u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] * pow(u, 2)
+ outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] * pow(u, 2)
+ outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] * pow(u, 2)
+ outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}
void drawSplineBezier(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) + abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) / utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.00f, 0.00f, 0.00f, 0.00f,
1.00f, 1.00f, 1.00f, 1.00f,
0.00f, 1.00f, 0.00f, 0.00f,
0.00f, 1.00f, 2.00f, 3.00f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien cubic au^3 + bu^2 + cu + d
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
// rumus bezier
float inMatX[4] = { point1.X, point4.X,
1.0f/(u3-u1)*(point3.X - point1.X),
1.0f/(u4-u2)*(point4.X - point2.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u3-u1)*(point3.Y - point1.Y),
1.0f/(u4-u2)*(point4.Y - point2.Y) };
float inMatZ[4] = { point1.Z, point4.Z,
1.0f/(u3-u1)*(point3.Z - point1.Z),
1.0f/(u4-u2)*(point4.Z - point2.Z) };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);

49
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

DotMatrix(inverseMat, inMatZ, outMatZ);


// gambar kurva cubic spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan persamaan diatas
for (int i=0; i<nPoint; i++)
{
float step = 1.0f / nPoint; // jeda setiap titik pd bobot u
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva cubic spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] * pow(u, 2)
+ outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] * pow(u, 2)
+ outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] * pow(u, 2)
+ outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}
// fungsi untuk membuat kurva spline catmull-rom dari 4 titik kontrol
// point1 dan point4 = titik kontrol awal dan akhir
// point2 dan point3 = titik kontrol pembentuk kurva
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineCatmullRom(Vec3 point1, Vec3 point2, Vec3 point3,
Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) +
abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) /
utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.0000f, 0.0000f, 0.0000f, 0.0000f,
1.0000f, 1.0000f, 1.0000f, 1.0000f,

50
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

0.0000f, 1.0000f, 0.0000f, 0.0000f,


0.0000f, 1.0000f, 2.0000f, 3.0000f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point4.X,
1.0f/(u3-u1)*(point3.X - point1.X),
1.0f/(u4-u2)*(point4.X - point2.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u3-u1)*(point3.Y - point1.Y),
1.0f/(u4-u2)*(point4.Y - point2.Y) };
float inMatZ[4] = { point1.Z, point4.Z,
1.0f/(u3-u1)*(point3.Z - point1.Z),
1.0f/(u4-u2)*(point4.Z - point2.Z) };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan
// persamaan diatas
for (int i=0; i<nPoint; i++)
{
// jeda setiap titik pd bobot u
float step = 1.0f / nPoint;
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] *
pow(u, 2) + outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] *
pow(u, 2) + outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] *
pow(u, 2) + outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}

51
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// fungsi ini digunakan untuk menggambar obyek


void drawObject()
{
glPushMatrix();
glRotatef(objectAngle, objectRotation.X, objectRotation.Y, objectRotation.Z);
// membuat 4 titik kontrol kurva
Vec3 point1 = Vec3(-150.0f, -70.0f, 0.0f);
Vec3 point2 = Vec3(-50.0f, 50.0f, 0.0f);
Vec3 point3 = Vec3(50.0f, 10.0f, 0.0f);
Vec3 point4 = Vec3(150.0f, -50.0f, 0.0f);
// tandai setiap titik kontrol kurva dengan warna
markPoint(point1, Vec3(1.0f, 1.0f, 1.0f), 5.0f);
markPoint(point2, Vec3(1.0f, 0.75f, 0.0f), 5.0f);
markPoint(point3, Vec3(1.0f, 0.0f, 1.5f), 5.0f);
markPoint(point4, Vec3(0.5f, 1.0f, 0.7f), 5.0f);
// mengatur warna obyek menjadi berwarna putih
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_LINES);
// membuat kurva spline cubic dari titik kontrol diatas
drawSplineCubic(point1, point2, point3, point4, 30);
glEnd();
glPopMatrix();
}
// taruh semua fungsi obyek yang akan digambar di fungsi display()
void display()
{
// bersihkan dan reset layar dan buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// posisikan pandangan kamera
// dalam hal ini sumbu Y kamera ada di atas
// dan posisi kamera di camPosition
gluLookAt(camPosition.X, camPosition.Y, camPosition.Z,
camPosition.X + camLookAt.X,
camPosition.Y + camLookAt.Y,
camPosition.Z + camLookAt.Z,
camUp.X, camUp.Y, camUp.Z);
// panggil fungsi untuk menggambar obyek
drawObject();
// tampilkan obyek ke layar
// gunakan glFlush() bila memakai single buffer
// gunakan glutSwapBuffers() bila memakai double buffer
glutSwapBuffers();
}
// inisialisasikan variabel, pencahayaan, tekstur,
// pengaturan pandangan kamera dan sebagainya di fungsi init()
void init(void)
{
// inisialisasi warna latar belakang layar

52
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// dalam hal ini warna putih warna hitam (0.0, 0.0, 0.0, 0.0)
glClearColor(0.0, 0.0, 0.0, 0.0);
// mengaktifkan depth buffer
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// set proyeksi ke proyeksi perspektif
//gluPerspective(fov, 1.0, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// inisialisasi kamera pandang
// kamera berada di posisi (0.0f, 0.0f, 0.0f)
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
// fungsi ini digunakan bila layar akan diresize (default)
// (akan dijelaskan pada praktikum ke-5)
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(fov, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
// fungsi untuk mengatur masukan dari keyboard
void keyboard(unsigned char key, int x, int y)
{
Vec3 result = normalize(cross(camLookAt, camUp));
switch (key)
{
case 'w': // bila tombol 'w' pada keyboard ditekan
// geser pandangan kamera ke depan
camPosition.X += moveSpeed * camLookAt.X;
camPosition.Y += moveSpeed * camLookAt.Y;
camPosition.Z += moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;
case 's': // bila tombol 's' pada keyboard ditekan
// geser pandangan kamera ke belakang
camPosition.X -= moveSpeed * camLookAt.X;
camPosition.Y -= moveSpeed * camLookAt.Y;
camPosition.Z -= moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;
case 'a': // bila tombol 'a' pada keyboard ditekan

53
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// geser pandangan kamera ke ke kiri


camPosition.X -= moveSpeed * result.X;
camPosition.Y -= moveSpeed * result.Y;
camPosition.Z -= moveSpeed * result.Z;
glutPostRedisplay();
break;
case 'd': // bila tombol 'd' pada keyboard ditekan
// geser pandangan kamera ke kanan
camPosition.X += moveSpeed * result.X;
camPosition.Y += moveSpeed * result.Y;
camPosition.Z += moveSpeed * result.Z;
glutPostRedisplay();
break;
case 'f': // bila tombol 'f' pada keyboard ditekan
// percepat laju pergerakan kamera
moveSpeed = moveSpeed + 0.5f;
glutPostRedisplay();
break;
case 'g': // bila tombol 'g' pada keyboard ditekan
// perlambat laju pergerakan kamera
moveSpeed = moveSpeed - 0.5f > 0.5f ? moveSpeed - 0.5f : 0.5f;
glutPostRedisplay();
break;
case 27: // bila tombol 'esc' pada keyboard ditekan
// keluar program
exit(0);
break;
}
}
// fungsi untuk mengatur masukan tombol dari mouse
void mousebutton(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_UP)
firstMouse = false;
else
firstMouse = true;
}
}
// fungsi untuk mengatur masukan pergerakan dari mouse
void mousemove(int x, int y)
{
if (firstMouse)
{
lastX = x; lastY =
y; firstMouse =
false;
}

54
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

GLfloat xoffset = x - lastX;


GLfloat yoffset = lastY - y;
lastX = x;
lastY = y;
GLfloat sensitivity = 0.05;
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
Vec3 front;
front.X = cos(yaw * PHI / 180) * cos(pitch * PHI / 180);
front.Y = sin(pitch * PHI / 180);
front.Z = sin(yaw * PHI / 180) * cos(pitch * PHI / 180);
camLookAt = normalize(front);
glutPostRedisplay();
}
// timer untuk animasi (gunakan bila perlu)
void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(55, timer, 0);
}
// program utama
int main(int argc, char** argv)
{
// inisialisasi jendela OpenGL
// GLUT_SINGLE berarti memakai single buffer
// GLUT_DOUBLE berarti memakai double buffer
// GLUT_RGB berarti mode tampilan yang dipakai RGB
// GLUT_RGBA berarti mode tampilan yang dipakai RGBA
// GLUT_DEPTH berarti memakai depth buffer
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
// set ukuran jendela tampilan
// besarnya jendela dalam piksel dalam hal ini 480x480
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
// posisi jendela dilayar komputer dalam piksel
glutInitWindowPosition(100, 100);
// judul jendela (wajib diubah dengan informasi
// NAMA / NIM - JUDUL PRAKTIKUM masing-masing)
glutCreateWindow("Syifa Fauziah_2006133_Grafkom -Cubic");
// panggil fungsi init untuk melakukan inisialisasi awal
init();
// event handler untuk display, reshape dan keyboard
glutDisplayFunc(display); // display

55
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

glutReshapeFunc(reshape); // reshape
glutKeyboardFunc(keyboard); // keyboard
glutMouseFunc(mousebutton); // mouse button
glutMotionFunc(mousemove); // mouse movement
//glutTimerFunc(0, timer, 0); // aktifkan timer bila perlu
// looping
glutMainLoop();
return 0;
}

Bezier
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// header untuk GLUT
#include <gl/glut.h>
using namespace std;
#define PHI 3.14
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 480
// container untuk membuat tipe data 3D (X, Y, Z)
struct Vec3

56
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

{
float X; float Y; float Z;
Vec3(float x, float y, float z) { X = x; Y = y; Z = z; }
//
Vec3() { }
~Vec3() { }
};
// inisialisasi variabel untuk kecepatan pergerakan kamera
// (akan digunakan di praktikum ke-5 tentang Proyeksi)
float fov = 45; // sudut proyeksi
float moveSpeed = 0.5f; // kecepatan pergerakan kamera
float rotateSpeed = 0.05f; // kecepatan rotasi kamera
// inisialisasi variabel untuk proyeksi
// (akan digunakan di praktikum ke-5 tentang Proyeksi)
// posisi kamera
Vec3 camPosition = Vec3(0.0f, 0.0f, 5.0f);
Vec3 camLookAt = Vec3(0.0f, 0.0f, -1.0f);
Vec3 camUp = Vec3(0.0f, 1.0f, 0.0f);
// sudut transformasi kamera
float camAngle = 0.0f;
// inisialisasi variabel untuk proyeksi dengan mouse
bool firstMouse = true;
float yaw = -90.0f;
float pitch = 0.0f;
float lastX = SCREEN_WIDTH / 2.0f;
float lastY = SCREEN_HEIGHT / 2.0f;
// inisialisasi variabel untuk transformasi
// seperti translasi, rotasi atau scaling
// (akan digunakan di praktikum ke-4 tentang transformasi 2D/3D)
float objectAngle = 0.0f; // sudut tranformasi obyek
Vec3 objectRotation = Vec3(0.0f, 1.0f, 0.0f); // posisi rotasi
Vec3 objectPosition = Vec3(0.0f, 0.0f, 0.0f); // posisi obyek
// fungsi untuk melakukan normalisasi koordinat posisi
Vec3 normalize(Vec3 value)
{
Vec3 result;
float lengths = sqrt((value.X * value.X) + (value.Y * value.Y)
+ (value.Z * value.Z));
result.X = value.X / lengths;
result.Y = value.Y / lengths;
result.Z = value.Z / lengths;
return result;
}
// fungsi untuk melakukan operasi perkalian cross
Vec3 cross(Vec3 value1, Vec3 value2)
{
Vec3 result;
result.X = value1.Y * value2.Z - value2.Y * value1.Z;
result.Y = value1.Z * value2.X - value2.Z * value1.X;

57
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

result.Z = value1.X * value2.Y - value2.X * value1.Y;


return result;
}
// menggambar setiap titik kontrol kurva
void markPoint(Vec3 points, Vec3 colors, float width)
{
// tandai setiap titik dengan warna
glPushMatrix();
glColor3f(colors.X, colors.Y, colors.Z);
glBegin(GL_QUADS);
glVertex3f(points.X - width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y + width, points.Z);
glVertex3f(points.X - width, points.Y + width, points.Z);
glEnd();
glPopMatrix();
}
// fungsi untuk menghitung invers matriks ordo 4x4
bool inverse(float inMat[16], float outMat[16])
{
float inv[16], det;
int i;
inv[0] =
inMat[5] * inMat[10] * inMat[15] -
inMat[5] * inMat[11] * inMat[14] -
inMat[9] * inMat[6] * inMat[15] +
inMat[9] * inMat[7] * inMat[14] +
inMat[13] * inMat[6] * inMat[11] -
inMat[13] * inMat[7] * inMat[10];
inv[4] =
-inMat[4] * inMat[10] * inMat[15] +
inMat[4] * inMat[11] * inMat[14] +
inMat[8] * inMat[6] * inMat[15] -
inMat[8] * inMat[7] * inMat[14] -
inMat[12] * inMat[6] * inMat[11] +
inMat[12] * inMat[7] * inMat[10];
inv[8] =
inMat[4] * inMat[9] * inMat[15] -
inMat[4] * inMat[11] * inMat[13] -
inMat[8] * inMat[5] * inMat[15] +
inMat[8] * inMat[7] * inMat[13] +
inMat[12] * inMat[5] * inMat[11] -
inMat[12] * inMat[7] * inMat[9];
inv[12] =
-inMat[4] * inMat[9] * inMat[14] +
inMat[4] * inMat[10] * inMat[13] +
inMat[8] * inMat[5] * inMat[14] -
inMat[8] * inMat[6] * inMat[13] -
inMat[12] * inMat[5] * inMat[10] +

58
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[12] * inMat[6] * inMat[9];


inv[1] =
-inMat[1] * inMat[10] * inMat[15] +
inMat[1] * inMat[11] * inMat[14] +
inMat[9] * inMat[2] * inMat[15] -
inMat[9] * inMat[3] * inMat[14] -
inMat[13] * inMat[2] * inMat[11] +
inMat[13] * inMat[3] * inMat[10];
inv[5] =
inMat[0] * inMat[10] * inMat[15] -
inMat[0] * inMat[11] * inMat[14] -
inMat[8] * inMat[2] * inMat[15] +
inMat[8] * inMat[3] * inMat[14] +
inMat[12] * inMat[2] * inMat[11] -
inMat[12] * inMat[3] * inMat[10];
inv[9] =
-inMat[0] * inMat[9] * inMat[15] +
inMat[0] * inMat[11] * inMat[13] +
inMat[8] * inMat[1] * inMat[15] -
inMat[8] * inMat[3] * inMat[13] -
inMat[12] * inMat[1] * inMat[11] +
inMat[12] * inMat[3] * inMat[9];
inv[13] =
inMat[0] * inMat[9] * inMat[14] -
inMat[0] * inMat[10] * inMat[13] -
inMat[8] * inMat[1] * inMat[14] +
inMat[8] * inMat[2] * inMat[13] +
inMat[12] * inMat[1] * inMat[10] -
inMat[12] * inMat[2] * inMat[9];
inv[2] =
inMat[1] * inMat[6] * inMat[15] -
inMat[1] * inMat[7] * inMat[14] -
inMat[5] * inMat[2] * inMat[15] +
inMat[5] * inMat[3] * inMat[14] +
inMat[13] * inMat[2] * inMat[7] -
inMat[13] * inMat[3] * inMat[6];
inv[6] =
-inMat[0] * inMat[6] * inMat[15] +
inMat[0] * inMat[7] * inMat[14] +
inMat[4] * inMat[2] * inMat[15] -
inMat[4] * inMat[3] * inMat[14] -
inMat[12] * inMat[2] * inMat[7] +
inMat[12] * inMat[3] * inMat[6];
inv[10] =
inMat[0] * inMat[5] * inMat[15] -
inMat[0] * inMat[7] * inMat[13] -
inMat[4] * inMat[1] * inMat[15] +
inMat[4] * inMat[3] * inMat[13] +
inMat[12] * inMat[1] * inMat[7] -

59
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[12] * inMat[3] * inMat[5];


inv[14] =
-inMat[0] * inMat[5] * inMat[14] +
inMat[0] * inMat[6] * inMat[13] +
inMat[4] * inMat[1] * inMat[14] -
inMat[4] * inMat[2] * inMat[13] -
inMat[12] * inMat[1] * inMat[6] +
inMat[12] * inMat[2] * inMat[5];
inv[3] =
-inMat[1] * inMat[6] * inMat[11] +
inMat[1] * inMat[7] * inMat[10] +
inMat[5] * inMat[2] * inMat[11] -
inMat[5] * inMat[3] * inMat[10] -
inMat[9] * inMat[2] * inMat[7] +
inMat[9] * inMat[3] * inMat[6];
inv[7] =
inMat[0] * inMat[6] * inMat[11] -
inMat[0] * inMat[7] * inMat[10] -
inMat[4] * inMat[2] * inMat[11] +
inMat[4] * inMat[3] * inMat[10] +
inMat[8] * inMat[2] * inMat[7] -
inMat[8] * inMat[3] * inMat[6];
inv[11] =
-inMat[0] * inMat[5] * inMat[11] +
inMat[0] * inMat[7] * inMat[9] +
inMat[4] * inMat[1] * inMat[11] -
inMat[4] * inMat[3] * inMat[9] -
inMat[8] * inMat[1] * inMat[7] +
inMat[8] * inMat[3] * inMat[5];
inv[15] =
inMat[0] * inMat[5] * inMat[10] -
inMat[0] * inMat[6] * inMat[9] -
inMat[4] * inMat[1] * inMat[10] +
inMat[4] * inMat[2] * inMat[9] +
inMat[8] * inMat[1] * inMat[6] -
inMat[8] * inMat[2] * inMat[5];
det = inMat[0] * inv[0] + inMat[1] * inv[4] + inMat[2] * inv[8] + inMat[3] * inv[12];
if (det == 0)
return false;
det = 1.0 / det;
for (i = 0; i < 16; i++)
outMat[i] = inv[i] * det;
return true;
}
// fungsi untuk perkalian matriks 4x4 dengan 4x1
void DotMatrix(float inMat1[16], float inMat2[4], float outMat[4])
{
outMat[0] = inMat1[0] * inMat2[0] + inMat1[1] * inMat2[1] +
inMat1[2] * inMat2[2] + inMat1[3] * inMat2[3];

60
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

outMat[1] = inMat1[4] * inMat2[0] + inMat1[5] * inMat2[1] +


inMat1[6] * inMat2[2] + inMat1[7] * inMat2[3];
outMat[2] = inMat1[8] * inMat2[0] + inMat1[9] * inMat2[1] +
inMat1[10] * inMat2[2] + inMat1[11] * inMat2[3];
outMat[3] = inMat1[12] * inMat2[0] + inMat1[13] * inMat2[1] +
inMat1[14] * inMat2[2] + inMat1[15] * inMat2[3];
}
// fungsi untuk membuat kurva spline cubic dari 4 titik kontrol
// point1 sampai point4 = titik kontrol
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineCubic(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) + abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) / utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.00f, 0.00f, 0.00f, 0.00f,
1.00f, u2, pow(u2, 2), pow(u2, 3),
1.00f, u3, pow(u3, 2), pow(u3, 3),
1.00f, 1.00f, 1.00f, 1.00f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien cubic au^3 + bu^2 + cu + d
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point2.X, point3.X, point4.X };
float inMatY[4] = { point1.Y, point2.Y, point3.Y, point4.Y };
float inMatZ[4] = { point1.Z, point2.Z, point3.Z, point4.Z };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva cubic spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan persamaan diatas
for (int i=0; i<nPoint; i++)
{
float step = 1.0f / nPoint; // jeda setiap titik pd bobot u
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva cubic spline sebanyak nPoint
u = u + step;

61
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

glVertex3f(pX, pY, pZ); // gambar titik awal


// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] * pow(u, 2)
+ outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] * pow(u, 2)
+ outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] * pow(u, 2)
+ outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}

// fungsi untuk membuat kurva spline bezier dari 4 titik kontrol


// point1 dan point4 = titik kontrol awal dan akhir
// point2 dan point3 = titik kontrol pembentuk kurva
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineBezier(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) +
abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) /
utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.0000f, 0.0000f, 0.0000f, 0.0000f,
1.0000f, 1.0000f, 1.0000f, 1.0000f,
0.0000f, 1.0000f, 0.0000f, 0.0000f,
0.0000f, 1.0000f, 2.0000f, 3.0000f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point4.X,
1.0f/(u2-u1)*(point2.X - point1.X),
1.0f/(u4-u3)*(point4.X - point3.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u2-u1)*(point2.Y - point1.Y),
1.0f/(u4-u3)*(point4.Y - point3.Y) };
float inMatZ[4] = { point1.Z, point4.Z,

62
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

1.0f/(u2-u1)*(point2.Z - point1.Z),
1.0f/(u4-u3)*(point4.Z - point3.Z) };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva cubic spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan
// persamaan diatas
for (int i=0; i<nPoint; i++)
{
// jeda setiap titik pd bobot u
float step = 1.0f / nPoint;
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] *
pow(u, 2) + outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] *
pow(u, 2) + outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] *
pow(u, 2) + outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}

void drawSplineCatmullRom(Vec3 point1, Vec3 point2, Vec3 point3,


Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) +
abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) /
utotal;
float u4 = 1;

63
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// hitung inverse matriks dari koefisien u (lihat slide kuliah)


float inverseMat[16];
float coeffMat[16] = {
1.0000f, 0.0000f, 0.0000f, 0.0000f,
1.0000f, 1.0000f, 1.0000f, 1.0000f,
0.0000f, 1.0000f, 0.0000f, 0.0000f,
0.0000f, 1.0000f, 2.0000f, 3.0000f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point4.X,
1.0f/(u3-u1)*(point3.X - point1.X),
1.0f/(u4-u2)*(point4.X - point2.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u3-u1)*(point3.Y - point1.Y),
1.0f/(u4-u2)*(point4.Y - point2.Y) };
float inMatZ[4] = { point1.Z, point4.Z,
1.0f/(u3-u1)*(point3.Z - point1.Z),
1.0f/(u4-u2)*(point4.Z - point2.Z) };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan
// persamaan diatas
for (int i=0; i<nPoint; i++)
{
// jeda setiap titik pd bobot u
float step = 1.0f / nPoint;
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] *
pow(u, 2) + outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] *
pow(u, 2) + outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] *
pow(u, 2) + outMatZ[1] * u + outMatZ[0];

64
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

glVertex3f(pX, pY, pZ); // gambar titik akhir


}
}
}
}
// fungsi ini digunakan untuk menggambar obyek
void drawObject()
{
glPushMatrix();
glRotatef(objectAngle, objectRotation.X, objectRotation.Y, objectRotation.Z);
// membuat 4 titik kontrol kurva
Vec3 point1 = Vec3(-150.0f, -70.0f, 0.0f);
Vec3 point2 = Vec3( -50.0f, 50.0f, 0.0f);
Vec3 point3 = Vec3( 50.0f, 10.0f, 0.0f);
Vec3 point4 = Vec3( 150.0f, -50.0f, 0.0f);
// tandai setiap titik kontrol kurva dengan warna
markPoint(point1, Vec3(1.0f, 1.0f, 1.0f), 5.0f);
markPoint(point2, Vec3(1.0f, 0.75f, 0.0f), 5.0f);
markPoint(point3, Vec3(1.0f, 0.0f, 1.5f), 5.0f);
markPoint(point4, Vec3(0.5f, 1.0f, 0.7f), 5.0f);
// mengatur warna obyek menjadi berwarna putih
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_LINES);
// membuat kurva spline cubic dari titik kontrol diatas
//drawSplineCatmullRom(point1,point2,point3,point4,30);
drawSplineBezier(point1,point2,point3,point4,30);
//drawSplineCubic(point1, point2, point3, point4, 30);
glEnd();
glPopMatrix();
}
// taruh semua fungsi obyek yang akan digambar di fungsi display()

void display()
{
// bersihkan dan reset layar dan buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// posisikan pandangan kamera
// dalam hal ini sumbu Y kamera ada di atas
// dan posisi kamera di camPosition
gluLookAt(camPosition.X, camPosition.Y, camPosition.Z,
camPosition.X + camLookAt.X,
camPosition.Y + camLookAt.Y,
camPosition.Z + camLookAt.Z,
camUp.X, camUp.Y, camUp.Z);
// panggil fungsi untuk menggambar obyek
drawObject();
// tampilkan obyek ke layar
// gunakan glFlush() bila memakai single buffer

65
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// gunakan glutSwapBuffers() bila memakai double buffer


glutSwapBuffers();
}
// inisialisasikan variabel, pencahayaan, tekstur,
// pengaturan pandangan kamera dan sebagainya di fungsi init()
void init(void)
{
// inisialisasi warna latar belakang layar
// dalam hal ini warna putih warna hitam (0.0, 0.0, 0.0, 0.0)
glClearColor(0.0, 0.0, 0.0, 0.0);
// mengaktifkan depth buffer
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// set proyeksi ke proyeksi perspektif
//gluPerspective(fov, 1.0, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// inisialisasi kamera pandang
// kamera berada di posisi (0.0f, 0.0f, 0.0f)
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
// fungsi ini digunakan bila layar akan diresize (default)
// (akan dijelaskan pada praktikum ke-5)
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(fov, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
// fungsi untuk mengatur masukan dari keyboard
void keyboard(unsigned char key, int x, int y)
{
Vec3 result = normalize(cross(camLookAt, camUp));
switch (key)
{
case 'w': // bila tombol 'w' pada keyboard ditekan
// geser pandangan kamera ke depan
camPosition.X += moveSpeed * camLookAt.X;
camPosition.Y += moveSpeed * camLookAt.Y;
camPosition.Z += moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;

66
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

case 's': // bila tombol 's' pada keyboard ditekan


// geser pandangan kamera ke belakang
camPosition.X -= moveSpeed * camLookAt.X;
camPosition.Y -= moveSpeed * camLookAt.Y;
camPosition.Z -= moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;
case 'a': // bila tombol 'a' pada keyboard ditekan
// geser pandangan kamera ke ke kiri
camPosition.X -= moveSpeed * result.X;
camPosition.Y -= moveSpeed * result.Y;
camPosition.Z -= moveSpeed * result.Z;
glutPostRedisplay();
break;
case 'd': // bila tombol 'd' pada keyboard ditekan
// geser pandangan kamera ke kanan
camPosition.X += moveSpeed * result.X;
camPosition.Y += moveSpeed * result.Y;
camPosition.Z += moveSpeed * result.Z;
glutPostRedisplay();
break;
case 'f': // bila tombol 'f' pada keyboard ditekan
// percepat laju pergerakan kamera
moveSpeed = moveSpeed + 0.5f;
glutPostRedisplay();
break;
case 'g': // bila tombol 'g' pada keyboard ditekan
// perlambat laju pergerakan kamera
moveSpeed = moveSpeed - 0.5f > 0.5f ? moveSpeed - 0.5f : 0.5f;
glutPostRedisplay();
break;
case 27: // bila tombol 'esc' pada keyboard ditekan
// keluar program
exit(0);
break;
}
}
// fungsi untuk mengatur masukan tombol dari mouse
void mousebutton(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_UP)
firstMouse = false;
else
firstMouse = true;
}
}
// fungsi untuk mengatur masukan pergerakan dari mouse

67
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

void mousemove(int x, int y)


{
if (firstMouse)
{
lastX = x; lastY =
y; firstMouse =
false;
}
GLfloat xoffset = x - lastX;
GLfloat yoffset = lastY - y;
lastX = x;
lastY = y;
GLfloat sensitivity = 0.05;
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
Vec3 front;
front.X = cos(yaw * PHI / 180) * cos(pitch * PHI / 180);
front.Y = sin(pitch * PHI / 180);
front.Z = sin(yaw * PHI / 180) * cos(pitch * PHI / 180);
camLookAt = normalize(front);
glutPostRedisplay();
}
// timer untuk animasi (gunakan bila perlu)
void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(55, timer, 0);
}
// program utama
int main(int argc, char** argv)
{
// inisialisasi jendela OpenGL
// GLUT_SINGLE berarti memakai single buffer
// GLUT_DOUBLE berarti memakai double buffer
// GLUT_RGB berarti mode tampilan yang dipakai RGB
// GLUT_RGBA berarti mode tampilan yang dipakai RGBA
// GLUT_DEPTH berarti memakai depth buffer
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
// set ukuran jendela tampilan
// besarnya jendela dalam piksel dalam hal ini 480x480
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
// posisi jendela dilayar komputer dalam piksel

68
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

glutInitWindowPosition(100, 100);
// judul jendela (wajib diubah dengan informasi
// NAMA / NIM - JUDUL PRAKTIKUM masing-masing)
glutCreateWindow("2006133_Syifa Fauziah");
// panggil fungsi init untuk melakukan inisialisasi awal
init();
// event handler untuk display, reshape dan keyboard
glutDisplayFunc(display); // display
glutReshapeFunc(reshape); // reshape
glutKeyboardFunc(keyboard); // keyboard
glutMouseFunc(mousebutton); // mouse button
glutMotionFunc(mousemove); // mouse movement
//glutTimerFunc(0, timer, 0); // aktifkan timer bila perlu
// looping
glutMainLoop();
return 0;
}

catmull-rom
#include <windows.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// header untuk GLUT
#include <gl/glut.h>
using namespace std;
#define PHI 3.141592654
#define SCREEN_WIDTH 480
#define SCREEN_HEIGHT 480
// container untuk membuat tipe data 3D (X, Y, Z)

69
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

struct Vec3
{
float X; float Y; float Z;
Vec3(float x, float y, float z) { X = x; Y = y; Z = z; }
//
Vec3() { }
~Vec3() { }
};
// inisialisasi variabel untuk kecepatan pergerakan kamera
// (akan digunakan di praktikum ke-5 tentang Proyeksi)
float fov = 45; // sudut proyeksi
float moveSpeed = 0.5f; // kecepatan pergerakan kamera
float rotateSpeed = 0.05f; // kecepatan rotasi kamera
// inisialisasi variabel untuk proyeksi
// (akan digunakan di praktikum ke-5 tentang Proyeksi)
// posisi kamera
Vec3 camPosition = Vec3(0.0f, 0.0f, 5.0f);
Vec3 camLookAt = Vec3(0.0f, 0.0f, -1.0f);
Vec3 camUp = Vec3(0.0f, 1.0f, 0.0f);
// sudut transformasi kamera
float camAngle = 0.0f;
// inisialisasi variabel untuk proyeksi dengan mouse
bool firstMouse = true;
float yaw = -90.0f;
float pitch = 0.0f;
float lastX = SCREEN_WIDTH / 2.0f;
float lastY = SCREEN_HEIGHT / 2.0f;
// inisialisasi variabel untuk transformasi
// seperti translasi, rotasi atau scaling
// (akan digunakan di praktikum ke-4 tentang transformasi 2D/3D)
float objectAngle = 0.0f; // sudut tranformasi obyek
Vec3 objectRotation = Vec3(0.0f, 1.0f, 0.0f); // posisi rotasi
Vec3 objectPosition = Vec3(0.0f, 0.0f, 0.0f); // posisi obyek
// fungsi untuk melakukan normalisasi koordinat posisi
Vec3 normalize(Vec3 value)
{
Vec3 result;
float lengths = sqrt((value.X * value.X) + (value.Y * value.Y)
+ (value.Z * value.Z));
result.X = value.X / lengths;
result.Y = value.Y / lengths;
result.Z = value.Z / lengths;
return result;
}
// fungsi untuk melakukan operasi perkalian cross
Vec3 cross(Vec3 value1, Vec3 value2)
{
Vec3 result;
result.X = value1.Y * value2.Z - value2.Y * value1.Z;

70
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

result.Y = value1.Z * value2.X - value2.Z * value1.X;


result.Z = value1.X * value2.Y - value2.X * value1.Y;
return result;
}
// menggambar setiap titik kontrol kurva
void markPoint(Vec3 points, Vec3 colors, float width)
{
// tandai setiap titik dengan warna
glPushMatrix();
glColor3f(colors.X, colors.Y, colors.Z);
glBegin(GL_QUADS);
glVertex3f(points.X - width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y - width, points.Z);
glVertex3f(points.X + width, points.Y + width, points.Z);
glVertex3f(points.X - width, points.Y + width, points.Z);
glEnd();
glPopMatrix();
}
// fungsi untuk menghitung invers matriks ordo 4x4
bool inverse(float inMat[16], float outMat[16])
{
float inv[16], det;
int i;
inv[0] =
inMat[5] * inMat[10] * inMat[15] -
inMat[5] * inMat[11] * inMat[14] -
inMat[9] * inMat[6] * inMat[15] +
inMat[9] * inMat[7] * inMat[14] +
inMat[13] * inMat[6] * inMat[11] -
inMat[13] * inMat[7] * inMat[10];
inv[4] =
-inMat[4] * inMat[10] * inMat[15] +
inMat[4] * inMat[11] * inMat[14] +
inMat[8] * inMat[6] * inMat[15] -
inMat[8] * inMat[7] * inMat[14] -
inMat[12] * inMat[6] * inMat[11] +
inMat[12] * inMat[7] * inMat[10];
inv[8] =
inMat[4] * inMat[9] * inMat[15] -
inMat[4] * inMat[11] * inMat[13] -
inMat[8] * inMat[5] * inMat[15] +
inMat[8] * inMat[7] * inMat[13] +
inMat[12] * inMat[5] * inMat[11] -
inMat[12] * inMat[7] * inMat[9];
inv[12] =
-inMat[4] * inMat[9] * inMat[14] +
inMat[4] * inMat[10] * inMat[13] +
inMat[8] * inMat[5] * inMat[14] -
inMat[8] * inMat[6] * inMat[13] -

71
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[12] * inMat[5] * inMat[10] +


inMat[12] * inMat[6] * inMat[9];
inv[1] =
-inMat[1] * inMat[10] * inMat[15] +
inMat[1] * inMat[11] * inMat[14] +
inMat[9] * inMat[2] * inMat[15] -
inMat[9] * inMat[3] * inMat[14] -
inMat[13] * inMat[2] * inMat[11] +
inMat[13] * inMat[3] * inMat[10];
inv[5] =
inMat[0] * inMat[10] * inMat[15] -
inMat[0] * inMat[11] * inMat[14] -
inMat[8] * inMat[2] * inMat[15] +
inMat[8] * inMat[3] * inMat[14] +
inMat[12] * inMat[2] * inMat[11] -
inMat[12] * inMat[3] * inMat[10];
inv[9] =
-inMat[0] * inMat[9] * inMat[15] +
inMat[0] * inMat[11] * inMat[13] +
inMat[8] * inMat[1] * inMat[15] -
inMat[8] * inMat[3] * inMat[13] -
inMat[12] * inMat[1] * inMat[11] +
inMat[12] * inMat[3] * inMat[9];
inv[13] =
inMat[0] * inMat[9] * inMat[14] -
inMat[0] * inMat[10] * inMat[13] -
inMat[8] * inMat[1] * inMat[14] +
inMat[8] * inMat[2] * inMat[13] +
inMat[12] * inMat[1] * inMat[10] -
inMat[12] * inMat[2] * inMat[9];
inv[2] =
inMat[1] * inMat[6] * inMat[15] -
inMat[1] * inMat[7] * inMat[14] -
inMat[5] * inMat[2] * inMat[15] +
inMat[5] * inMat[3] * inMat[14] +
inMat[13] * inMat[2] * inMat[7] -
inMat[13] * inMat[3] * inMat[6];
inv[6] =
-inMat[0] * inMat[6] * inMat[15] +
inMat[0] * inMat[7] * inMat[14] +
inMat[4] * inMat[2] * inMat[15] -
inMat[4] * inMat[3] * inMat[14] -
inMat[12] * inMat[2] * inMat[7] +
inMat[12] * inMat[3] * inMat[6];
inv[10] =
inMat[0] * inMat[5] * inMat[15] -
inMat[0] * inMat[7] * inMat[13] -
inMat[4] * inMat[1] * inMat[15] +
inMat[4] * inMat[3] * inMat[13] +

72
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat[12] * inMat[1] * inMat[7] -


inMat[12] * inMat[3] * inMat[5];
inv[14] =
-inMat[0] * inMat[5] * inMat[14] +
inMat[0] * inMat[6] * inMat[13] +
inMat[4] * inMat[1] * inMat[14] -
inMat[4] * inMat[2] * inMat[13] -
inMat[12] * inMat[1] * inMat[6] +
inMat[12] * inMat[2] * inMat[5];
inv[3] =
-inMat[1] * inMat[6] * inMat[11] +
inMat[1] * inMat[7] * inMat[10] +
inMat[5] * inMat[2] * inMat[11] -
inMat[5] * inMat[3] * inMat[10] -
inMat[9] * inMat[2] * inMat[7] +
inMat[9] * inMat[3] * inMat[6];
inv[7] =
inMat[0] * inMat[6] * inMat[11] -
inMat[0] * inMat[7] * inMat[10] -
inMat[4] * inMat[2] * inMat[11] +
inMat[4] * inMat[3] * inMat[10] +
inMat[8] * inMat[2] * inMat[7] -
inMat[8] * inMat[3] * inMat[6];
inv[11] =
-inMat[0] * inMat[5] * inMat[11] +
inMat[0] * inMat[7] * inMat[9] +
inMat[4] * inMat[1] * inMat[11] -
inMat[4] * inMat[3] * inMat[9] -
inMat[8] * inMat[1] * inMat[7] +
inMat[8] * inMat[3] * inMat[5];
inv[15] =
inMat[0] * inMat[5] * inMat[10] -
inMat[0] * inMat[6] * inMat[9] -
inMat[4] * inMat[1] * inMat[10] +
inMat[4] * inMat[2] * inMat[9] +
inMat[8] * inMat[1] * inMat[6] -
inMat[8] * inMat[2] * inMat[5];
det = inMat[0] * inv[0] + inMat[1] * inv[4] + inMat[2] * inv[8] + inMat[3] * inv[12];
if (det == 0)
return false;
det = 1.0 / det;
for (i = 0; i < 16; i++)
outMat[i] = inv[i] * det;
return true;
}
// fungsi untuk perkalian matriks 4x4 dengan 4x1
void DotMatrix(float inMat1[16], float inMat2[4], float outMat[4])
{
outMat[0] = inMat1[0] * inMat2[0] + inMat1[1] * inMat2[1] +

73
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

inMat1[2] * inMat2[2] + inMat1[3] * inMat2[3];


outMat[1] = inMat1[4] * inMat2[0] + inMat1[5] * inMat2[1] +
inMat1[6] * inMat2[2] + inMat1[7] * inMat2[3];
outMat[2] = inMat1[8] * inMat2[0] + inMat1[9] * inMat2[1] +
inMat1[10] * inMat2[2] + inMat1[11] * inMat2[3];
outMat[3] = inMat1[12] * inMat2[0] + inMat1[13] * inMat2[1] +
inMat1[14] * inMat2[2] + inMat1[15] * inMat2[3];
}
// fungsi untuk membuat kurva spline cubic dari 4 titik kontrol
// point1 sampai point4 = titik kontrol
// nPoint = jumlah titik interpolasi antara point1 sampai point4
// fungsi untuk membuat kurva spline bezier dari 4 titik kontrol
// point1 sampai point4 = titik kontrol
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineBezier(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = 1.0f;
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = abs(point3.X - point2.X) / utotal;
float u4 = 1;

// hitung inverse matriks dari koefisien u (lihat slide kuliah)


float inverseMat[16];
float coeffMat[16] = {
-1.0f, 3.0f, -3.0f, 1.0f,
3.0f, -6.0f, 3.0f, 0.0f,
-3.0f, 3.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f, 0.0f
};

bool status = inverse(coeffMat, inverseMat);

// hitung koefisien bezier


if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];

float inMatX[4] = { point1.X, point2.X, point3.X, point4.X };


float inMatY[4] = { point1.Y, point2.Y, point3.Y, point4.Y };
float inMatZ[4] = { point1.Z, point2.Z, point3.Z, point4.Z };

DotMatrix(inverseMat, inMatX, outMatX);


DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);

// gambar kurva bezier dengan titik kontrol diatas


// hitung posisi y untuk setiap x di setiap point dengan persamaan diatas

74
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

for (int i = 0; i < nPoint; i++)


{
float step = 1.0f / nPoint; // jeda setiap titik pd bobot u
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;

float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva bezier sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal

// koordinat X pada kurva


pX = outMatX[3] * pow(u, 3) + outMatX[2] * pow(u, 2) + outMatX[1] * u +
outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] * pow(u, 2) + outMatY[1] * u +
outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] * pow(u, 2) + outMatZ[1] * u +
outMatZ[0];

glVertex3f(pX, pY, pZ); // gambar titik akhir


}
}
}
}
void drawSplineCubic(Vec3 point1, Vec3 point2, Vec3 point3, Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik
float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) + abs(point4.X -
point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) / utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.00f, 0.00f, 0.00f, 0.00f,
1.00f, 1.00f, 1.00f, 1.00f,
0.00f, 1.00f, 0.00f, 0.00f,
0.00f, 1.00f, 2.00f, 3.00f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien cubic au^3 + bu^2 + cu + d
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];

75
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// rumus bezier
float inMatX[4] = { point1.X, point4.X,
1.0f/(u3-u1)*(point3.X - point1.X),
1.0f/(u4-u2)*(point4.X - point2.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u3-u1)*(point3.Y - point1.Y),
1.0f/(u4-u2)*(point4.Y - point2.Y) };
float inMatZ[4] = { point1.Z, point4.Z,
1.0f/(u3-u1)*(point3.Z - point1.Z),
1.0f/(u4-u2)*(point4.Z - point2.Z) };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva cubic spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan persamaan diatas
for (int i=0; i<nPoint; i++)
{
float step = 1.0f / nPoint; // jeda setiap titik pd bobot u
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva cubic spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] * pow(u, 2)
+ outMatX[1] * u + outMatX[0];
// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] * pow(u, 2)
+ outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] * pow(u, 2)
+ outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}
// fungsi untuk membuat kurva spline catmull-rom dari 4 titik kontrol
// point1 dan point4 = titik kontrol awal dan akhir
// point2 dan point3 = titik kontrol pembentuk kurva
// nPoint = jumlah titik interpolasi antara point1 sampai point4
void drawSplineCatmullRom(Vec3 point1, Vec3 point2, Vec3 point3,
Vec3 point4, int nPoint)
{
// hitung bobot jarak u di masing-masing titik

76
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

float utotal = (abs(point2.X - point1.X) + abs(point3.X - point2.X) +


abs(point4.X - point3.X));
float u1 = 0;
float u2 = abs(point2.X - point1.X) / utotal;
float u3 = (abs(point2.X - point1.X) + abs(point3.X - point2.X)) /
utotal;
float u4 = 1;
// hitung inverse matriks dari koefisien u (lihat slide kuliah)
float inverseMat[16];
float coeffMat[16] = {
1.0000f, 0.0000f, 0.0000f, 0.0000f,
1.0000f, 1.0000f, 1.0000f, 1.0000f,
0.0000f, 1.0000f, 0.0000f, 0.0000f,
0.0000f, 1.0000f, 2.0000f, 3.0000f };
bool status = inverse(coeffMat, inverseMat);
// hitung koefisien
if (status == true)
{
float outMatX[4], outMatY[4], outMatZ[4];
float inMatX[4] = { point1.X, point4.X,
1.0f/(u3-u1)*(point3.X - point1.X),
1.0f/(u4-u2)*(point4.X - point2.X) };
float inMatY[4] = { point1.Y, point4.Y,
1.0f/(u3-u1)*(point3.Y - point1.Y),
1.0f/(u4-u2)*(point4.Y - point2.Y) };
float inMatZ[4] = { point1.Z, point4.Z,
1.0f/(u3-u1)*(point3.Z - point1.Z),
1.0f/(u4-u2)*(point4.Z - point2.Z) };
DotMatrix(inverseMat, inMatX, outMatX);
DotMatrix(inverseMat, inMatY, outMatY);
DotMatrix(inverseMat, inMatZ, outMatZ);
// gambar kurva spline dengan titik kontrol diatas
// hitung posisi y untuk setiap x di setiap point dengan
// persamaan diatas
for (int i=0; i<nPoint; i++)
{
// jeda setiap titik pd bobot u
float step = 1.0f / nPoint;
// titik awal
float pX = point1.X, pY = point1.Y, pZ = point1.Z;
//
float u = 0.0f;
for (int i = 0; i < nPoint; i++)
{
// bentuk segment kurva spline sebanyak nPoint
u = u + step;
glVertex3f(pX, pY, pZ); // gambar titik awal
// koordinat X pada kurva
pX = outMatX[3] * pow(u, 3) + outMatX[2] *

77
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

pow(u, 2) + outMatX[1] * u + outMatX[0];


// koordinat Y pada kurva
pY = outMatY[3] * pow(u, 3) + outMatY[2] *
pow(u, 2) + outMatY[1] * u + outMatY[0];
// koordinat Z pada kurva
pZ = outMatZ[3] * pow(u, 3) + outMatZ[2] *
pow(u, 2) + outMatZ[1] * u + outMatZ[0];
glVertex3f(pX, pY, pZ); // gambar titik akhir
}
}
}
}
// fungsi ini digunakan untuk menggambar obyek
void drawObject()
{
glPushMatrix();
glRotatef(objectAngle, objectRotation.X, objectRotation.Y, objectRotation.Z);
// membuat 4 titik kontrol kurva
Vec3 point1 = Vec3(-150.0f, -70.0f, 0.0f);
Vec3 point2 = Vec3( -50.0f, 50.0f, 0.0f);
Vec3 point3 = Vec3( 50.0f, 10.0f, 0.0f);
Vec3 point4 = Vec3( 150.0f, -50.0f, 0.0f);
// tandai setiap titik kontrol kurva dengan warna
markPoint(point1, Vec3(1.0f, 1.0f, 1.0f), 5.0f);
markPoint(point2, Vec3(1.0f, 0.75f, 0.0f), 5.0f);
markPoint(point3, Vec3(1.0f, 0.0f, 1.0f), 5.0f);
markPoint(point4, Vec3(0.5f, 1.0f, 0.7f), 5.0f);
// mengatur warna obyek menjadi berwarna putih
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_LINES);
// membuat kurva spline cubic dari titik kontrol diatas
drawSplineCubic(point1, point2, point3, point4, 30);
glEnd();
glPopMatrix();
}
// taruh semua fungsi obyek yang akan digambar di fungsi display()
void display()
{
// bersihkan dan reset layar dan buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// posisikan pandangan kamera
// dalam hal ini sumbu Y kamera ada di atas
// dan posisi kamera di camPosition
gluLookAt(camPosition.X, camPosition.Y, camPosition.Z,
camPosition.X + camLookAt.X,
camPosition.Y + camLookAt.Y,
camPosition.Z + camLookAt.Z,
camUp.X, camUp.Y, camUp.Z);

78
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// panggil fungsi untuk menggambar obyek


drawObject();
// tampilkan obyek ke layar
// gunakan glFlush() bila memakai single buffer
// gunakan glutSwapBuffers() bila memakai double buffer
glutSwapBuffers();
}
// inisialisasikan variabel, pencahayaan, tekstur,
// pengaturan pandangan kamera dan sebagainya di fungsi init()
void init(void)
{
// inisialisasi warna latar belakang layar
// dalam hal ini warna putih warna hitam (0.0, 0.0, 0.0, 0.0)
glClearColor(0.0, 0.0, 0.0, 0.0);
// mengaktifkan depth buffer
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// set proyeksi ke proyeksi perspektif
//gluPerspective(fov, 1.0, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// inisialisasi kamera pandang
// kamera berada di posisi (0.0f, 0.0f, 0.0f)
gluLookAt(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
// fungsi ini digunakan bila layar akan diresize (default)
// (akan dijelaskan pada praktikum ke-5)
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//gluPerspective(fov, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glOrtho((GLfloat)-SCREEN_WIDTH / 2, (GLfloat)SCREEN_WIDTH / 2,
(GLfloat)-SCREEN_HEIGHT / 2, (GLfloat)SCREEN_HEIGHT / 2, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
}
// fungsi untuk mengatur masukan dari keyboard
void keyboard(unsigned char key, int x, int y)
{
Vec3 result = normalize(cross(camLookAt, camUp));
switch (key)
{
case 'w': // bila tombol 'w' pada keyboard ditekan
// geser pandangan kamera ke depan
camPosition.X += moveSpeed * camLookAt.X;

79
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

camPosition.Y += moveSpeed * camLookAt.Y;


camPosition.Z += moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;
case 's': // bila tombol 's' pada keyboard ditekan
// geser pandangan kamera ke belakang
camPosition.X -= moveSpeed * camLookAt.X;
camPosition.Y -= moveSpeed * camLookAt.Y;
camPosition.Z -= moveSpeed * camLookAt.Z;
glutPostRedisplay();
break;
case 'a': // bila tombol 'a' pada keyboard ditekan
// geser pandangan kamera ke ke kiri
camPosition.X -= moveSpeed * result.X;
camPosition.Y -= moveSpeed * result.Y;
camPosition.Z -= moveSpeed * result.Z;
glutPostRedisplay();
break;
case 'd': // bila tombol 'd' pada keyboard ditekan
// geser pandangan kamera ke kanan
camPosition.X += moveSpeed * result.X;
camPosition.Y += moveSpeed * result.Y;
camPosition.Z += moveSpeed * result.Z;
glutPostRedisplay();
break;
case 'f': // bila tombol 'f' pada keyboard ditekan
// percepat laju pergerakan kamera
moveSpeed = moveSpeed + 0.5f;
glutPostRedisplay();
break;
case 'g': // bila tombol 'g' pada keyboard ditekan
// perlambat laju pergerakan kamera
moveSpeed = moveSpeed - 0.5f > 0.5f ? moveSpeed - 0.5f : 0.5f;
glutPostRedisplay();
break;
case 27: // bila tombol 'esc' pada keyboard ditekan
// keluar program
exit(0);
break;
}
}
// fungsi untuk mengatur masukan tombol dari mouse
void mousebutton(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_UP)
firstMouse = false;
else

80
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

firstMouse = true;
}
}
// fungsi untuk mengatur masukan pergerakan dari mouse
void mousemove(int x, int y)
{
if (firstMouse)
{
lastX = x; lastY =
y; firstMouse =
false;
}
GLfloat xoffset = x - lastX;
GLfloat yoffset = lastY - y;
lastX = x;
lastY = y;
GLfloat sensitivity = 0.05;
xoffset *= sensitivity;
yoffset *= sensitivity;
yaw += xoffset;
pitch += yoffset;
if (pitch > 89.0f)
pitch = 89.0f;
if (pitch < -89.0f)
pitch = -89.0f;
Vec3 front;
front.X = cos(yaw * PHI / 180) * cos(pitch * PHI / 180);
front.Y = sin(pitch * PHI / 180);
front.Z = sin(yaw * PHI / 180) * cos(pitch * PHI / 180);
camLookAt = normalize(front);
glutPostRedisplay();
}
// timer untuk animasi (gunakan bila perlu)
void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(55, timer, 0);
}
// program utama
int main(int argc, char** argv)
{
// inisialisasi jendela OpenGL
// GLUT_SINGLE berarti memakai single buffer
// GLUT_DOUBLE berarti memakai double buffer
// GLUT_RGB berarti mode tampilan yang dipakai RGB
// GLUT_RGBA berarti mode tampilan yang dipakai RGBA
// GLUT_DEPTH berarti memakai depth buffer
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);

81
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

// set ukuran jendela tampilan


// besarnya jendela dalam piksel dalam hal ini 480x480
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
// posisi jendela dilayar komputer dalam piksel
glutInitWindowPosition(100, 100);
// judul jendela (wajib diubah dengan informasi
// NAMA / NIM - JUDUL PRAKTIKUM masing-masing)
glutCreateWindow("Syifa Fauziah_2006133");
// panggil fungsi init untuk melakukan inisialisasi awal
init();
// event handler untuk display, reshape dan keyboard
glutDisplayFunc(display); // display
glutReshapeFunc(reshape); // reshape
glutKeyboardFunc(keyboard); // keyboard
glutMouseFunc(mousebutton); // mouse button
glutMotionFunc(mousemove); // mouse movement
//glutTimerFunc(0, timer, 0); // aktifkan timer bila perlu
// looping
glutMainLoop();
return 0;
}

82
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

Penjelasan

Dalam program tersebut, terdapat implementasi kurva spline cubic menggunakan metode Catmull-
Rom, Bezier, dan Cubic. Berikut adalah beberapa poin utama dari implementasi tersebut:
1. Struktur Data dan Inisialisasi:
• Struktur data `Vec3` digunakan untuk merepresentasikan titik dalam tiga dimensi (X,
Y, Z).
• Variabel-variabel seperti `camPosition`, `camLookAt`, dan `camUp` digunakan untuk
mengontrol posisi dan orientasi kamera.
• Ada juga variabel-variabel untuk mengatur kecepatan pergerakan kamera, sudut
proyeksi, dan variabel-variabel terkait proyeksi dengan mouse.
2. Fungsi Matematika:
• Terdapat fungsi-fungsi matematika seperti `normalize` untuk normalisasi koordinat
posisi dan `cross` untuk melakukan operasi perkalian cross pada vektor.
3. Fungsi Matriks:
• Fungsi `inverse` digunakan untuk menghitung invers dari matriks ordo 4x4.
• Fungsi `DotMatrix` digunakan untuk melakukan perkalian matriks 4x4 dengan
matriks 4x1.
4. Fungsi Kurva Spline:
• Fungsi `drawSplineBezier` mengimplementasikan kurva spline cubic menggunakan
metode Bezier.
• Fungsi `drawSplineCubic` mengimplementasikan kurva spline cubic menggunakan
metode interpolasi cubic.
• Fungsi `drawSplineCatmullRom` mengimplementasikan kurva spline cubic
menggunakan metode Catmull-Rom.
5. Fungsi Gambar Obyek:
• Fungsi `drawObject` digunakan untuk menggambar obyek, dan di dalamnya, terdapat
penggambaran kurva spline cubic dengan beberapa titik kontrol.
6. Fungsi Display dan Inisialisasi OpenGL:
• Fungsi `display` digunakan untuk merender layar dengan memanggil fungsi-fungsi
penggambaran obyek.
• Fungsi `init` melakukan inisialisasi OpenGL, seperti mengatur warna latar belakang
dan mengaktifkan depth buffer.

83
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

• Fungsi `reshape` digunakan untuk menangani perubahan ukuran layar (resolusi).


7. Fungsi Keyboard:
• Fungsi `keyboard` mengatur respons terhadap input keyboard. Misalnya,
menggerakkan kamera ke depan (`w`) atau ke belakang (`s`).
Program ini menggunakan OpenGL dan GLUT untuk rendering grafis dan interaksi dengan
pengguna. Terdapat juga konsep-konsep dasar dalam grafika komputer seperti proyeksi, transformasi
objek, dan manipulasi kamera.

84
Praktikum Grafika Komputer
Pertemuan ke-7 (Kurva Spline)

III. Kesimpulan

Program ini merupakan implementasi kurva spline cubic dengan menggunakan metode Catmull-
Rom, Bezier, dan interpolasi cubic. Dalam strukturnya, program ini mengadopsi struktur data `Vec3`
untuk merepresentasikan titik dalam tiga dimensi. Terdapat pula fungsi-fungsi matematika dan
matriks yang mendukung perhitungan dan transformasi.
Fungsi utama program ini adalah menggambar kurva spline cubic dengan titik kontrol menggunakan
metode Bezier, interpolasi cubic, dan Catmull-Rom. Kurva ini kemudian digunakan untuk
menggambar obyek pada layar, dan pengguna dapat berinteraksi dengan program melalui input
keyboard untuk menggerakkan kamera.
Selain itu, program ini memanfaatkan OpenGL dan GLUT untuk rendering grafis dan menangani
event. Konsep-konsep dasar dalam grafika komputer seperti proyeksi, transformasi objek, dan
pengaturan kamera turut diterapkan dalam implementasi ini. Program ini menyajikan visualisasi yang
dinamis dan responsif, memungkinkan pengguna untuk mengamati efek dari berbagai metode
interpolasi spline cubic pada kurva yang dihasilkan.

85

Das könnte Ihnen auch gefallen