If you're seeing this message, it means we're having trouble loading external resources on our website.

Ha webszűrőt használsz, győződj meg róla, hogy a *.kastatic.org és a *.kasandbox.org nincsenek blokkolva.

Fő tartalom

Newton mozgástörvényei

Az előző rész utolsó példájában láttuk, hogyan kell kiszámítani a dinamikus gyorsulást a rajzvásznon levő kör helyzetéből az egér helyzetébe mutató vektor alapján. Az eredményül kapott mozgás olyan volt, mintha mágneses vonzás lenne a kör és az egér között, mintha valami erő a kört az egér felé húzná.
Ebben a részben elmélyítjük az erő fogalmával kapcsolatos tudásunkat és annak viszonyát a gyorsulással. Célunk az, hogy a fejezet végére megértsd, hogyan mozgathatsz tárgyakat a rajzvásznon úgy, hogy azok mozgása reagáljon a környezetében fellépő erőkre.
Mielőtt elkezdenénk megvizsgálni az erő programmal való szimulációjának gyakorlati vonatkozásait, elméleti síkon nézzük meg, mit jelent az erő a valóságban. A „vektor”-hoz hasonlóan az „erő” is különböző dolgokat jelenthet. Utalhat hatalmas intenzitásra, mint például „Nagy erővel tolta a sziklatömböt” vagy „Erősen érvelt”. Az erő minket érdeklő definíciója ennél tudományosabb, és a testek mozgását leíró, Isaac Newtontól származó törvényeken alapul:
Az erő vektor, mely tömeggel rendelkező testet gyorsulásra késztet.
A jó hír az, hogy a definíció első részét értjük:  az erő vektor. Szerencsénkre egy egész fejezetet szántunk arra, hogy megtanuljuk, mi a vektor és hogyan programozzunk PVectorokkal!
Vizsgáljuk meg Newton három mozgástörvényét az erő szempontjából!

Newton első törvénye

Newton első törvényét így fogalmazhatjuk meg egyszerűen:
A nyugalmi állapotban levő test megtartja nyugalmi állapotát és a mozgásban levő test mozgásban marad.
Ebből a definícióból azonban hiányzik egy fontos, az erőre vonatkozó kitétel. Az alábbi módon egészíthetnénk ki:
Minden test megtartja nyugalmi állapotát vagy egyenes vonalú egyenletes mozgását mindaddig, amíg egy másik erő nem kényszeríti mozgásállapotának megváltoztatására.
Amikor Newton megjelent a színen, a mozgásról alkotott általánosan elfogadott elképzelés – amit Arisztotelész fogalmazott meg – már közel kétezer éves volt. Ez azt mondta ki, hogy ha egy test mozog, valamilyen erő kell ahhoz, hogy mozgásban tartsa. Ha azt a mozgó dolgot nem tolják vagy húzzák, akkor az le fog lassulni, majd megáll. Igaz?
Ez persze így nem igaz. Ha nincs jelen semmilyen erő, akkor a test mozgásban tartásához sincs szükség erőre. Egy test (mint például egy labda), amit a Föld atmoszférájában elengedünk, a légellenállás miatt egy idő után nem fog tovább gyorsulni. Egy test sebessége csak akkor marad állandó, ha semmilyen erő nem hat rá, vagy ha a rá ható erők kioltják egymást, más szóval, ha az erők eredője nulla. Ezt gyakran erőegyensúlynak is nevezik. Egy szabadon eső labda idővel eléri a végsebességét (mely ezután konstans marad), amint a légellenállás és a gravitációs erő nagysága megegyezik..
Ábra: két ember fúj egy ingát
Az inga nem mozdul, mert az erők kiegyenlítik egymást (összeadódva a nettó erő értéke nulla)
A ProcessingJS világában így fogalmazhatjuk át Newton első törvényét:
Egy objektum PVector sebessége konstans marad, ha egyensúlyi helyzetben van.
Most hagyjuk ki a második törvényt (valószínűleg a mi számunkra az lesz a legfontosabb), előbb nézzük meg a harmadik törvényt:

