Sabtu, 04 Juli 2015

Mendeteksi Posisi dengan Vektor Proyeksi

Good Morning Everyone, today is very beautiful day the sunshine very bright...udah cukup bahasa inggris-nya, ogut hanya bisa segitu aja ngak bisa ngelanjutin lagi ntar artinya ngaco  (sebenernya mau minta tolong rekan-rekan yang lancar bahasa inggris, tapi malu ngomongnya, ogut mau belajar).

Selamat Pagi rekan-rekan, teman-teman, kang mas kang mas, mbak mbak sekalian...kembali lagi ogut ngeblog nih karena ide ini harus di bagikan kepada Anda Anda sekalian. Kali ini ogut akan menjelaskan tentang mendeteksi posisi dengan menggunakan proyeksi vektor. Pada artikel sebelumnya proyeksi vektor pernah dibahas beserta contohnya sehingga tidak akan dibahas ulang dan kali ini ogut akan memberikan implementasi atau contoh program game-nya. Matematika vektor yes, narkoba no...(iklan dikit)


Program yang akan ogut bagikan akan tampak seperti gambar di bawah ini. Peluru yang ditembakkan oleh pesawat Fighter hanya aktif di dalam kotak hitam saja, setelah melewati kotak hitam peluru akan mati atau tidak aktif. Mengubah status peluru menjadi tidak aktif sangat bermanfaat karena peluru yang tidak aktif tidak perlu diproses translasi dan render, sehingga dapat menghemat pemakaian memory dan mempercepat laju program. Bagaimana cara mendeteksi posisi peluru yang ada di dalam kotak hitam dan yang berada di luar kotak hitam?


Teori Skala Proyeksi Vektor


Pada gambar di atas terlihat titik P yang berada di dalam sebuah persegipanjang ABCD, untuk membuktikan bahwa posisi titik P berada di dalam persegipanjang dapat digunakan tiga vektor bantu yaitu vektor a, vektor b dan vektor p.


Jika vektor p diproyeksikan ke vektor a maka skala proyeksi akan bernilai antara 0(nol) sampai 1.


Demikian pula jika vektor p diproyeksikan ke vektor b maka skala proyeksi akan bernilai antara 0(nol) sampai 1.


Penting!
Titik P berada di dalam persegipanjang ABCD jika skala proyeksi vektor p ke vektor a dan vektor b keduanya bernilai antara 0(nol) sampai 1(0 ≤ skala proyeksi ≤ 1).

Dengan menggunakan skala proyeksi vektor seperti contoh di atas maka sebuah titik koordinat dapat terdeteksi posisinya, teori inilah yang akan menjadi pedoman untuk diterapkan pada pemrograman game.
Ok selesai teorinya sekarang saatnya programming.

Tentukan nilai awal untuk Fighter dan peluru.

    Public Sub SettingNilaiAwal()
        'fighter
        Fighter.Ax = 420 : Fighter.Ay = 120
        Fighter.Bx = 580 : Fighter.By = 120
        Fighter.Cx = 580 : Fighter.Cy = 280
        Fighter.Dx = 420 : Fighter.Dy = 280

        Fighter.d_X = 25
        Fighter.d_Y = 25
        Fighter.Index_Tekstur = 1

        Indeks_Tekstur_Fighter = 1
        Delay_Tekstur_Fighter = 1
        Plus_Indeks_Tekstur_Fighter = True

        '=================================
        'cos 45 = 0.7071, sin 45 = 0.7071
        'buat 8 buah vektor fighter dengan
        'menggunakan aturan trigonometri
        '=================================
        'arah utara
        Vektor_Fighter(0).i = 0 : Vektor_Fighter(0).j = Fighter.d_Y
        'arah timur laut
        Vektor_Fighter(1).i = Fighter.d_X * 0.7071
        Vektor_Fighter(1).j = Fighter.d_Y * 0.7071
        'arah timur
        Vektor_Fighter(2).i = Fighter.d_X : Vektor_Fighter(2).j = 0
        'arah tenggara
        Vektor_Fighter(3).i = Fighter.d_X * 0.7071
        Vektor_Fighter(3).j = -Fighter.d_Y * 0.7071
        'arah selatan
        Vektor_Fighter(4).i = 0 : Vektor_Fighter(4).j = -Fighter.d_Y
        'arah barat daya
        Vektor_Fighter(5).i = -Fighter.d_X * 0.7071
        Vektor_Fighter(5).j = -Fighter.d_Y * 0.7071
        'arah barat
        Vektor_Fighter(6).i = -Fighter.d_X : Vektor_Fighter(6).j = 0
        'arah barat laut
        Vektor_Fighter(7).i = -Fighter.d_X * 0.7071
        Vektor_Fighter(7).j = Fighter.d_Y * 0.7071

        Dim i As Integer
        'Peluru Fighter
        For i = 0 To 98
            Peluru_Fighter(i).GO_Active = False
        Next

        Counter_Delay_Peluru = 99

        'area tembak
        Area_Tembak_Xmin = -500
        Area_Tembak_Xmax = 500
        Area_Tembak_Ymin = -300
        Area_Tembak_Ymax = 300

        'create vektorA
        VektorA.i = Area_Tembak_Xmax - Area_Tembak_Xmin
        VektorA.j = 0
        'create vektorB
        VektorB.i = 0
        VektorB.j = Area_Tembak_Ymax - Area_Tembak_Ymin

        LVektorA = Panjang_Vektor(VektorA)
        LVektorB = Panjang_Vektor(VektorB)

    End Sub

