Tuesday, 21 April 2015

Memperoleh Hari sesuai Tanggal


Kali ini kita akan meminta user memasukkan tanggal, bulan, dan tahun, lalu secara otomatis program akan menampilkan hari sesuai tanggal tersebut. Yang kita perlukan adalah library <ctime> dengan menggunakan tipe data bentukan tm . Untuk itu perhatikan kode berikut :

.

#include <ctime>
#include <iostream>

using std::cout;
using std::cin;

int main()
{
    std::tm waktu = {};
    
    cout<<"Masukkan Tahun = ";
    cin>>waktu.tm_year;
    waktu.tm_year-=1900;     //perlu dikurangi karena tahun dimulai dari 1900

    cout<<"Masukkan Bulan = "; 
    cin>>waktu.tm_mon;
    waktu.tm_mon -= 1;       //indeks bulan dimulai dari 0

    cout<<"Masukkan Tanggal = "; 
    cin>>waktu.tm_mday;
    
    //mengatur nilai
    mktime( &waktu);

    cout<<"Hari pada tgl. "<<waktu.tm_mday<<"-"<<waktu.tm_mon<<"-"<< (1900+waktu.tm_year) <<" adalah "<<waktu.tm_wday;

    return 0;    
}

.

Fungsi mktime akan menyesuaikan data yang ada pada nilai-nilai variabel waktu menjadi format data yang sesuai pada sistem waktu di komputer. Misal ketika user memasukkan nilai tahun=2014 dan bulan bernilai 15, maka hasil yang diperoleh adalah tahun=2015 dan bulan=3. Karena nilai bulan telah melebihi setahun dan secara otomatis variabel tm_year bertambah satu. Yang perlu diperhatikan sebelum memproses nilai-nilai tersebut adalah bulan harus dikurang 1 karena indeks nya dimulai dari nol. Selain itu nilai tahun harus dikurang 1900, karena perhitungannya dimulai dari 1900.

Dari kodingan diatas, saat dijalankan ternyata hasil yang diperoleh berupa angka (variabel tm_wday) dimulai dari 0-6 , 0=Minggu, 1=Senin, dst. Untuk itu kita perlu membuat array konstan yang menampung nama-nama hari dalam satu minggu, perhatikan kode berikut :

  
.        
     const char * hari[] = { "Minggu", "Senin", "Selasa", "Rabu",
                             "Kamis", "Jumat", "Sabtu"};

     const char * bulan[] = { "Januari", "Februari", "Maret", "April", "Mei",
                              "Juni", "Juli", "Agustus", "September",
                              "Oktober", "November","Desember"};
     ...

     cout << "Hari pada tgl. " << waktu.tm_mday << " " << bulan[waktu.tm_mon] << " " << (1900+waktu.tm_year) << " adalah " << hari[waktu.tm_wday];
.

Selain hari, bulan dan tahun terdapat juga anggota variabel waktu lainnya seperti tm_hour, tm_min, dan tm_sec pada struktur tm. Proses perhitungan juga akan disesuaikan. Contoh saat memasukkan nilai 65 pada menit maka saat fungsi mktime dipanggil, nilai jam akan bertambah 1 jam dan menit akan dikurang 60 menit. Tentunya struktur data ini dapat membantu kita untuk pemrosesan yang berhubungan dengan waktu. Akhir kata, Happy Coding! :D

- krofz

Saturday, 4 April 2015

SDL2 : Dimulai dari Sebuah Titik (Piksel) #5


Tulisan ini merupakan lanjutan dari:

Sebuah titik saja tidak cukup, mari kita membuatnya dari garis karena hasil yang diperoleh akan lebih baik. Yang diperlukan adalah koordinat lama, kita namakan X2 dan Y2. Perhatikan kode berikut :
   
   ...
      int X2=0,Y2=0;
      for(int X1=0; X1 < Layar_Lebar; X1++){

         //Memperoleh derajat untuk Y , dimana 1 gelombang = 360 derajat
         int derajat = X1*((iPulse*360.0f)/Layar_Lebar);

         //setiap nilai X bernilai sekian derajat tergantung banyak iPulse
         int Y1 = (Layar_Tinggi/2) +
                  cos(derajat*PI/180.0)*iTinggi;

         // Jika salah satu dari dua titik berada pada dimensi layar,
         // maka selanjutnya membuat garis.
         if( ((X1 > 0 && X1 < Layar_Lebar) && (Y1 > 0 && Y1 < Layar_Tinggi)) ||
             ((X2 > 0 && X2 < Layar_Lebar) && (Y2 > 0 && Y2 < Layar_Tinggi)))
         {
            //proses drawing
            SDL_RenderDrawLine( gRenderer, X1, Y1, X2, Y2);

         }

         //Menyimpan titik terakhir pada (X2,Y2)
         X2 = X1;
         Y2 = Y1;
      }
   ...