Newton harmadik törvénye

Ezt a törvényt így szokták megfogalmazni:
Minden hatásra egy egyenlő nagyságú és ellentétes irányú ellenhatás keletkezik.
Ez a törvény a megfogalmazása miatt gyakran zavart okoz. Például azért, mert olybá tűnik, mintha az egyik erő hozná létre a másikat. Igaz, ha te valakit meglöksz, az dönthet úgy, hogy visszalök téged. De ez nem az a hatás-ellenhatás, amiről Newton harmadik törvénye szól.
Tegyük fel, hogy nekitámaszkodsz egy falnak. A fal nem dönt úgy, hogy téged visszanyom. Nincs „kiinduló” erő. A te támaszkodásod magába foglalja mindkét erőt, amit „hatás/ellenhatás párnak” nevezünk.
A törvény jobb megfogalmazása ez lehet:
Az erők mindig párosával lépnek fel. A két erő egyező nagyságú, de ellentétes irányú.
Most ez még mindig zavarkeltő, mert úgy hangzik, mintha ezek az erők mindig kioltanák egymást. Nem ez a helyzet. Ne feledd, ezek az erők nem ugyanazokra a testekre hatnak! Abból, mert a két erő egyenlő, nem következik, hogy a mozgás is egyenlő (vagy hogy a testek nem mozognak tovább).
Próbálj eltolni egy álló teherautót! Habár a teherautó nálad sokkal erősebb, egy álló teherautó – egy mozgásban lévővel ellentételesen – nem fog leütni a lábadról és hátrarepíteni. Az az erő, amit kifejtesz, egyenlő és ellentétes azzal, amit a teherautó a kezedre kifejt. A végeredmény egy csomó más tényezőtől függ. Ha a teherautó kicsi és egy jeges lejtőn áll, valószínűleg meg tudod mozdítani. Egy nagy, földúton álló teherautót viszont ha erősen tolod (talán még nekifutásból is), akár meg is sérülhet a kezed.
Mi történik akkor, ha görkorcsolya van a lábadon, amikor megtolod a teherautót?
Teherautót toló férfi görkorcsolyával a lábán
Fogalmazzuk meg Newton harmadik törvényét a ProcessingJS világában:
Amikor az A objektum B objektumra gyakorolt f erejéhez tartozó PVector-t számoljuk, akkor alkalmazni kell a B objektum által az A objektumra kifejtett PVector.mult(f,-1) erőt is.
Látni fogjuk, hogy a ProcessingJS programozás világában nem mindig kell magunkat a fentiekhez tartani. Néha – például a testek közötti gravitációs vonzás esetében – modellezni akarjuk az egyenlő, egymással ellentétes erőt. Máskor, például amikor azt mondjuk, „A környezetben most legyen szél!”, nem fogjuk venni a fáradtságot, hogy a test széllel szembeni ellenhatását is modellezzük. Sőt, a levegőt egyáltalán nem fogjuk modellezni! Ne feledd, a természetes világ fizikájából csak ihletet merítünk, nem akarunk teljes precizitással mindent szimulálni!

Newton második törvénye

