BAB-3 ATRIBUT PRIMITIF 2D Yang termasuk dalam atribut primitive adalah titik dan garis. Pembetuk garis yang dikenal adalah algoritma DDA, dan Bresenham. Oleh : I Gusti Ngurah Suryantara,S.Kom., M.Kom 3.1. PENDAHULUAN Yang merupakan atribut primitif adalah: titik dan garis. Ada beberapa metode pembentuk garis yang umum digunakan yaitu: Algoritma DDA (Digital Defferential Analyzer) Algoritma Bressenham 3.1.1. DDA (Digital Defferential Analyzer) Garis merupakan kumpulan dari titik-titik, untuk membentuk garis lurus adalah dengan mengetahui titik awal dan titik akhir. Dengan mengetahui titik awal dan titik akhir maka kita dapat membentuk garis. Untuk menggambarkan proses pembuatan garis dari titik awal ke titik akhir ada berbagai algoritma. Algoritma yang umum adalah DDA dan Bresenham. Berikur ini adalah algoritma DDA 1. Tentukan 2 buah titik. 2. Tentukan yang menjadi titik awal (X 0,Y 0 ) dan titik akhir (X 1,Y 1 ). 3. Hitung Dx dan D y D x = X 1 -X 0 dan D y = Y 1 Y 0 4. Bandingkan Abs(D x ) dan Abs(D y ) Jika Abs(D x ) > Abs(D y ) maka Steps = Abs(D x ) bila tidak Steps = Abs(D y ) 5. Hitung penambahan koordinat pixel, yaitu: X_increment = dx/steps, dan Y_increment = dy/steps. 6. Koordint selanjutnya, yaitu X+X_increment Y+Y_increment 7. Posisi pixel ditentukan dengan pembulatan nilai koordinat tersebut. 8. Ulangi langkah 6 dan 7 untuk posisi selanjutnya sampai X = X 1, Y = Y 1 48
DDA (bahasa pascal) Procedure DDA; Begin Write( Masukkan Nilai X0 : ); Write( Masukkan Nilai Y0 : ); Write( Masukkan Nilai X1 : ); Write( Masukkan Nilai Y1 : ); Dx:= X1-X0; Dy:= Y1-Y0; If Abs(Dx) > Abs(Dy) Then Steps:= Abs(Dx) Else Steps:= Abs(Dy); Endif Xincrement = dx / Steps Yincrement = dy / Steps PutPixel(x,y,Hitam); For x = 1 to Steps Do X := X + Xincrement; Y := Y + Yincrement; PutPixel(x,y,Hitam); End; End; Readln(X0); Readln(Y0); Readln(X1); Readln(Y1); Contoh Diketahui 2 buah titik A(10,10) dan titik B(17,16), bila titik A sebagai titik awal dan titik B sebagai titik akhir maka buatlah garis yang menghubungkan titik tersebut dengan menggunakan algoritma DDA. Jawab Titik Awal = A(10,10) Titik Akhir = B(17,16) D x = (X 1 -X 0 ) (17-10) = 7 D y = (Y 1 -Y 0 ) (16-10) = 6 Abs(D x ) = Abs(7) = 7 Abs(D y ) = Abs(6) = 6 Abs(D x ) > Abs(D y ) maka Step = Abs(D x ) = 7 Xincrement = Dx / Step = 7 / 7 = 1 Yincrement = Dy / Step = 6 / 7 = 0,86 Tabel 3.1. Nilai perhitungan 49
K X Y Xinc Yinc - - - 10 10 0 11 10,86 11 11 1 12 11,71 12 12 2 13 12,57 13 13 3 14 13,43 14 14 4 15 14,28 15 14 5 16 15,14 16 15 6 17 16 17 16 Y 16 B(17,16) 10 A(10,10) 10 17 X Digambar Pada Layar Monitor x Gambar 3.1. Digambar pada sumbu cartesian y Gambar 3.2. Coordinat monitor Berikut hasil tampilan program dengan menggnakan algoritma DDA. 50
Gambar 3.3. Tampilan DDA dengan VB 4.1.2.BRESSENHAM ALGORITMA BRESSENHAM Tujuan dari algoritma Bressenham ini adalah untuk menghindari pembulatan nilai seperti pada algoritma DDA. 1. Tentukan dua titik yang akan dihubungkan dalam pembentukan garis. 2. Tentukan salah satu titik di sebelah kiri sebagai titi awal, yaitu (x 0,y 0 ) dan titik lainnya sebgai titik akhir (x 1,y 1 ). 3. Hitung d x,d y,2 dx dan 2 dy -2 dx. 4. Hitung parameter P 0 = 2 dy -d x 5. Untuk setiap X k sepanjang jalur garis, dimulai dengan k=0, - bila p k <0, maka titik selanjutnya adalah (x k +1, y k ), dan P k+1 = P k +2 dy - bila tidak, maka titik selanjutnya adalah (x k +1,y k +1), dan P k+1 = P k +2 dy -2 dx 6. Ulangi langkah no 5 untuk menentukan posisi pixel selanjutnya, sampai x = x 1 dan y = y 1. 51
Sub Rutim Berssenham dalam C Void line (int xa, ya, xb, yb, xend; flot x,y) { Int dx = abs(xb-xa), dy=abs(yb-ya); Int p = 2*dy-dx; Int twody = 2*dy, twodydx = 2*(dy-dx); If (xa>xb) { X = xb; Y = yb; Xend = xa; } Else{ X = xa; Y = ya; xend = xb; } SetPixel(x,y); While (x<xend) { X=X+1; If (p<0) P = P + twody; Else{ Y = Y + 1; P = P + twodydx; } SetPixel(x,y); } }; Contoh Berdasarkan contoh pada algoritma DDA buatlah dengan metode bresenham. JAWAB dx = abs(xb xa) = abs(17 10 ) = 7 dy = abs(yb ya) = abs(16 10) = 6 p = 2 * dy - dx = 2 * 6 7 = 5 twody = 2 * dy = 2 * 6 = 12 twodydx = 2 * (dy dx ) = 2 * ( 6 7 ) = -2 Periksa xa dan xb xa = 10 < xb = 17 Maka 52
x = xa = 10 y = ya = 10 Xend = xa = 17 Ulangi selama x < xend K0: x = x + 1 = 10 + 1 = 11 Periksa nilai p, dimana p = 5 y = y + 1 = 10 + 1 = 11 p = p + twodydx = 5 + (-2) = 3 K1: x = x + 1 = 11 + 1 = 12 Periksa nilai p, dimana p = 3 y = y +1 = 11 + 1 = 12 p = p + twodydx = 3 + (-2) = 1 K2: x = x + 1 = 12 + 1 = 13 Periksa nilai p, dimana p = 1 y = y +1 = 12 + 1 = 13 p = p + twodydx = 1 + (-2) = -1 K3: x = x + 1 = 13 + 1 = 14 Periksa nilai p, dimana p = -1 Nilai y tetap yaitu y=13 p = p + twody = (-1) + 12 = 11 K4: x = x + 1 = 14 + 1 = 15 Periksa nilai p, dimana p = 11 53
y = y +1 = 13 + 1 = 14 p = p + twodydx = 11 + (-2) = 9 K5: x = x + 1 = 15 + 1 = 16 Periksa nilai p, dimana p = 9 y = y +1 = 14 + 1 = 15 p = p + twodydx = 9 + (-2) = 7 K6: x = x + 1 = 16 + 1 = 17 Periksa nilai p, dimana p = 7 y = y +1 = 15 + 1 = 16 p = p + twodydx = 7 + (-2) = 5 Proses berhenti karena x = x 1 dan y = y 1 Masukkan nilai kedalam tabel, seperti pada tabel 3.2. Tabel 3.2.Hasil penelusuran dengan bressenham K P k (X k+1, Y k+1 ) - - 10,10 0 3 11,11 1 1 12,12 2-1 13,13 3 11 14,13 4 9 15,14 5 7 16,15 6 5 17,16 54
Y Digambar pada sumbu cartesian 16 B(17,16) 10 A(10,10) 10 17 x Gambar 3.4. Hasil perhitungan dengan bressenham Latihan Diketahui 2 buah titik yaitu, A(25,27) dan B(20,17), buatlah garis dengan menggunakan algoritma DDA dan Bressenham. PRAKTIKUM Latihan Praktikum 1 Pada latihan kali ini kita akan membuat program pembentuk garis dengan menggunakan algoritma DDA. Desain sebuah form seperti pada Gambar 3.5. Contoh program garis DDA dengan VB Gambar 3.5. Hasil program DDA dengan VB 55
Setting Property Objek Properti Setting Form1 Nama FrmDDA AlgoritmaDDA Frame1 Frame1 Bidang Gambar Frame2 Frame2 Titik Awal Frame3 Frame3 Titik Akhir PictureBox1 ScaleMode PicBidangGambar Pixel Label1 Label1 X0 Label2 Label2 Y0 TextBox1 TxtX0 Text TextBox2 TxtY0 Text Label3 Label3 X1 Label4 Label4 Y1 TextBox3 TxtX1 Text TextBox4 TxtY1 Text Label5 Label5 X_Inc, Y_Inc ListBox1 ListData CommandButton1 Capton cmdok &Ok CommandButton2 cmdcancel &Cancel Buat Modul Buat sebuah modul dengan nama module1 Option Explicit Public SzeX As Long, SzeY As Long Public PSzeX As Long, PSzeY As Long Public PixSze As Long Public ShowGrid As Boolean Public PenWidth As Long Type POINTAPI X As Long Y As Long End Type 56
Declare Function CreatePen Lib "gdi32" (ByVal npenstyle As Long, ByVal nwidth As Long, ByVal crcolor As Long) As Long Declare Function CreateSolidBrush Lib "gdi32" (ByVal crcolor As Long) As Long Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hobject As Long) As Long Declare Function DeleteObject Lib "gdi32" (ByVal hobject As Long) As Long Declare Function Rectangle Lib "gdi32" (ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long Declare Function LineTo Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long Declare Function MoveToEx Lib "gdi32" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, lppoint As POINTAPI) As Long Public Sub APIline(hdc As Long, PenType As Long, BorderW As Long, BorderKl As Long, _ ix1 As Long, iy1 As Long, ix2 As Long, iy2 As Long) Dim Pt As POINTAPI Dim hpn As Long, hpnold As Long hpn = CreatePen(PenType, BorderW, BorderKl Xor &H1000000) hpnold = SelectObject(hdc, hpn) MoveToEx hdc, ix1, iy1, Pt LineTo hdc, ix2, iy2 SelectObject hdc, hpnold DeleteObject hpn Public Sub APIrect(hdc As Long, BorderW As Long, BorderKl As Long, FillKl As Long, _ ix1 As Long, iy1 As Long, ix2 As Long, iy2 As Long) Dim hpn As Long, hpnold As Long Dim hbr As Long, hbrold As Long hpn = CreatePen(0, BorderW, BorderKl Xor &H1000000) hpnold = SelectObject(hdc, hpn) hbr = CreateSolidBrush(FillKl Xor &H1000000) hbrold = SelectObject(hdc, hbr) Rectangle hdc, ix1, iy1, ix2, iy2 SelectObject hdc, hbrold DeleteObject hbr SelectObject hdc, hpnold DeleteObject hpn Program garis DDA Option Explicit Dim Loading As Boolean Dim CurCol As Long ' current color = pallet ID Dim prszex As Long Dim prszey As Long Private Sub GambarPixel(X As Long, Y As Long, Color As Long) Dim ex1 As Long, ey1 As Long Dim ex2 As Long, ey2 As Long If PenWidth = 1 Then ex1 = X * PixSze ey1 = Y * PixSze ex2 = (X + 1) * PixSze 57
ey2 = (Y + 1) * PixSze APIrect BidangGambar.hdc, 0, 8, Color, ex1, ey1, ex2, ey2 Else ex1 = (X - PenWidth \ 2) * PixSze ey1 = (Y - PenWidth \ 2) * PixSze If PenWidth = 3 Or PenWidth = 5 Then ex2 = (X + PenWidth \ 2 + 1) * PixSze ey2 = (Y + PenWidth \ 2 + 1) * PixSze Else ex2 = (X + PenWidth \ 2) * PixSze ey2 = (Y + PenWidth \ 2) * PixSze End If APIrect BidangGambar.hdc, 0, Color, Color, ex1, ey1, ex2, ey2 End If BidangGambar.Refresh 'membuat grid lines Private Sub GambarGrid() Dim I As Long Dim J As Long For I = 0 To SzeY - 1 APIline BidangGambar.hdc, 0, 0, 8, 0, I * PixSze, SzeX * PixSze, I * PixSze Next I For I = 0 To SzeX - 1 For J = 5 To SzeX Step 5 BidangGambar.ForeColor = vbred APIline BidangGambar.hdc, 0, 0, vbblue, J * PixSze, 0, J * PixSze, SzeY * PixSze Next J APIline BidangGambar.hdc, 0, 0, 8, I * PixSze, 0, I * PixSze, SzeY * PixSze Next I For J = 5 To SzeY Step 5 BidangGambar.ForeColor = vbred APIline BidangGambar.hdc, 0, 1, vbgreen, 0, J * PixSze, SzeX * PixSze, J * PixSze Next J 'menampilkan grid lines pada bidang gamar Private Sub PixelKecilKeBesar() If ShowGrid Then GambarGrid BidangGambar.Refresh Private Sub cmdgambar_click() Dim dx, dy, k As Integer Dim XIncrement, YIncrement, X, Y As Variant Dim Steps As Single 'Bersihkan bidang gambar BidangGambar.Cls PixelKecilKeBesar ListView1.ListItems.Clear Loading = False PenWidth = Val(scrollTebalGaris.Value) 'atur ketebalan garis 'Hitung Dx dan Dy 58
dx = Val(txtX1.Text) - Val(txtX0.Text) dy = Val(txtY1.Text) - Val(txtY0.Text) 'Cari nilai steps If Abs(dX) > Abs(dY) Then Steps = Abs(dX) Else Steps = Abs(dY) End If 'Hitung XIncrement dan YIncrement XIncrement = dx / Steps YIncrement = dy / Steps X = Val(txtX0.Text) Y = Val(txtX0.Text) 'Hidupkan pixel pada posisi x,y GambarPixel Round(X), Round(Y), CurCol ListView1.ListItems.Add,, "-" ListView1.ListItems(ListView1.ListItems.Count).SubItems(1) = "-" ListView1.ListItems(ListView1.ListItems.Count).SubItems(2) = "-" ListView1.ListItems(ListView1.ListItems.Count).SubItems(3) = Round(X) ListView1.ListItems(ListView1.ListItems.Count).SubItems(4) = Round(Y) For k = 1 To Steps X = X + XIncrement Y = Y + YIncrement 'Hidupkan pixel pada posisi x + xincremen,y + yincrement GambarPixel Round(X), Round(Y), CurCol ListView1.ListItems.Add,, k ListView1.ListItems(ListView1.ListItems.Count).SubItems(1) = X ListView1.ListItems(ListView1.ListItems.Count).SubItems(2) = Y ListView1.ListItems(ListView1.ListItems.Count).SubItems(3) = Round(X) ListView1.ListItems(ListView1.ListItems.Count).SubItems(4) = Round(Y) Next k Private Sub cmdkeluar_click() Unload Me Private Sub Form_Activate() If Loading = True Then PixelKecilKeBesar Loading = False End If Private Sub Form_Load() 'Menampilkan data di list view Call ListView1.ColumnHeaders.Add(,, "k", 300) Call ListView1.ColumnHeaders.Add(,, "X", 700) Call ListView1.ColumnHeaders.Add(,, "Y", 700) Call ListView1.ColumnHeaders.Add(,, "Xk+1", 600) Call ListView1.ColumnHeaders.Add(,, "Yk+1", 600) ListView1.ListItems.Clear Loading = True 59
PixSze = 8 SzeX = 128: SzeY = 64: prszex = 127: prszey = 63 PSzeX = 8: PSzeY = 8 ShowGrid = True PenWidth = 1 'atur ketebalan garis 'Untuk mendapatkan nilai posisi kursor di koordinat x,y Private Sub BidangGambar_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) lblx. = (X \ PixSze) lbly. = (Y \ PixSze) Private Sub scrolltebalgaris_change() TebalGaris.BorderWidth = scrolltebalgaris.value Tugas Buatlah Program pembentuk garis menggunakan algoritma Bresenham. 60