Tekan tombol 'F' untuk mengisi peluru (reload).

    Private Sub Tekan_Keyboard()
        ...
        ...          
        ...

        '===========================
        'tombol 'f' untuk rapid fire
        '===========================
        If (GetKeyState(Keys.F) And &H1000) Then
            If Counter_Delay_Peluru >= 6 Then
                Reload_Peluru()
                Sound1.Play()
                Counter_Delay_Peluru = 0
            Else
                Counter_Delay_Peluru = Counter_Delay_Peluru + 1
            End If

        End If
    End Sub

    Private Sub Reload_Peluru()
        Dim i, j As Integer

        For j = 1 To 3
            For i = 0 To 98
                If Peluru_Fighter(i).GO_Active = False Then
                    Peluru_Fighter(i).GO_Active = True
                    'isi koordinat peluru
                    Peluru_Fighter(i).Ax = Fighter.Ax - 20
                    Peluru_Fighter(i).Ay = ((Fighter.Dy - Fighter.Ay) / 2) + Fighter.Ay - 10
                    Peluru_Fighter(i).Bx = Peluru_Fighter(i).Ax + 20
                    Peluru_Fighter(i).By = Peluru_Fighter(i).Ay
                    Peluru_Fighter(i).Cx = Peluru_Fighter(i).Bx
                    Peluru_Fighter(i).Cy = Peluru_Fighter(i).By + 20
                    Peluru_Fighter(i).Dx = Peluru_Fighter(i).Ax
                    Peluru_Fighter(i).Dy = Peluru_Fighter(i).Cy
                    '================================
                    'setting vektor peluru
                    'cos 15 = 0.9659, sin 15 = 0.2588
                    '================================
                    If j = 1 Then
                        Peluru_Fighter(i).Vektor.i = -26.5629
                        Peluru_Fighter(i).Vektor.j = 7.1175
                    End If
                    If j = 2 Then
                        Peluru_Fighter(i).Vektor.i = -27.5
                        Peluru_Fighter(i).Vektor.j = 0.0#
                    End If
                    If j = 3 Then
                        Peluru_Fighter(i).Vektor.i = -26.5629
                        Peluru_Fighter(i).Vektor.j = -7.1175
                    End If

                    i = 99
                End If
            Next
        Next
    End Sub