Megérkeztünk a ProcessingJS programozó legfontosabb törvényéhez. (A továbbiakban használt jelölések, és az eredetük: f,F: erő (force); m,M: tömeg (mass); a,A: gyorsulás (acceleration); w,W: súly (weight); g,G: gravitáció)
Ezt a szabályt hagyományosan így szokták megfogalmazni:
Erő egyenlő tömegszer gyorsulás.
Másképpen:
F=MA
Miért ez a számunkra legfontosabb törvény? Írjuk fel másképpen:
A=F/M
A gyorsulás egyenesen arányos az erővel és fordítottan arányos a tömeggel. Ez azt jelenti, hogyha meglöknek, minél erősebb a lökés, annál gyorsabban fogsz mozogni (gyorsulni). Minél nagyobb vagy, annál lassabban fogsz mozogni.
A súly és a tömeg
Egy test tömege a testet alkotó anyag mennyisége (kilóban mérve).
A súly – bár gyakran összekeverik a tömeggel – a Föld testre ható gravitációs erejét jelenti a gyakorlatban. Newton második törvényéből következően úgy számoljuk ki, hogy a tömeget megszorozzuk a gravitáció gyorsulási értékével (w = m · g). A súlyt newtonban mérjük.
A sűrűség definíciója: a tömeg mennyisége térfogategységenként (például gramm per köbcentiméter).
Ebből következik, hogy egy test, aminek a tömege a Földön egy kiló, annak a holdon is egy kiló a tömege, viszont a súlya csak az egyhatoda lesz.
A ProcessingJS világában vajon mi a tömeg? Hát itt nem pixellel dolgozunk? Kezdjük egy kis egyszerűsítéssel, mondjuk azt, hogy a mi feltételezett pixel világunkban minden pixel tömege 1. F/1 = F. Ezért:
A=F
Egy test gyorsulása egyenlő az erővel. Ez remek hír. Hiszen láttuk a vektorokról szóló fejezetben, hogy a rajzvásznon az objektumok mozgásának vezérléséhez a gyorsulás a kulcs. A helyzetet a sebesség változtatja, a sebességet pedig a gyorsulás. Minden a gyorsulással kezdődött. Most arra jöttünk rá, hogy az erő az, ami mindent vezérel!
A most tanultakat használjuk fel ahhoz, hogy továbbépítsük a Mover objektumunkat, aminek pillanatnyilag van helyzete, sebessége és gyorsulása. Most az a célunk, hogy az objektumunkhoz hozzáadjuk az erőhatásokat például valahogy így:
mover.applyForce(wind);
vagy:
mover.applyForce(gravity);
ahol a szél (wind) és a gravitáció (gravity) PVectorok. Newton második törvénye alapján ezt a függvényt így implementáljuk:
Mover.prototype.applyForce = function(force) {
    this.acceleration = force;
};

Az erők összeadása

