Simulasi Fluida dengan Pegas


Tertarik untuk belajar kembali simulasi fluida yang pernah menjadi tugas akhir penulis 10 tahun sebelumnya, untuk belajar konsep dasar, fluida dapat disimulasikan juga menggunakan asumsi pegas.

Hal ini berawal dari ketika penulis diminta dosen untuk memberi materi kepada mahasiswa baru mengenai simulasi fluida dengan metode Smoothed Particle Hydrodinamics (SPH).

Dengan mengasumsikan fluida sebagai partikel yang tekoneksi satu sama lain menggunakan pegas, menurut penulis adalah langkah terbaik belajar pemrograman fluida, sebelum melangkah ke SPH yang sebenarnya.

Berikut ini adalah contoh code Javascript HTML5 Canvas untuk simulasi fluida menggunakan pegas tersebut.

<html> 
<head> 
<title>Spring Fluid Simulation</title> 
</head> 
<body> 
<canvas id="myCanvas" width="800" height="500"></canvas> 
<script> 
var canvas=document.getElementById("myCanvas"); 
var ctx=canvas.getContext("2d"); 
 
class Ball 
{ 
 constructor(x,y) 
 { 
  this.x=x; 
  this.y=y; 
  this.vx=0; 
  this.vy=0; 
  this.ax=0; 
  this.ay=0; 
 } 
} 
 
var ball=[]; 
 
for(i=0;i<50;i++){ 
 ball[i]=new Ball(0.5*canvas.width-100+200*Math.random(),0.5*canvas.height-100+200*Math.random()); 
} 
 
var dt=0.1,kspring=0.25,delta=100,jeda=500; 
 
function W(r,h) 
{ 
 var hasil=0.0; 
 if(r<=h){ 
  r/=h; 
  hasil=(315.0/(64.0*Math.PI))*(1.0-r*r)*(1.0-r*r)*(1.0-r*r); 
 } 
 return hasil; 
} 
 
function Menggambar() 
{ 
 if(jeda>0)jeda--; 
 if(jeda==0 && ball.length<250){ 
  ball[ball.length]=new Ball(canvas.width-100,50); 
  ball[ball.length-1].vx=-30; 
  jeda=30; 
 } 
 
 ctx.fillStyle="blue"; 
 ctx.rect(0,0,canvas.width,canvas.height); 
 ctx.fill(); 

 for(i=0;i<ball.length;i++){ 
  //acceleration 
  ball[i].ax=0; 
  ball[i].ay=10;//gravity 
 } 

 //add spring force :) 
 for(i=0;i<ball.length;i++){ 
  for(j=i+1;j<ball.length;j++){ 
   var rx=ball[i].x-ball[j].x; 
   var ry=ball[i].y-ball[j].y; 
   var r=Math.sqrt(rx*rx+ry*ry); 
   if(r>0){ 
    var f=-kspring*(r-delta)*W(r,2*delta)/W(0,2*delta); 
    ball[i].ax+=f*rx/r; 
    ball[i].ay+=f*ry/r; 
    ball[j].ax-=f*rx/r; 
    ball[j].ay-=f*ry/r; 
   } 
  } 
 } 

 for(i=0;i<ball.length;i++){ 
  ball[i].vx+=ball[i].ax*dt; 
  ball[i].vy+=ball[i].ay*dt; 

  var u=0.1; 
  if(Math.abs(ball[i].vx)>u){ 
   ball[i].vx+=(ball[i].vx>0)?-u:u; 
  }else ball[i].vx=0; 
  if(Math.abs(ball[i].vy)>u){ 
   ball[i].vy+=(ball[i].vy>0)?-u:u; 
  }else ball[i].vy=0; 

  ball[i].x+=ball[i].vx*dt; 
  ball[i].y+=ball[i].vy*dt; 

  if(ball[i].y>canvas.height){ 
   ball[i].y=canvas.height; 
   ball[i].vy*=-1; 
  } 

  if(ball[i].x>canvas.width){ 
   ball[i].x=canvas.width; 
   ball[i].vx*=-1; 
  } 

  if(ball[i].x<0){ 
   ball[i].x=0; 
   ball[i].vx*=-1; 
  } 
 
  ctx.fillStyle="red"; 
  ctx.beginPath(); 
  ctx.arc(ball[i].x,ball[i].y,10,0,2*Math.PI); 
  ctx.fill(); 
  ctx.closePath(); 
 } 

 window.requestAnimationFrame(Menggambar); 
} 
 
Menggambar(); 
</script> 
</body> 
</html> 

Fungsi berat W, dipergunakan untuk memotong koneksi antar partikel yang jaraknya terlalu jauh. Sebab jika tetap mengikuti konsep pegas, jarak yang semakin jauh, justru akan semakin memperkuat gaya tarik-menariknya.

Dibawah ini adalah video bagaimana penulis membuat codenya:


Komentar



Postingan populer dari blog ini

Jasa Penjadwalan Semester, UTS dan UAS Perguruan Tinggi menggunakan Google Sheet

Apps Script untuk Cetak Sertifikat

Peringatan: Aksi Penipuan Skimming Melalui Aplikasi Android M-Pajak

Checking Data yang Belum Dimasukkan dalam Daftar Menggunakan Query Google Sheet

Kebodohan Karyawan Menyalahkan Sistem

Kumpulan Source Code Greenfoot

Menyembunyikan Failed Load Images di Blogger

Apps Script untuk Mengirimkan Notifikasi Approval

Ketika Pengelola Basis Data Terabaikan

Generate Karakter Acak dan Menempatkannya di Sel Google Sheets dengan Apps Script