Sunday, May 11, 2014

Gerak Pada Bidang Miring: Kesalahan Terbesar Microsoft Excel VBA

Dalam tulisan kali ini saya sedikit berbagi pengalaman dalam menggunakan Microsoft Excel. Kebetulan kemarin saya mencoba membuat sebuah animasi mengenai bidang miring dengan menggunakan VBA ala Microsoft Excel. Masalahnya adalah rumusan saya tentang posisi kotak pada bidang miring itu sudah benar 100 persen. Yang bikin heran kok hasil penggambaran di Microsoft Excel tidak sesuai yang saya harapkan?

Gambar 1. Geometri Bidang Miring


Pada gambar 1, dengan mengingat bahwa koordinat monitor menggunakan titik asal pada TOP-LEFT, maka dapat diberlakukan persamaan: \begin{eqnarray} x_1 = x_2 - w \cdot \sin(\alpha) \\ y_1 = y_2 + w \cdot \cos(\alpha) \end{eqnarray} yang mengakibatkan \begin{eqnarray} x_2 = x_1 + w \cdot \sin (\alpha) \\ y_2 = y_1 - w \cdot \cos(\alpha) \end{eqnarray} Nah, rumusan ini berhasil saya terapkan dengan sempurna di JavaFX. Tapi entah kenapa ketika saya ganti ke VBA dari Microsoft Excel, semuanya kacau dan tidak sesuai harapan. Yang saya heran di Microsoft Excel, kok menghitung fungsi matematika yang berkaitan dengan trigonometri, dia menggunakan sudut radian. Ketika dia menentukan rotasi suatu objek, dia menggunakan sudut derajat. Mungkin saja ini penyebabnya atau satu dan lain hal, saya juga g tau.

Berikut ini adalah cuplikan video hasil implementasi dari rumus di atas di JavaFX:



Sementara source code untuk implementasi tersebut dapat anda lihat di github.

Adapun video dari keanehan Microsoft Excel yang dimaksud adalah:



di mana contoh implementasinya adalah
Sub TestAnimasi()
    total_iterasi = 0
    
    Dim shape As shape
    namaBenda = "Kotak"
    
    Set shape = Sheet1.shapes(namaBenda)
    Dim segitiga As shape
    Set segitiga = Sheet1.shapes("Bidang Miring")
    
    lokasiSegitigaX = segitiga.Left
    lokasiSegitigaY = segitiga.Top
    
    panjang = segitiga.Width
    lebar = segitiga.Height
    
    ' Hitung kemiringan bidang
    Dim sudutDerajat As Double
    sudut = Math.Atn(lebar / panjang)
    sudutDerajat = sudut / WorksheetFunction.Pi * 180
    shape.Rotation = sudutDerajat
    
    'Hitung default posisi
    defaultX = segitiga.Left + shape.Height * Sin(sudut)
    defaultY = segitiga.Top - shape.Height * Cos(sudut)
    
    'Letakkan kotak pada bagian awal dari bidang miring
    shape.Left = defaultX
    shape.Top = defaultY
    
    n = Sheet1.Cells(12, 13)
  
    Sheet1.Cells(22, 16) = sudutDerajat
    
    panjangLintasan = Math.Sqr(lebar * lebar + panjang * panjang)
    spasiLintasan = panjangLintasan / n
    lintasanAwal = 0
     Do
        DoEvents
        shape.Left = shape.Left + spasiLintasan * Cos(sudut)
        shape.Top = shape.Top + spasiLintasan * Sin(sudut)
        total_iterasi = total_iterasi + 1
        lintasanAwal = lintasanAwal + spasiLintasan
        timeout (0.2)
    Loop Until total_iterasi = n - 1
End Sub

Sub timeout(waktu As Double)
    StartTime = Timer
    Do
    DoEvents
    Loop Until (Timer - StartTime) >= waktu
End Sub