Ez jónak tűnik. Végül is a gyorsulás = erő Newton második törvényének leképezése (a tömeget figyelmen kívül hagyva). Viszont van egy nagy gond. Térjünk vissza arra, hogy mit akarunk elérni: olyan mozgó tárgyat akarunk készíteni, ami reagál a szélre és a gravitációra.
mover.applyForce(wind);
mover.applyForce(gravity);
mover.update();
mover.display();
Gondolkodjunk a számítógép fejével egy kicsit. Először meghívjuk az applyForce() metódust a szél miatt, ennek hatására a Mover objektum gyorsulásához hozzárendeljük a szél PVector-át. Ezután meghívjuk az applyForce() metódust a gravitáció miatt. Most a Mover objektum gyorsulását beállítjuk a gravitáció PVector értékére. Majd meghívjuk az update() metódust. Mi történik az update()ben? A gyorsulást hozzáadjuk a sebességhez.
velocity.add(acceleration);
Nem látunk hibaüzenetet, de a mindenit! Valami nagyon nem jó. Mi a gyorsulás értéke, amikor hozzáadjuk a sebességhez? A gravitációs erő. A szél kimaradt. Ha az applyForce() metódust többször hívjuk, az előző mindig felülíródik. Hogyan kell kezelni a többszörös erőt?
Az az igazság, hogy mi itt newton második törvényének egy egyszerűsített változatával kezdtünk. A pontosított megfogalmazás így szól:
Az erők eredője egyenlő tömegszer gyorsulás.
Más szóval a gyorsulás egyenlő az összes erő összege osztva a tömeggel. Ez már jónak tűnik. Végül is láthattuk Newton első törvényében, hogyha az összes erő összege nulla, akkor a test egyensúlyi állapotba kerül (azaz nem lesz gyorsulás). Ezt az erők összeadásának nevezett eljáráson keresztül valósítjuk meg. Tulajdonképpen ez egy nagyon egyszerű eljárás, annyit kell csak tennünk, hogy összeadjuk az összes erőt. Bármely adott pillanatban lehet 1, 2, 6, 12 vagy akár 313 erőhatás is! Mindaddig, amíg az objektumaink össze tudják gyűjteni az erőket, nem számít, hányan vannak.
Módosítsuk az applyForce() metódust úgy, hogy az erőket egyenként hozzáadjuk a gyorsuláshoz:
Mover.prototype.applyForce = function(force) {
    this.acceleration.add(force);
};
Most még nem végeztünk teljesen. Az erők összeadásához még tartozik valami. Mivel minden pillanatban összeadjuk az erőket, nem szabad elfelejtkezni arról, hogy a gyorsulást visszaállítsuk alaphelyzetbe (lenullázzuk) minden alkalommal, amikor meghívjuk az update() metódust. Vegyük például a szelet. Néha a szél nagyon erős, néha gyenge, néha meg egyáltalán nem fúj. Bármely pillanatban jöhet egy hatalmas széllökés, például amikor a felhasználó lenyomva tartja az egérgombot:
if (mouseIsPressed) {
  var wind = new PVector(0.5, 0);
  mover.applyForce(wind);
}
Amikor a felhasználó elengedi az egérgombot, a szél eláll, és Newton első törvénye alapján a tárgy egyenletes sebességgel halad tovább. Ha azonban elfelejtettük volna a gyorsulást visszaállítani nullára, akkor a széllökés még mindig hatna. Ami még ennél is rosszabb, tovább halmozódna az előző képkockáról, mivel az erőket összeadjuk!
Szimulációnkban a gyorsulásnak nincs emlékezete: egyszerűen mindig kiszámítja a program az adott időpillanatban a környezetben fellépő erők alapján. Ez különbözik mondjuk a helyzettől, aminek mindig emlékeznie kell arra, hogy az előző képkockában a tárgy hol volt ahhoz, hogy a következő képkockában megfelelően tudjuk mozgatni.
A gyorsulás alaphelyzetbe állításának legegyszerűbb módja az, ha minden képkockánál megszorozzuk a PVectort nullával az update() végén.
Mover.prototype.update = function() {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity);
    this.acceleration.mult(0);
};

A tömeg figyelembevétele

