Anda di halaman 1dari 11

GRAFIKA KOMPUTER

“RESUME TEKNIK SCAN TRIANGLES”


 

 
 

Disusun Oleh :
 

Nama                    : Afifah Putri Mevtilina


NIM                      : 09021282025052
Kelas                    : 4 Reguler C
Dosen                   : M. Fachrurrozi, S.SI., M.T.
 

FAKULTAS ILMU KOMPUTER


PROGRAM STUDI TEKNIK INFORMATIKA
UNIVERSITAS SRIWIJAYA
2022
TEKNIK SCAN TRIANGLES

Homogeneus coordinates biasanya digunakan untuk transformasi dalam grafik 3D. Mereka
biasa digunakan karena rotasi, penskalaan, translasi dan perspektif yang semuanya linier
dalam ruang homogen. Akibatnya, transformasi dapat diekspresikan secara seragam dalam
matriks bentuk dan dapat dengan mudah digabungkan menjadi matriks komposit tunggal.
Sementara homogeneus coordinates digunakan untuk transformasi 3D, poin dikonversi
kembali ke 3D yang sebenarnya setelah hither clipping. Satu dari alasan bahwa hither
clipping diperlukan adalah untuk menghindari singularitas dalam konversi.

Segitiga mungkin yang paling penting diisi primitif. Beberapa alasan untuk ini adalah:

 Segitiga minimal

Mereka ditentukan hanya dengan 3 poin atau 3 tepi.

 Segitiga yang selalu convex polygons

Suatu poligon cembung jika dan hanya jika setiap ruas garis yang menghubungkan
dua titik pada batasnya terdapat seluruhnya di dalam poligon atau salah satu sisinya.
 Segitiga secara matematis sangat sederhana

Matematika yang terlibat dalam pemindaian mengubah segitiga hanya melibatkan


persamaan linier sederhana.

 Bentuk arbitrer dapat didekati dengan segitiga 

Bentuk 2 dimensi apa pun dapat didekati dengan poligon menggunakan pendekatan
linier lokal ke permukaan. Untuk meningkatkan kualitas kecocokan, kita hanya perlu
menambah jumlah tepi.

 Setiap poligon dapat didekomposisi menjadi segitiga

Sebuah poligon bersisi-n cembung, dengan simpul-simpul terurut {v 0 , v 1 , ... v n } di
sepanjang kelilingnya, dapat diuraikan menjadi segitiga-segitiga {(v 0 ,v 1 ,v 2 ),
{v 0 ,v 2 ,v 3 ), (v 0 ,v i ,v i+1 ), ... (v 0 ,v n-1 ,v n )}.

Kita biasanya dapat menguraikan poligon tidak cembung menjadi segitiga, tetapi
poligon ini non-trivial, dan dalam beberapa kasus yang tumpang tindih, kita harus
memasukkan simpul baru.
Ada dua strategi umum untuk memindai-mengonversi segitiga. Yang pertama
menggunakan edge walking dan yang kedua menggunakan edge equations.

Edge-walking

Catatan di edge walking:

 Urutkan simpul di x dan y


 Tentukan apakah titik tengah, atau titik putus terletak di sisi kiri atau kanan
poligon. Jika segitiga memiliki sisi yang sejajar dengan arah scanline maka tidak ada
breakpoint.
 Menentukan tepi kiri dan kanan untuk setiap garis pindai (disebut spans).
 Menuju ke bawah tepi kiri dan kanan untuk mengisi piksel di antara sampai
breakpoint atau titik bawah tercapai.
 Keluar dari perubahan tepi jalan aktif.

Keuntungan dan kerugian:

 Sarat dengan kasus khusus (breakpoint kiri dan kanan, tidak ada breakpoints)
 Sulit untuk mendapatkan yang benar
 Membutuhkan komputasi offset fraksional saat menginterpolasi parameter melintasi
segitiga
 Umumnya sangat cepat

Edge equations

Pendekatan lain untuk rasterisasi segitiga menggunakan edge equations untuk menentukan
piksel mana yang akan diisi. Edge equations adalah nama lain untuk fungsi pembeda yang
kita gunakan dalam algoritma kurva dan gambar garis. Edge equations membagi daerah
planar menjadi tiga bagian, batas, dan dua setengah ruang. Batas diidentifikasi oleh titik-titik
di mana persamaan tepi sama dengan nol. Setengah ruang dibedakan oleh perbedaan tanda
persamaan tepi. Kita dapat memilih setengah ruang mana yang memberikan tanda positif
dengan mengalikan dengan -1.

