Salah satu cara berlatih pemrograman adalah dengan mencoba mengimplementasikan berbagai algoritma pemrograman ke dalam kode program. Selain dapat melatih keterampilan memrogram, algoritma-algoritma tentunya dibutuhkan oleh seorang programmer dalam pekerjaanya sebagai pengembang software aplikasi. Contoh algoritma yang biasa dipelajari ketika belajar pemrograman adalah algoritma struktur data linked-list, double linked-list, circular-list, tree, sorting dan searching. Dan jika Anda juga mempelajari pemrograman grafis, Anda pasti juga mempelajari berbagai algoritma seperti algoritma menggambar garis, lingkaran, polygon dan lain sebagainya.

Pada tulisan ini, saya akan memberikan contoh implementasi algoritma Bresenham untuk menggambar garis dan lingkaran. Contoh programnya sederhana saja, hanya menampilkan beberapa garis dan lingkaran di layar console.

Lho, kok console? Iya, contoh program ini menggambar garis dan lingkaran pada layar mode teks, bukan grafis. Bukan tanpa tujuan. Tujuan saya selain memberikan contoh implementasi algortima Bresenham’s Line and Circle adalah memperkenalkan konsep menggambar pada layar console (teks) menggunakan buffer layar teks.

Nah, langsung saja, berikut ini adalah listing programnya.

Listing Program linecircle.c

/*
 Bresenham's Line & Circle Demo
 Chandra MDE - https://telinks.wordpress.com
 Kompilasi: $ gcc -o linecircle linecircle.c
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MAXLINE 22

char *screen[MAXLINE];
char init_OK = 0;

int screen_init()
{
  int i;
  for (i=0; i<MAXLINE; i++)
  {
    screen[i] = (char *)calloc(80, sizeof(char));
    if (screen[i]==NULL) return 0;
    memset(screen[i], ' ', 79);
  }
  init_OK = 1;
  return 1;
}

void screen_print()
{
  int i;
  for (i=0; i<MAXLINE; i++) printf("%s\r\n", screen[i]);
}

void screen_outxy(int x, int y, char *s)
{
  while (*s) memset(screen[y-1]+x++ -1, *s++, 1);
}

void screen_free()
{
  int i;
  for (i=0; i<MAXLINE; i++) free(screen[i]);
}

void line(int x0, int y0, int x1, int y1)
{
  int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
  int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
  int err = (dx>dy ? dx : -dy)/2, e2;
  for(;;)
  {
    screen_outxy(x0+1,y0+1, "*");
    if (x0==x1 && y0==y1) break;
    e2 = err;
    if (e2 >-dx) { err -= dy; x0 += sx; }
    if (e2 < dy) { err += dx; y0 += sy; }
  }
}

void circle(int x0, int y0, int radius)
{
  int x = radius, y = 0;
  int radiusError = 1-x;
  while(x >= y)
  {
    screen_outxy(x + x0, y + y0, "*");
    screen_outxy(y + x0, x + y0, "*");
    screen_outxy(-x + x0, y + y0, "*");
    screen_outxy(-y + x0, x + y0, "*");
    screen_outxy(-x + x0, -y + y0, "*");
    screen_outxy(-y + x0, -x + y0, "*");
    screen_outxy(x + x0, -y + y0, "*");
    screen_outxy(y + x0, -x + y0, "*");
    y++;
    if (radiusError<0)
      radiusError += 2 * y + 1;
    else
    {
      x--;
      radiusError+= 2 * (y - x + 1);
    }
  }
}

int main()
{
  printf("Bresenham's Line & Circle\n");
  if (!screen_init()) exit(1);
  line(2, 1, 52, 1);
  line(52, 1, 52, 5);
  line(52, 5, 2, 5);
  line(2, 5, 2, 1);
  screen_outxy(6, 4, "Chandra - https://telinks.wordpress.com");
  circle(5, 17, 3);
  circle(16, 16, 4);
  circle(29, 15, 5);
  circle(44, 14, 6);
  circle(61, 13, 7);
  line(60, 9, 63, 12);
  line(63, 12, 60, 15);
  line(60, 15, 57, 12);
  line(57, 12, 60, 9);
  screen_print();
  screen_free();
  return 0;
}

 

Penjelasan Singkat

Fungsi screen_init()

Fungsi screen_init() adalah fungsi yang bertugas untuk menyiapkan buffer layar dengan ukuran 22 baris kali 80 kolom. Buffer layar ini disimpan dalam variabel array pointer screen. Fungsi mengalokasikan memori menggunakan fungsi calloc() dan mengisinya dengan karakter spasi (‘ ‘) menggunakan fungsi memset().

Fungsi screen_print()

Fungsi screen_print() adalah fungsi yang bertugas untuk menampilkan buffer layar ke layar console. Dengan menggunakan perulangan for fungsi ini mencetak ke layar isi dari variabel screen.

Fungsi screen_outxy()

Fungsi screen_outxy(int x, int y, char *s) bertugas “mencetak” string s pada lokasi (x, y) pada buffer layar screen. Fungsi ini mencetak di buffer layar, jadi tidak menghasilkan tampilan pada layar console. Untuk melihat tampilan sesungguhnya di layar console, maka digunakanlah fungsi screen_print().

Fungsi screen_free()

Alokasi memori yang kita gunakan dalam program seyogyanya kita bebaskan sebelum program diakhiri. Itulah tugas dari fungsi screen_free().

Fungsi line()

Fungsi berikutnya adalah fungsi line(int x0, int y0, int x1, int y1). Fungsi ini bertugas untuk “menggambar” garis menggunakan metode algoritma Bresenham pada buffer layar screen. Penjelasan lebih lengkap mengenai algortima garis Bresenham bisa Anda baca di sini.

Fungsi circle()

Fungsi circle(int x0, int y0, int radius) bertugas untuk “menggambar” lingkaran menggunakan metode algoritma Bresenham pada buffer layar screen. Penjelasan lebih lengkap mengenai algortima lingkaran Bresenham bisa Anda baca di sini.

Fungsi main()

Fungsi program utama bertugas menguji fungsi-fungsi di atas dengan mencetak string dan menggambar beberapa garis dan lingkaran pada buffer layar screen dan menampilkannya ke layar console dengan perintah screen_print().

Kompilasi

Untuk mengompilasi kode program linecircle, gunakan perintah:

$ gcc -o linecircle linecircle.c

Setelah sukses dikompilasi, panggil program linecircle menggunakan perintah:

$ ./linecircle

Dan berikut ini adalah screenshot program linecircle.

Program juga telah saya uji pada platform Windows menggunakan kompiler Pelles C. Berikut adalah screenshotnya.

Nah, sekian dulu dan semoga contoh program di atas bermanfaat.

Terima kasih sudah membaca dan selamat belajar.