Oké. Még egy dolgot kell hozzáadnunk a modellhez, mielőtt elkészülnénk az erőknek a Mover objektumba való beépítésével. Utána megnézünk egy példát. Végül is Newton második törvénye igazándiból F=MA, nem A=F. A tömeg figyelembevételéhez nem kell mást tennünk, mint hozzáadni egy tömeg tulajdonságot az objektumunkhoz, de el kell ezzel töltenünk egy kis időt, mert adódnak még komplikációk.
Mértékegységek
Most, hogy be akarjuk vezetni a tömeget, itt az ideje, hogy foglalkozzunk egy kicsit a mértékegységekkel. A valós világban a dolgokat meghatározott mértékegységekkel mérjük. Azt mondjuk, hogy két tárgy 3 méterre van egymástól, a focilabda 90 km/óra sebességgel repül, vagy a tekegolyó súlya 6 kilogramm. Ahogy a kurzus során a későbbiekben látni fogjuk, néha figyelembe fogjuk venni a valós világ mértékegységeit. Ebben a részben azonban többnyire figyelmen kívül hagyjuk őket.
Itt a mértékegységünk a pixel („Ez a két kör 100 pixelnyire van egymástól”), animációs időablak („Ez a kör képkockánként 2 pixelnyit halad”). A tömeg esetében nincs használható mértékegységünk. Egyszerűen tetszőleges számokat fogunk használni. Ebben a példában hasraütésre a 10-et fogjuk használni. Nincs mértékegység, bár kitalálhatsz magadnak egyet, mondjuk „1 moog” vagy „1 yurkle.”
A példa kedvéért a tárgy tömegét a tárgy méretéhez fogjuk kötni – így, ha a tárgy tömege 10, akkor egy 10 átmérőjű kört rajzolunk. Ezáltal könnyű megjeleníteni a tárgyak tömegét és könnyebb lesz a programjainkban megérteni a tömeg hatását. De a valós világban a méret persze nem határozza meg a tömeget. Egy kis fémlabda tömege jóval nagyobb lehet egy nagy léggömbnél a nagyobb sűrűsége miatt.
A tömeg skaláris lebegőpontos változó (float), nem vektor, mivel az csak egy szám, ami leírja a tárgyat alkotó anyag mennyiségét. Bonyolíthatnánk a dolgot, és kiszámíthatnánk az alakzat területét a tömeg meghatározásához, de egyszerűbb simán azt mondani: „Legyen a tárgy tömege... izé, mit tudom én, mit szóltok a 10-hez?”
var Mover = function() {
    this.mass = 10;
    this.position = new PVector(random(width), random(height));
    this.velocity = new PVector(0, 0);
    this.acceleration = new PVector(0, 0);
};
Ez itt most azért nem igazán jó, mert a dolgok akkor válnak érdekessé, ha különböző tömegű tárgyaink vannak, de indulásnak ez is jó lesz. Hogyan kerül a képbe a tömeg? Hát Newton második törvényének alkalmazásával!
Mover.prototype.applyForce = function(force) {
  force.div(this.mass);
  this.acceleration.add(force);
};
Bár a program megfelelőnek tűnik, megint egy nagyobbacska problémával találjuk szembe magunkat. Tegyük fel, hogy két Mover objektumunk van, amiket a szél sodor.
var m1 = new Mover();
var m2 = new Mover();

var wind = new PVector(1, 0);

m1.applyForce(wind);
m2.applyForce(wind);
Megint helyezzük magunkat a számítógép helyébe. m1.applyForce() megkapja az (1;0) erejű szelet, elosztja a tömegével (10), és hozzáadja a gyorsuláshoz.
kódwind (szél)
var wind = new PVector(1, 0);(1, 0)
m1.applyForce(wind)(0.1, 0)
Rendben. Folytatjuk az m2-vel. Ez is megkapja a szélerőt — (1;0). Várjunk csak... Mi a szélerő értéke? Ha jobban megnézed, a szélerő mostanra (0,1;0) lett.
Emlékszel még arra az apróságra az objektumokkal kapcsolatban? Javascriptben egy objektumot jelölő változó (mint ami például a PVector) valójában egy pointer, ami az objektumot tartalmazó memóriaterületre mutat. Amikor az objektumot átadod egy függvénynek, akkor nem az objektum egy másolatát adod át, hanem az eredeti pointert. Ebből következik, hogy ha a függvény megváltoztatja az objektumot, akkor az eredeti objektum véglegesen megváltozik (mint itt is, amikor elosztjuk a tömeggel).
Ezért csúsztak itt félre a dolgok! Nem szeretnénk, hogy m2 az m1 tömegével elosztott erőt kapja meg. Az eredeti állapotban levő erőt szeretné megkapni — (1;0)-t. Ennek a kivédésére csináljunk egy másolatot a PVector f változóról, mielőtt elosztjuk a tömeggel.
Szerencsére a PVector objektumnak van egy megfelelő metódusa a másolatkészítésre – a get(). A get() egy új PVector objektumot ad vissza ugyanazzal az értékkel. Ennek alapján írjuk át az applyForce() metódust:
Mover.prototype.applyForce = function(force) {
    var f = force.get();
    f.div(this.mass);
    this.acceleration.add(f);
};
Egy másik módszer arra, hogy a metódust a div() statikus változatával írjuk át annak alapján, amit az előző részben tanultunk:
Mover.prototype.applyForce = function(force) {
  var f = PVector.div(force, this.mass);
  this.acceleration.add(f);
};
Az a fontos, hogy megtaláljuk annak a módját, hogy ne változtassuk meg az eredeti force vektort, így több Mover objektum is használhatja azt.