Catatan tentang penggunaan edge equations untuk memindai-mengonversi segitiga:

 Hitung persamaan tepi dari simpul


 Orientasikan persamaan tepi sehingga ruang setengah positifnya berada di bagian
dalam segitiga
 Hitung kotak pembatas
 Pindai melalui piksel dalam kotak pembatas yang mengevaluasi persamaan
tepi. Ketika ketiganya positif maka gambarlah pikselnya.

Berikut adalah contoh implementasi rasterizer segitiga yang menggunakan persamaan tepi.

Sebelum memulai, kita akan mendefinisikan beberapa objek yang berguna.

Pertama di sini adalah representasi dari sebuah simpul

public class Vertex2D {


public float x, y; // coordinate of vertex
public int argb; // color of vertex

public Vertex2D(float xval, float yval, int cval)


{
x = xval;
y = yval;
argb = cval;
}
}

Selanjutnya kita mendefinisikan objek EdgeEquation

class EdgeEqn {
public final static int FRACBITS = 12;
public int A, B, C;
public int flag;

public EdgeEqn(Vertex2D v0, Vertex2D v1)


{
double a = v0.y - v1.y;
double b = v1.x - v0.x;
double c = -0.5f*(a*(v0.x + v1.x) + b*(v0.y + v1.y));

A = (int) (a * (1<<FRACBITS));
B = (int) (b * (1<<FRACBITS));
C = (int) (c * (1<<FRACBITS));
flag = 0;
if (A >= 0) flag += 8;
if (B >= 0) flag += 1;
}

public void flip()


{
A = -A;
B = -B;
C = -C;
}

public int evaluate(int x, int y)


{
return (A*x + B*y + C);
}
}

Perhatikan bahwa disini menggunakan bilangan bulat untuk koefisiennya. Implementasi ini


menggunakan 12 bit pecahan, sehingga penggunaan praktisnya akan terbatas pada layar
dengan resolusi 4096 by 4096 atau kurang.

Kita menentukan koefisien persamaan tepi menggunakan dua titik di tepi. Setiap titik
menentukan persamaan dalam hal tiga tidak diketahui, A , B , dan C .

Kita dapat menyelesaikan A dan B dalam suku C dengan menyiapkan sistem linier homogen
berikut.
Mengalikan kedua ruas dengan invers matriks.

Jika kita memilih  , maka kita dapatkan 

dan  . Persamaan untuk A dan B cocok dengan persamaan yang muncul dalam


definisi metode.

Untuk memahami ekspresi yang digunakan untuk C , kita perlu mendiskusikan presisi
numerik dari perhitungan floating point yang digunakan oleh komputer. Komputer mewakili
angka floating-point secara internal dalam format yang mirip dengan notasi ilmiah. Setiap
angka disimpan dengan bagian pecahan yang memiliki jumlah angka penting yang tetap
bersama dengan eksponen. Jika kita mengingat kembali pelajaran kimia atau fisika, hal yang
paling buruk yang dapat kita lakukan dengan angka yang direpresentasikan dalam notasi
ilmiah adalah mengurangi angka dengan besaran yang sama. Inilah yang terjadi. Misalkan
kita memiliki empat angka penting dalam notasi kita. Jika kita mengurangkan bilangan-
bilangan yang besarnya sama seperti gambar di bawah ini:

Kita kehilangan sebagian besar angka penting dalam hasil.

Dalam kasus segitiga, kita dapat mengharapkan masalah presisi semacam ini sering terjadi,
karena secara umum simpul segitiga biasanya relatif dekat satu sama lain.

dan  dengan demikian 

Untungnya, kita dapat menghindari pengurangan bilangan besar ini saat menghitung ekspresi
untuk C. Mengingat bahwa kita mengetahui A dan B , kita dapat menyelesaikan C sebagai
berikut:

atau

Untuk menghilangkan bias yang tidak perlu terhadap salah satu simpul dalam perhitungan,
dapat menghitung rata-rata nilai C ini sebagai berikut.
Ini adalah ekspresi untuk C yang muncul dalam metode, dan ini menghindari banyak masalah
numerik yang mengganggu pendekatan lain.

Bendera digunakan dalam menghitung kotak pembatas. Selanjutnya, mari kita lihat loop
utama dari rasterizer.