Render / display peluru dan jika peluru berada di luar area ubah statusnya menjadi non aktif.

    Private Sub Render_Peluru()
        Dim i As Integer
        Dim SkalaPro1, SkalaPro2 As Single

        For i = 0 To 98
            If Peluru_Fighter(i).GO_Active Then

                '=====================================================
                'periksa apakah peluru di dalam area tembak atau tidak
                '=====================================================
                'hitung titik pusat peluru
                Titik_Pusat_Poligon(Peluru_Fighter(i), CenterX_Peluru, CenterY_Peluru)
                'create vektor peluru
                VektorPeluru = Create_Vektor(Area_Tembak_Xmin, Area_Tembak_Ymin, CenterX_Peluru, CenterY_Peluru)
                'hitung skala proyeksi
                SkalaPro1 = Dot_Product(VektorPeluru, VektorA) / (LVektorA * LVektorA)
                SkalaPro2 = Dot_Product(VektorPeluru, VektorB) / (LVektorB * LVektorB)

                If (SkalaPro1 >= 0 And SkalaPro1 <= 1 And SkalaPro2 >= 0 And SkalaPro2 <= 1) Then

                    '============================
                    'peluru berada di area tembak
                    '============================
                    GL.Enable(EnableCap.Blend)
                    GL.BlendFunc(BlendingFactorSrc.DstColor, BlendingFactorDest.Zero)

                    'Mask
                    GL.BindTexture(TextureTarget.Texture2D, Peluru_FBMP_Mask)
                    GL.Begin(BeginMode.Quads)
                    GL.TexCoord2(0.0, 0.0) : GL.Vertex2(Peluru_Fighter(i).Ax, Peluru_Fighter(i).Ay)
                    GL.TexCoord2(1.0, 0.0) : GL.Vertex2(Peluru_Fighter(i).Bx, Peluru_Fighter(i).By)
                    GL.TexCoord2(1.0, 1.0) : GL.Vertex2(Peluru_Fighter(i).Cx, Peluru_Fighter(i).Cy)
                    GL.TexCoord2(0.0, 1.0) : GL.Vertex2(Peluru_Fighter(i).Dx, Peluru_Fighter(i).Dy)
                    GL.End()

                    GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.One)
                    'BMP
                    GL.BindTexture(TextureTarget.Texture2D, Peluru_FBMP)
                    GL.Begin(BeginMode.Quads)
                    GL.TexCoord2(0.0, 0.0) : GL.Vertex2(Peluru_Fighter(i).Ax, Peluru_Fighter(i).Ay)
                    GL.TexCoord2(1.0, 0.0) : GL.Vertex2(Peluru_Fighter(i).Bx, Peluru_Fighter(i).By)
                    GL.TexCoord2(1.0, 1.0) : GL.Vertex2(Peluru_Fighter(i).Cx, Peluru_Fighter(i).Cy)
                    GL.TexCoord2(0.0, 1.0) : GL.Vertex2(Peluru_Fighter(i).Dx, Peluru_Fighter(i).Dy)
                    GL.End()

                    GL.Disable(EnableCap.Blend)

                    If CheckBox2.Checked = True Then
                        'warna merah untuk garis
                        GL.BindTexture(TextureTarget.Texture2D, Red)

                        GL.Begin(BeginMode.LineLoop)
                        GL.Vertex2(Peluru_Fighter(i).Ax, Peluru_Fighter(i).Ay)
                        GL.Vertex2(Peluru_Fighter(i).Bx, Peluru_Fighter(i).By)
                        GL.Vertex2(Peluru_Fighter(i).Cx, Peluru_Fighter(i).Cy)
                        GL.Vertex2(Peluru_Fighter(i).Dx, Peluru_Fighter(i).Dy)
                        GL.End()
                    End If

                    '=================================
                    'translasi peluru dengan vektornya
                    '=================================
                    Peluru_Fighter(i).Ax = Peluru_Fighter(i).Ax + Peluru_Fighter(i).Vektor.i
                    Peluru_Fighter(i).Bx = Peluru_Fighter(i).Bx + Peluru_Fighter(i).Vektor.i
                    Peluru_Fighter(i).Cx = Peluru_Fighter(i).Cx + Peluru_Fighter(i).Vektor.i
                    Peluru_Fighter(i).Dx = Peluru_Fighter(i).Dx + Peluru_Fighter(i).Vektor.i

                    Peluru_Fighter(i).Ay = Peluru_Fighter(i).Ay + Peluru_Fighter(i).Vektor.j
                    Peluru_Fighter(i).By = Peluru_Fighter(i).By + Peluru_Fighter(i).Vektor.j
                    Peluru_Fighter(i).Cy = Peluru_Fighter(i).Cy + Peluru_Fighter(i).Vektor.j
                    Peluru_Fighter(i).Dy = Peluru_Fighter(i).Dy + Peluru_Fighter(i).Vektor.j
                Else
                    'non aktifkan peluru yang tidak di dalam area tembak
                    Peluru_Fighter(i).GO_Active = False
                End If
            End If
        Next
    End Sub

Tuntas sudah penjelasan tentang mendeteksi posisi dengan menggunakan vektor proyeksi, bagaimana mantap  ya vektor bisa dipakai buat macam-macam, kadang bisa buat menghitung jarak, sudut antara dua objek dan lain-lain. Nanti pada artikel berikutnya ogut akan membahas tentang deteksi tabrakan dengan vektor, sabar ya, tunggu saja tanggal mainnya.

Salam matematika vektor rekan-rekan


Heriady
heriady.yoh@gmail.com




Tidak ada komentar:

Posting Komentar