Erő létrehozása

Tudjuk, hogy mi az erő (egy vektor) és tudjuk, hogyan hat az erő egy testre (oszd el a tömeggel, és add hozzá a test gyorsulásvektorához). Mi hiányzik még? Először rá kell jönni, hogy hogyan kapjuk meg az erőt. Honnan származnak az erők?
Ebben a fejezetben két módszert használunk ProcessingJS erő létrehozására:
  • Készíts erőt! Végül is te vagy a programozó, a világod megteremtője. Senki nem tiltja meg neked, hogy készíts egy erőt és azt használd.
  • Modellezd az erőt! Persze, léteznek erők a valóságban, és a fizikakönyvek képleteket is társítanak az erőkhöz. Vehetjük akár ezeket a képleteket, és programkóddá fordíthatjuk le őket, valódi erő modelljét készítve el a ProcessingJS eszköztárával.
Erőt legegyszerűbben úgy készíthetünk, ha egyszerűen kiválasztunk egy számot. Kezdjük a szél szimulációjával. Mit szólnál egy jobbra fújó, gyengécske szélhez? Feltételezve egy m Mover objektumot a programunk így nézne ki:
var wind = new PVector(0.01, 0);
m.applyForce(wind);
Az eredmény nem különösebben érdekes, de kezdetnek nem rossz. Elkészítünk egy PVector objektumot, kezdeti értéket rendelünk hozzá, és átadjuk azt egy másik objektumnak (ami azután felhasználja a saját gyorsulásához). Ha két erőt szeretnénk, mondjuk szelet és gravitációt (ez utóbbi egy kicsit erősebb, és lefelé mutat), az alábbi kódot írhatnánk:
var wind = new PVector(0.01, 0);
var gravity = new PVector(0, 0.1);
m.applyForce(wind);
m.applyForce(gravity);
Most két, különböző irányú és nagyságú erőnk van, és mindkettő az m objektumra hat. Biztatóan haladunk előre. A ProcessingJS segítségével felépítettünk a tárgyainknak egy világot, egy olyan környezetet, amire a tárgyaink reagálnak.
Így néz ki a program, miután mindent hozzáadtunk. (A programban található megjegyzések: 1. sor: Dan Shiffman, natureofcode.com példája alapján; 11. sor: Newton második törvényének szimulációja; 12. sor: Kap egy erőt, elosztja a tömeggel, hozzáadja a gyorsuláshoz; 19. sor: 101-es mozgás szimulációja a vektor tananyag szerint; 22. sor: Most biztosítjuk a sebesség lenullázását; 30. sor: A méretet a tömeg alapján állítjuk be, így jelenítjük meg; 34. sor: Bár azt mondtuk, hogy a sebességhez közvetlenül nem nyúlunk, vannak kivételek. Itt megkönnyíti a labda visszapattanásának kódolását.)
Sokat tanultunk, de most már rengeteg mindent meg tudunk csinálni! Folytasd tovább – tanuld meg használni az erődet!

Ez a „Természetes szimulációk" tananyag a Daniel Shiffman által készített „The Nature of Code” alapján készült, a Creative Commons Attribution-NonCommercial 3.0 Unported License szerint.

Szeretnél részt venni a beszélgetésben?

Még nincs hozzászólás.
Tudsz angolul? Kattints ide, ha meg szeretnéd nézni, milyen beszélgetések folynak a Khan Academy angol nyelvű oldalán.