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
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; |
położenie - aby obliczyć, gdzie będzie znajdował się obiekt "za chwilę", należy do poprzedniego położenia dołożyć iloczyn prędkości i czasu
prędkość - aby wyliczyć zmianę szybkości związaną z opadaniem na powierzchnię ziemi, należy do początkowej prędkości dołożyć iloczyn przyspieszenia ziemskiego i czasu
opór powietrza - opór sprawia, że w każdej chwili zmniejsza się prędkość obiektu, wystarczy obliczone prędkości pomnożyć przez odpowiedni współczynnik
sprężyste odbicie - tylko jeden raz podczas odbicia, prędkość pionową mnożymy przez odpowiedni współczynnik, aby zasymulować tzw. tłumienie
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> |