mgr inż. Wacław Libront * Bobowa 2017-2019

ZSO Bobowa, ul. Długoszowskich 1, 38-350 Bobowa, tel: 0183514009, fax: 0183530221, email: sekretariat@zsobobowa.eu, www: zsobobowa.eu

Lekcja 8

Grawitacja w JS

  1. grawitacja
  2. odbijanie
  3. program
  4. interaktywność

Grawitacja
Jak zasymulować grawitację? Animacja nie jest problemem, a grawitacja w przypadku Ziemi i wszystkich znajdujących się na niej obiektów polega na tym, że, gdy je podrzucimy, to zaraz spadają, z coraz większą prędkością – z przyspieszeniem. Wszystkie zależności, które odpowiadają za poruszanie się obiektów można wyprowadzić z najprostszych fizycznych równań na prędkość i przyspieszenie. Po niewielkich przekształceniach można je zapisać w następujący sposób pokazany w ramce.

//równania ruchu
x = x + vx * dt;
y = y + vy * dt;
//szybkość
vy = vy + g * dt;
//opór powietrza
vx = vx * opor;
vy = vy * opor;
//sprężyste odbicia
vy = vy * spr;

Odbijanie sprężyste
Jeżeli piłka dociera do dolnego brzegu obszaru canvas powinna się odbić - zmieniamy jej współrzędną prędkości pionowej na przeciwną. Najprostszy warunek logiczny pokazuje poniższa ramka:

if (y > h) vy = -vy*spr;

Jednak dla niektórych promieni i prędkości piłka zachowuje się "dziwnie" całkowicie tłumiąc swoje odbicia. Okazuje się, że musimy jeszcze podczas zmiany kierunku uwzględniać promień piłki i samą prędkość. Poprawiony warunek logiczny:

if (y > h-r-vy*dt) vy = -(vy-g*dt)*spr;

Gotowy program
Gotowy program oparty jest na standardowym schemacie animacji opisanym w poprzednich lekcjach. Uruchom program kilka razy i sprawdź, jak zachowuje się piłka po zmianie parametrów ruchu: oporu i sprężystości.

<canvas width="200" height="600" id="can"></canvas>
<script>
  var c = can.getContext("2d");

  var w = c.canvas.width;
  var h = c.canvas.height;
  var skok = 10;
  var czas;

// kolorowa piłka
function pilka(x,y,r,kolor) {
  c.beginPath();
  c.strokeStyle=kolor;
  c.fillStyle=kolor;
  c.arc(x,y,r,0,2*Math.PI);
  c.stroke();
  c.fill();
};

// parametry animacji
var skok = 10;
var czas;
// parametry ruchu
var x=20;
var y=20;
var vx=10;
var vy=0;
var r=15;	
var kolor="red";
var g=9.81;     //grawitacja
var dt=0.1;     //skok czasu
var opor=0.999; //opór powietrza
var spr=0.8;   //sprężystość
// rekurencyjna animacja
function grawitacja() {
  c.clearRect(0, 0, w, h);
  c.strokeStyle="black";
  c.strokeRect(0, 0, w, h);
  pilka(x,y,r,kolor);
  x=x+vx*dt;
  y=y+vy*dt;
  vy=vy+g*dt;
  vx=vx*opor;
  vy=vy*opor;
  if (y>h-r-vy*dt){vy=-(vy-g*dt)*spr}
  clearTimeout(czas);
  czas = setTimeout(grawitacja, skok); 
}
grawitacja();
</script>

Interaktywność
Wciskać za każdym razem F5, aby odświeżyć stronę i zobaczyć piłkę od nowa, to nie jest dobre rozwiązanie. Prawdziwy program reaguje na myszkę i klawiaturę. W JS odpowiadają za te operacje  zdarzenia. Połączymy możliwości, jakie daje HTML przyciski, suwaki, itp) i podłączymy pod nie funkcje JS.

 


Przycisk START
Najpierw zdefiniujemy w HTML przycisk i przypiszemy do zdarzenia onclick funkcję OdNowa, która zwiera dane początkowe i uruchomienie animacji. Znaczniki przycisku wstawiamy w obszar HTML strony, a funkcję do obszaru JS, pomiędzy znaczniki <script>. Po naciśnięciu przycisku START animacja jest uruchamiana od nowa.

//przycisk wstawiamy do obszaru HTML - pomiędzy znaczniki <body>
<input type="button" value="START" onclick= OdNowa()>
<br>

//funkcję wstawiamy do obszaru JS - pomiędzy znaczniki <script>
function OdNowa(){
  x=20; 
  y=20;
  vx=10;  
  vy=0;
  czas=setTimeout(grawitacja,skok);
}

Rysowanie – wymazywanie
Pole checkbox posłuży nam do ustawiania wymazywania ekranu podczas animacji. Wymazywanie ekranu będzie teraz zależało od stanu pola checkbox o nazwie rys0. Jeśli pole będzie odznaczone, to ekran nie będzie wymazywany i zobaczymy kolejne położenia piłki.

//pole wstawiamy do obszaru HTML - pomiędzy znaczniki <body>
//najlepiej pod przycisk START, przed znacznik <br>
czyść ekran <input id="rys0" type="checkbox">


//samą instrukcję warunkową dopisujemy do czyszczenia obszaru canvas
if (rys0.checked)
    c.clearRect(0, 0, w, h);

Suwak oporu powietrza
Za pomocą suwaka RopS określamy opór powietrza, opór wpisujemy po każdej zmianie – zdarzenie onchange do pola tekstowego RopT. Funkcja OporPow oblicza na nowo parametr i wpisuje go do pola tekstowego. Suwak zmienia swoje wartości pomiędzy 990 a 1000, które dzielimy przez 1000 i wstawiamy jako parametr sprężystości 0.99 do 1.00

//znaczniki wstawiamy do obszaru HTML - pomiędzy znaczniki <body>
//najlepiej pod przycisk START, przed znacznik <br>
opór powietrza
<input type="range" id="RopS" min=990 max=1000 onchange=OporPow()>
<input type="text" id="RopT" size=2>

//funkcję wstawiamy do obszaru JS - pomiędzy znaczniki <script>
function OporPow(){
  opor=RopS.value/1000;
  RopT.value=opor;
}

Szablon

<canvas width="400" height="400" id="can"></canvas>
<script>
  var c = can.getContext("2d");



</script>