Proses penggambaran terjadi jika X1 atau X2 lebih besar dari 0 (nol) begitu pula untuk Y1 atau Y2 > 0. Yang perlu diperhatikan adalah variabel X2 dan Y2. Karena kita melakukan inisialisasi dengan nilai 0 (nol), maka (X2,Y2) = (0,0) dan X1,Y1 berada di posisi tertentu. Sehingga hasilnya tidak sesuai yang diharapkan. Untuk memperbaikinya dapat mengisi nilai awal sama seperti X1 dan Y1 pada X2 dan Y2.

Fungsi SDL_RenderDrawLine( gRenderer, X1, Y1, X2, Y2), sangat mudah digunakan, parameter yang perlu diisi pun cukup jelas. Sampai disini SDL2 sudah menyediakan banyak fungsi basic untuk proses penggambaran primitif yang lebih baik dan pemanfaatan akselerasi Hardware yang lebih powerful. So, Happy Coding! .

- krofz

Thursday, 12 March 2015

SDL2 : Dimulai dari Sebuah Titik (Piksel) #4


Tulisan ini merupakan lanjutan dari:

Seperti yang kita bahas sebelumnya, kini saatnya menambahkan tinggi dan banyaknya gelombang. Tambahkan variabel iPulse dan iTinggi seperti dibawah ini :
   
   ...
    //Variabel untuk menampung event masukkan
    SDL_Event e;
    int iPulse = 5 , iTinggi = 80;

    //Loop utama kita
    while( !keluar )
    {
   ...

Selanjutnya tambahkan sedikit perintah untuk mengatur nilai variabel tersebut dengan memeriksa tombol pada keyboard, seperti kode berikut :
   
   ...
      //menangani jenis masukkan
      switch ( e.type)
      {
         case SDL_QUIT : keluar = true; break;
         case SDL_KEYDOWN:{
            switch( e.key.keysym.sym){
               case SDLK_UP: if( iPulse < 15) pulse++; break;
               case SDLK_DOWN: if( iPulse > 5) pulse--; break;
               case SDLK_w: if( iTinggi < 300) iTinggi+=10; break;
               case SDLK_s: if( iTinggi > 60) iTinggi-=10; break;
               case SDLK_ESCAPE: keluar = true; break;
               default:;
            }
         }
         default:;
      }
   ...

Selanjutnya kita masuk ke perulangan X sebelumnya, dengan perubahan seperti berikut :
   
   ...
      for(int X=0;X < Layar_Lebar;X++){
      
         // Memperoleh derajat untuk Y , 
         // dimana 1 gelombang = 360 derajat
         int derajat = X*((iPulse*360.0f)/Layar_Lebar);

         // setiap nilai X bernilai sekian derajat,
         // tergantung banyaknya iPulse
         int Y = (Layar_Tinggi/2) +
                 cos(derajat*PI/180.0)*iTinggi;

         //optimasi
         if( (X > 0 && X < Layar_Lebar) &&
             (Y > 0 && Y < Layar_Tinggi))
         {
             //proses penggambaran
             SDL_RenderDrawPoint(gRenderer, X, Y);
         }
      }
   ...

Untuk proses optimasi kita hanya menampilkan titik tersebut jika koordinat (X,Y) berada pada dimensi layar (perhatikan kondisi if). Hasil yang akan diperoleh :


Gambar 1. Gunakan tombol W,S, dan anak panah Atas dan Bawah.

Kelemahan menggambar dengan titik adalah hasil yang diperoleh dapat terlihat putus-putus (perhatikan gambar diatas). Contoh, untuk (X1,Y1) = (5,30), dilanjutkan dengan (X2,Y2) = (6,35), jarak yang diperoleh oleh Y1 dan Y2 cukup jauh sehingga terlihat putus. Untuk itu kita perlu perbaikan proses penggambaran. Pada artikel selanjutnya kita akan menggunakan garis. So, Happy Coding! .

- krofz

Monday, 2 March 2015

SDL2 : Dimulai dari Sebuah Titik (Piksel) #3


Tulisan ini merupakan lanjutan dari:

Pada artikel pertama, kita sudah melihat prototipe, atau bentuk umum penulisan fungsi untuk membuat titik , yaitu cukup mengisi koordinat (X,Y) pada fungsi SDL_RenderDrawPoint(gRenderer, x, y). Lalu untuk menciptakan bentuk seperti bergelombangan, kita dapat menggunakan rumus Y = Cos(X) atau Y = Sin(X). Namun sebelumnya perhatikan Kode berikut :
   
   ...
   //Membersihkan layar
   SDL_SetRenderDrawColor( gRenderer, 0x55, 0x55, 0x55, 0xFF );
   SDL_RenderClear( gRenderer );
   
   //mengatur warna menjadi putih
   SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
   for(int X=100; X<400; X++){
      SDL_RenderDrawPoint(gRenderer, X, 50);
   }

   for(int X=100,Y=X; X<300; X++,Y=X){
      SDL_RenderDrawPoint(gRenderer, X, Y);
   }
   ...

Tambahkan pada loop utama tepatnya setelah proses penanganan event. Hasil yang akan diperoleh adalah 2 buah garis, garis pertama mendatar, dan yang kedua berbentuk garis miring, seperti gambar berikut :


Gambar 1. Dua buah garis.


Dapat dilihat bahwa deretan titik tersebut dapat membentuk sebuah garis atau bentuk lainnya. Tapi seharusnya kita menggunakan fungsi untuk menggambar sebuah garis dibanding menggambar titik demi titik (akan dijelaskan nanti). Okay, kita lanjut ke fungsi Y = Cos(X), algoritmanya sederhana setiap nilai Y didapat dari perhitungan Cos(X). Dimana X ini kita analogikan menggunakan satuan derajat, contoh X=0° / 0 derajat maka akan menghasilkan nilai 1 (Y=1), lalu X=30° bernilai (1/2) akar 3, dst . Untuk menggunakan fungsi Cos kita dapat menggunakan library cmath. Tambahkan code diawal sehingga tampak seperti berikut :

//Start Code
#include <sdl.h>
#include <stdio.h>
#include <cmath>

#define PI 3.14159265
...

Lalu pada main loop, tambah atau ubah kode sebelumnya menjadi berikut :

...
   //Membersihkan layar
   SDL_SetRenderDrawColor( gRenderer, 0x55, 0x55, 0x55, 0xFF );
   SDL_RenderClear( gRenderer );
   
   //mengatur warna menjadi putih
   SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
   for(int X=0;X < Layar_Lebar;X++){
       int Y = cos(X*PI/180.0)*80;
       SDL_RenderDrawPoint(gRenderer, X, (Layar_Tinggi/2)+Y);
   }
...

Saat dijalankan akan terbentuk gelombang seperti gambar berikut :


Gambar 2. Grafik Cos(X).

Dapat dilihat posisi Y untuk X = 1 / 1 derajat dimulai dari setengah dari tinggi layar ditambah 80 px. Karena perhitungan nilai dari cos(1 derajat) adalah 0.9998 dengan mengalikan dengan tinggi yang diinginkan yaitu 80px atau lebih. Dapat dilihat bahwa pada fungsi cos() tidak hanya memasukkan parameter nilai X mentah-mentah, tetapi perlu dikalikan dengan PI (3,14) lalu dibagi 180 derajat. Ini karena fungsi tersebut meminta memasukkan nilai Radian bukan Derajat / Degree. Nilai 1 radian = 57,296 derajat (dengan 3 angka dibelakang koma, aslinya mah banyak :v ). Perhatikan gambar berikut :


Gambar 3. Grafik Cos(X), titik Y dimulai dari 240 (setengah tinggi layar). 

Jadi Cos(3,14 Radian) = (-1) atau bernilai 180 derajat (lebih lanjut tentang radian). Selanjutnya agar dapat menghasilkan gelombang yang lebih banyak dalam satu layar, maka kita perlu persiapkan variabel untuk mengubah banyaknya gelombang. Sebut saja variabel pulse (int pulse = 5) :v . Tidak hanya itu kita juga akan mengatur tinggi titik tersebut pada artikel selanjutnya. So, Happy Coding!


- krofz
 

back to top

back to top