Vi skal sjå litt på prinsippa bak simulering av mekaniske system, dvs. anvendelsar av Newtons lover++.
Begrepa animasjon og simulering er ikkje veldefinerte, men dette er eit forsøk på avgrensing. Wikipedia seier at ein animasjon er ein "illusjon av bevegelse som oppstår når en viser stillestående bilder fortløpende etter hverandre". Eksempel på dette er ein tegnefilm. Og som vi alle veit behøver ikkje ein tegnefilm å vera eingong i nærheten av verkeligheten! Simuleringar prøver derimot alltid å modellera verkeligheten i større eller mindre grad. Ein animasjon kan altså vera ein simulering, men veldig ofte er den ikkje det. På same måten kan ein simulering vera animert, men den behøver ikkje vera det. Noken gonger vil vi bare rekna ut verdiar (av td. fart og posisjon til ein satelitt) for å plotta dei i ein graf, eller analysera data vidare. Men andre gonger vil vi sjå korleis bevegelsen ser ut, og det er det vi skal sjå på her.
Animasjonar kan altså vera realistiske. Men i den grad dei prøver å vera det, så vil dei ofte heller imitera resultata eller effekten av dei fysiske lovene, enn å imitera lovene direkte. Eksempel: Hvis vi vil laga ein enkel animasjon for ein satelitt som går i sirkelbane rundt jorda, så treng vi bare skriva posisjonsvektoren som ein funksjon av t: r(t) = [(r cos(kt), rsin(kt)], og så oppdatera t. I dette tilfellet kjenner vi altså funksjonsuttrykket. Men vi kan også simulera bevegelsen ved å ta utgangspunkt i Newtons gravitasjonslov og Newtons andre lov, og rekna ut bevegelsen iterativt (steg for steg). Hvis vi i ein slik simulering startar satelitten med passande posisjon og fart, så vil den faktisk gå i ein sirkelbane. Men med andre startbetingelsar vil den gå i ein ellipsebane, eller i ein parabel- eller hyperbelbane. Så denne måten å simulera er meir generell. Vi treng ikkje endra anna enn startbetingelsane for at vi skal sjå alle mulige banar for eit system av to objekt, som her. Men den største fordelen er at vi på same måten kan simulera bevegelsen i situasjonar der funksjonsuttrykket ikkje er kjent. Det kan vera tilfeller der vi har meir komplisere uttrykk for kreftene som virkar (ofte med luftmotstand) eller det kan vera tilfeller med tre eller fleire objekt (som planeter) påvirkar kvarandre gjensidig. Dette er det såkalte trelegemeproblemet. Når funksjonsuttrykka ikkje er kjent, er dette den einaste måten å simulera på. Vi skal no sjå litt nærare på korleis strukturen til slik simulering. Så dette blir vårt rammeverk, som kan brukast for mange ulike situasjonar.
Initier verdiar. I simuleringar, som i all annan programmering, er
det lurt å starta med å definera alle konstantane som for
systemet, som feks. den universelle gravitasjonskonstanten osv. I tillegg
treng vi å gi startverdiar til alle variablane som inngår, som
tid, posisjon, fart mm. I dei aller fleste tilfelle vil også massane til
gjenstandane vera konstante.
NB: Rakettar er eit unntak, sidan dei kan mista betydelig masse i løpet av
kort tid.
Løkke: I verkelighetens verden beveger ting seg gjennom rommet kontinuerlig, og dei blir påvirka av krefter heile tida. Men i ein datamaskin har vi ikkje mulighet til å modellera kontinuerlig tid. Så vi deler derfor tida opp i korte intervall Δt, og så prøver vi å rekna ut aktuelle størrelsar som krefter, akselerasjon, fart og posisjon for kvart tidspunkt t0, t1, t2, osv.ved hjelp av ei løkke. Vi vil som regel då enten ta vare på verdiane for å plotta grafar, eller vi vil animera bevegelsen vha. Pygame eller andre verktøy. Inne i løkka må vi gjera følgande: (steg 1 til 5)
1) Rekn ut kreftene på kvart objekt: Det første vi gjer inne i
løkka er å rekna ut alle kreftene som
virkar på kvart objekt. Det er veldig ofte tyngdekrafta, men det kan i
tillegg vera luftmotstand og andre krefter. Deretter må vi summera x-, y-
og z-komponentane til alle kreftene kvar for seg, slik at vi finn vektorsummen
F = [Fx, Fy,Fz] på kvart objekt. Vi kan også bruka andre
typer koordinater, som kulekoordinater.
Hvis massen til objektet (typisk ein rakett) endrar seg, så må vi også her
rekna ut ny verdi, basert på kor mykje drivstoff den taper per sekund.
Hvis vi gjer 2D-simuleringar, vil vi bare bruka x og y. Dette gjer vi normalt inne i løkka. Unntaket er hvis summen av kreftene er konstant, som for eksempel i eit fritt fall. Då kan vi rekna ut vektor a ein gong for alle utanfor løkka. I fritt fall får vi az = g, mens ax og ay er null.
3) Finn fart og posisjon for kvart objekt. Så langt vil feilen i våre utrekningar vera eit resultat av usikkerheten i målingane og unøyaktighet i korleis vi modellerer kreftene. For eksempel er luftmotstand vanskelig å modellera med stor grad av nøyaktighet, mens gravitasjonskrafta kan modellerast mykje meir nøyaktig. Begrensingar i antall siffer som datamaskinen kan rekna med gir også opphav til feil. Men no introduserer vi ein feil som har med metoden vår å gjera. Den enklaste metoden, som også gir størst feil, er å tenkja som følger: Hvis vi reknar over korte nok tidsintervall Δt, kan vi setja momentanakselerasjonen lik gjennomsnittsakselerasjonen. Dette er altså ein tilnærming, men den vil ofte fungera bra. Vi har altså:a = Δv/Δt. Når vi set Δv = vn+1 - vn, multipliserer med Δt, og ordnar, så får vi at vn+1 = vn + a*Δt
På same måte set vi momentanfarten lik gjennomsnittsfarten: (nok ein tilnærming, altså)v = Δx/Δt. Når vi lar Δx = xn+1 - xn , og multipliserer med Δt og ordnar likninga så får vi: xn+1 = xn + vn+1*Δt
Merk at disse to formlane er på vektorform. Så kvar av dei har tre (eller to) komponentar. I koden kan det gjerne stå vx +=ax*dt, og deretter x += vx*dt. Og tilsvarande for y, og evt. z. Når vi gjer det på denne måten har vi bare tre verdiar vx, vy og vz for farten og tre verdiar x, y og z for posisjonen, som vi oppdaterer heile tida. Med andre ord: dei forrige verdiane går tapt. Så hvis vi vil ta vare på alle disse verdiane for plotting, så må vi lagra dei i ei array / liste.
Dette er den enklaste metoden å rekna ut fart og posisjon på, og kallast Eulermetoden. Det fins meir nøyaktige metodar, men for vårt formål er Eulermetoden bra nok. Kva er så ein "liten nok" Δt? Det kjem an på problemstillingen. For for noken applikasjonar vil det vera mindre enn eit sekund, mens for vår satelitt-simulering kan det vera over eit minutt. Med for stor Δt, vil vi sjå at banen blir langt frå ein sirkelbevegelse.
4) Detektering og behandling av kollisjonar. For kvar iterasjon kan vi ha behov for å sjekka om objekta våre har kollidert eller er i ferd med å kollidera. Då må vi ha kode som korrigerer fartsvektoren og posisjonsvektoren. Problemet er for det første at kollisjonar ofte skjer veldig fort, og for det andre at har vi gjerne ikkje ein god modell for kreftene i kollisjonen. Derfor vil vi ikkje i dette kurset simulera fysikken i ein kollisjon, men bare effekten. Hvis vi for eksempel modellerer ein ball som treff ein vertikal vegg, så kan vi modellera det som om kollisjonen skjer frå eit klokketikk til det neste. Så neste t snur vi x-komponenten til farten. Hvis bevegelsen skjer i x-retning, så held det då å skriva vx = -vx. I tillegg kan vi redusera farten for å simulera uelastiske kollisjonar. Då kan vi feks. skriva vx = -0.99*vx. For ein fullstendig elastisk kollisjon vil ballen bli hengande fast i veggen, slik at vx = 0. I ein satelitt-simulering vil ein kollisjon gjerne innebera at vi stoppar animasjonen, for det betyr jo at satelitten har styrta.
5) Tegn objekt påny. Når vi lagar ein animert simulering vil vi flytta dei, dvs tegna dei i den nye posisjonen, og dette må vi gjera for klart klokketikk. Hvis vi derimot bare skal plotta kurvane som ein graf, så må vi ta vare på alle posisjonane og plotta dette først når alle er rekna ut. NB: Hvis vi har ein spill-liknande animasjon der koordinatane til objekta er det same som pikselverdiane i vinduet, treng vi ikkje rekna om. Men i alle realistiske simuleringar må vi rekna om. For eksempel har vi funne at posisjonen til eit prosjektil er x = 15000 m og y =1200 m. For å plotta dette må vi ta hensyn til dimensjonane for vinduet og rekna om.
Som sagt over: noken gonger har vi fasit. Hvis vi feks. simulerer eit kast uten luftmotstand i 2D, så kjenner vi teoretisk uttrykka for x(t) og y(t). Dette er jo fritt fall, og vi kan bruka bevegelseslikningane for konstant akselerasjon. Då er det veldig nyttig å samanlikna fasiten med vår simulering. Og hvis vi simulerer eit verkelig kast, så har vi mulighet til å måla banane, for eksempel med eit høyhastighetskamera. Då blir målingane vår fasit. Og uansett må vi bruka alt det vi veit om systemet og fysikken bak for å vurdera resultatet. Vi veit at jo mindre luftmotstand, jo nærmare skal banen bli fritt fall-banen. Jo større luftmotstand, jo kortare blir kastet.
Så kan vi også sei noke kvalitativt om det som skjer. Vi veit for eksempel at når vi slepp noko frå stor høyde, så vil etter kvart luftmotstanden gjera at akslerasjonen stoppar opp, og farten blir konstant. (Sjå eit ufritt fall). Hvis vi simulerer ein sprettball, så veit vi også at farten vil minka etter kvart, og for kvart sprett vil den mista høyde. Hvis den derimot sprett høgare og høgare, veit vi at det noke feil! Det same veit vi med svingesystem som feks ein pendel: amplituden blir mindre og mindre, og til slutt stoppar dei opp. På same måten veit vi ein del om planetbanar: ei enkelt planet som går i bane rundt sola (og er uten påverknad frå andre objekt) vil gå i ein sirkel/ellipsebane, og denne vil ikkje forandra seg.
På den andre sida: hvis simuleringen vår har bestått alle testane våre, og vi har grunn til å tru at den virkar, så kan vi testa den på tilfeller der vi ikkje kjenner utfallet. Då blir simuleringane våre ein ny måte å gjera eksperiment på, som vi ellers ikkje kan utføra. Slik bruker forskarane for eksempel simuleringar for å finna ut korleis månen vår vart skapt. Vi seier ofte at naturvitskapen består av to deler: teori og forsøk. Simulering er ein tredje måte å forska på, som blir brukt meir og meir.