public class FlatTri implements Drawable {


protected Vertex2D v[];
protected int color;

public FlatTri()
{
}

public FlatTri(Vertex2D v0, Vertex2D v1, Vertex2D v2)


{
v = new Vertex2D[3];
v[0] = v0;
v[1] = v1;
v[2] = v2;

/*
... Our policy is to assign a triangle
the average of it's vertex colors ...
*/
int a = ((v0.argb >> 24) & 255) + ((v1.argb >> 24) & 255) +
((v2.argb >> 24) & 255);
int r = ((v0.argb >> 16) & 255) + ((v1.argb >> 16) & 255) +
((v2.argb >> 16) & 255);
int g = ((v0.argb >> 8) & 255) + ((v1.argb >> 8) & 255) +
((v2.argb >> 8) & 255);
int b = (v0.argb & 255) + (v1.argb & 255) + (v2.argb & 255);

a = (a + a + 3) / 6;
r = (r + r + 3) / 6;
g = (g + g + 3) / 6;
b = (b + b + 3) / 6;

color = (a << 24) | (r << 16) | (g << 8) | b;


}
protected EdgeEqn edge[];
protected int area;
protected int xMin, xMax, yMin, yMax;
private static byte sort[][] = {
{0, 1}, {1, 2}, {0, 2}, {2, 0}, {2, 1}, {1, 0}
};

public void Draw(Raster r) {


if (!triangleSetup(r)) return;

int x, y;
int A0 = edge[0].A;
int A1 = edge[1].A;
int A2 = edge[2].A;

int B0 = edge[0].B;
int B1 = edge[1].B;
int B2 = edge[2].B;

int t0 = A0*xMin + B0*yMin + edge[0].C;


int t1 = A1*xMin + B1*yMin + edge[1].C;
int t2 = A2*xMin + B2*yMin + edge[2].C;

yMin *= r.width;
yMax *= r.width;

/* .... scan convert triangle .... */

for (y = yMin; y <= yMax; y += r.width) {


int e0 = t0;
int e1 = t1;
int e2 = t2;
int xflag = 0;
for (x = xMin; x <= xMax; x++) {
if ((e0|e1|e2) >= 0) { // all 3 edges must be >= 0
r.pixel[y+x] = color;
xflag++;
} else if (xflag != 0) break;
e0 += A0;
e1 += A1;
e2 += A2;
}
t0 += B0;
t1 += B1;
t2 += B2;
}
}
Hampir semuanya di sini lurus ke depan, dengan dua pengecualian.

 Ketiga sisi diuji dengan perbandingan tunggal dengan menyatukan ketiga sisi dan
memeriksa apakah hasilnya positif. Jika salah satu dari ketiganya negatif maka bit
tandanya akan diset ke 1, dan hasil dari or akan negatif.
 Karena segitiga adalah cembung, kita hanya bisa berada di dalam untuk satu interval
pada setiap garis pindai yang diberikan. Variabel xflag digunakan untuk melacak saat
kita keluar dari interior segitiga. Jika kita menemukan diri kita berada di luar segitiga
yang telah menetapkan beberapa piksel pada rentang, maka kita dapat melewati sisa
garis pindaian.

protected boolean triangleSetup(Raster r)


{
if (edge == null) edge = new EdgeEqn[3];

/*
Compute the three edge equations
*/
edge[0] = new EdgeEqn(v[0], v[1]);
edge[1] = new EdgeEqn(v[1], v[2]);
edge[2] = new EdgeEqn(v[2], v[0]);

/*
Trick #1: Orient edges so that the
triangle's interior lies within all
of their positive half-spaces.

Assuring that the area is positive


accomplishes this
*/
area = edge[0].C + edge[1].C + edge[2].C;
if (area == 0) return false; // degenerate triangle
if (area < 0) {
edge[0].flip();
edge[1].flip();
edge[2].flip();
area = -area;
}

/*
Trick #2: compute bounding box
*/
int xflag = edge[0].flag + 2*edge[1].flag + 4*edge[2].flag;
int yflag = (xflag >> 3) - 1;
xflag = (xflag & 7) - 1;
xMin = (int) (v[sort[xflag][0]].x);
xMax = (int) (v[sort[xflag][1]].x + 1);
yMin = (int) (v[sort[yflag][1]].y);
yMax = (int) (v[sort[yflag][0]].y + 1);

/*
clip triangle's bounding box to raster
*/
xMin = (xMin < 0) ? 0 : xMin;
xMax = (xMax >= r.width) ? r.width - 1 : xMax;
yMin = (yMin < 0) ? 0 : yMin;
yMax = (yMax >= r.height) ? r.height - 1 : yMax;
return true;
}

Dalam metode ini dilakukan dua hal penting. Kita mengorientasikan edge equations, dan
menghitung kotak pembatas.

Anda mungkin juga menyukai