Simulasi gerak peluru menggunakan matplotlib

Kali ini alza akan menyajikan cara membuat simulasi gerak peluru pada berbagai sudut lontar menggunakan matplotlib.

Gerak peluru (projectile motion) dalam ilmu fisika didefinisikan sebagai gerak sebuah benda/proyektil yang dilontarkan di atas permukaan bumi, dan membentuk lintasan berupa lengkungan akibat pengaruh gravitasi bumi.

Karena adanya sudut lontar/tembak, proyektil memiliki komponen pergerakan vertikal dan horizontal sekaligus. Pergerakan vertikal terpengaruh gravitasi bumi sehingga gerak mengalami perlambatan sebesar gravitasi bumi, yang mengakibatkan proyektil berhenti pada ketinggian tertentu kemudian jatuh ke tanah. Pergerakan horizontal memiliki kecepatan tetap (constant), dan berhenti saat proyektil menyentuh tanah akibat pergerakan vertikal.

Rumus yang digunakan

Artikel ini lebih menitikberatkan pada kode program yang digunakan daripada konsep fisikanya, oleh karena itu rumus yang digunakan diperlihatkan langsung dalam bentuk tiga fungsi pada kode berikut ini.

  1. Rumus untuk menghitung jarak tempuh horizontal (horiz_dist) setelah t detik berdasarkan kecepatan awal v0, dan sudut tembak deg derajat.
  2. Rumus untuk menghitung ketinggian proyektil (vert_dist) setelah t detik berdasarkan kecepatan awal v0, dan sudut tembak deg derajat.
  3. Rumus untuk menghitung lama waktu sebuah proyektil berada diudara (sejak ditembakkan hingga jatuh menyentuh tanah), dengan kecepatan awal v0, dan sudut tembak deg derajat.
  4. Konstanta gravitasi diasumsikan 9.8 meter per detik kuadrat.
GRVTY = 9.8 # gravity constant at 9.8 ms-2

# calculate horizontal distance travelled after t seconds, with initial velocity v0, and deg shoot angle
def horiz_dist(v0,t,deg):
    tmax = ground_t(v0,deg)
    rad = np.radians(deg) 
    v_horiz = v0 * np.cos(rad)
    if t <= tmax:        
        dist = v_horiz * t
    else:
        dist = v_horiz * tmax
    return dist

# calculate vertical distance to earth after t seconds, with initial velocity v0, and deg shoot angle
def vert_dist(v0,t,deg):
    rad = np.radians(deg) 
    v_vert = v0 * np.sin(rad)
    h = v_vert * t - (0.5 * GRVTY * t * t)
    if h >= 0:  
        return h
    else:
        return 0

# calculate projectile airtime
def ground_t(v0,deg):
    rad = np.radians(deg) 
    v_vert = v0 * np.sin(rad)
    t = 2 * v_vert / GRVTY
    return t

Menyiapkan data untuk simulasi

Data untuk simulasi disiapkan sebagai berikut:

  1. Kecepatan awal sebesar 25 meter per detik
  2. Sudut tembakal/lontaran pada 30, 45, dan 60 derajat
  3. Posisi benda/proyektil, ketinggian dan jarak tempuh horizontal, dicatat untuk tiap 0.1 detik

Kode program untuk menghasilkan data posisi tiap proyektil dengan tiga sudut tembakan berbeda tiap-tiap 0.1 detik hingga tiap proyektil menyentuh tanah dapat dilihat berikut ini.

v0 = 25
degs = [30,45,60]
t_grounds = [ground_t(v0,d) for d in degs] # calculate airtime for all angles
t_ground = max(t_grounds)

time_interval = 0.1 # distance between each point in time used for calculation in seconds
t_steps = np.arange(0,t_ground+time_interval,time_interval) # produce list of calculation times based on time_interval
# create list of horizontal position in each given time for each angle
hls = [[horiz_dist(v0,t,d) for t in t_steps] for d in degs] 

# create list of vertical position in each given time for each angle
vls = [[vert_dist(v0,t,d) for t in t_steps] for d in degs] 

h_max = max([ max(l) for l in hls]) # find maximum horizontal distance
h_max = np.ceil(h_max)
v_max = max([ max(l) for l in vls]) # find maximum vertical distance
v_max = np.ceil(v_max)

Membuat animasi

Berdasarkan data yang ada kemudian dibuat animasi yang menampilkan ketiga proyektil yang ditembakkan dengan kecepatan awal sama namun sudut tembakan berbeda dengan menggunakan kode di bawah ini.

fig, ax = plt.subplots()

plt.gca().set_aspect("equal") # equal scale on x axis and y axis 
plt.xlabel('Jarak tempuh horizontal (m)') # title for x axis
plt.ylabel('Ketinggian (m)') # title for y axis
plt.grid(True, which='both') # display grid for better view
   
lines = [ax.plot([],[],label='{} derajat'.format(d))[0] for d in degs] # create plot for each angle
ax.axis([0,h_max,0,v_max]) # set plot axis range
ax.legend()

def update(num,lines):
    for i in range(len(lines)):
        l = lines[i]
        l.set_data(hls[i][:num], vls[i][:num])
    tm = np.round(num * time_interval,1)
    plt.title('Kecepatan awal: {} m/s | Waktu simulasi: {} detik'.format(v0,tm))
    return lines

ani = animation.FuncAnimation(fig, update, frames=len(t_steps),fargs=[lines],interval=1000*time_interval)

ani.save('gifs/projectile-multi.gif', writer='imagemagick', fps=1/time_interval)

Kode lengkap dan hasilnya

Kode lengkap untuk simulasi ini dapat diakses di github pada alamat ini, kode disajikan dalam format .ipynb untuk jupyter notebook. Hasil simulasi dapat dilihat pada awal artikel ini.

Semoga bermanfaat,

Salam.

You may also like...

5 Responses

  1. Umar says:

    ka mau tanya, frames di line 20 gimana cara supaya berhenti di waktu pada saat pelurunya udh sampai ke tanah ya?. maksudnya supaya animasi simulasinya kalo udh sampe tanah dia berhenti ngak ngulang-ngulang. terimakasih kak

    • Alza says:

      Oh. Itu sebenarnya berhenti saat proyektil mencapai tanah. Animasi berulang lebih karena format gambarnya yg berekstensi .gif dan secara default selalu diloop oleh browser.
      Btw output jg bisa diset ke dalam bentuk video, misalnya .mp4.

  2. Fitriyadi says:

    Traceback (most recent call last):
    File “C:/Users/HP/PROJECT_ACTIVE/GERAK PROYEKTIL COPAS.py”, line 76, in
    ani.save(‘gifs/projectile-multi.gif’, writer= ‘fitriyadi’, fps=1 / time_interval)
    File “C:\Users\HP\AppData\Local\Programs\Python\Python38\lib\site-packages\matplotlib\animation.py”, line 1102, in save
    alt_writer = next(writers, None)
    TypeError: ‘MovieWriterRegistry’ object is not an iterator

    Process finished with exit code 1

    saat saya run tulisannya seperti ini, ini kenapa ya kak ?

    • Alza says:

      Maaf baru lihat, argumen writer diisi dengan plugin yg digunakan untuk membuat animasi. Kebetulan di contoh menggunakan imagemagick.

  3. Panduan Blog says:

    Terima kasih banyak atas pembahasannya

Berikan komentar