Hauptinhalt
Programmierung
Kurs: Programmierung > Lerneinheit 5
Lektion 5: Kräfte- Newtonsche Bewegungsgesetze
- Challenge: Schwebender Ballon
- Bewegung von vielen Objekten
- Challenge: Wandbälle
- Gravitation und Reibung modellieren
- Challenge: Liegende Polizisten
- Widerstand in Luft und Flüssigkeit
- Challenge: Sinkendes Treibholz
- Anziehungskraft der Gravitation
- Challenge: Kunstwerk-Generator
- Gegenseitige Anziehung
- Challenge: Gegenseitige Abstoßung
- Projekt: Angenehmes und fürchterliche Räuber
© 2023 Khan AcademyNutzungsbedingungenDatenschutzerklärungCookie-Meldung
Anziehungskraft der Gravitation
Die Schwerkraft ist wahrscheinlich die berühmteste aller Kräfte. Wenn wir Menschen auf der Erde and die Schwerkraft denken, denken wir daran, wie Isaac Newton ein Apfel auf den Kopf fiel. Schwerkraft bedeutet, dass Sachen herunterfallen. Aber das ist nur unsere Erfahrung der Schwerkraft. Tatsächlich zieht dank der Schwerkraft genauso wie die Erde den Apfel auch der Apfel die Erde an. Die Erde ist aber einfach so enorm groß, dass ihre Gravitationskraft alle gravitativen Wechselwirkungen zwischen anderen Objekten überlagert. Jedes Objekt mit einer Masse übt eine Gravitationskraft auf jedes andere Objekt aus. Wie in der Abbildung unten gezeigt, gibt es eine Formel, mit welcher wir die Stärke dieser Kräfte berechnen können.
Betrachten wir diese Formel ein wenig genauer.
F
bezieht sich auf die Gravitationskraft, den Vektor, den wir letztendlich berechnen und an unsere FunktionapplyForce()
übergeben wollen.G
ist die universelle Gravitationskonstante, die in unserer Welt 6,67428 x 10^-11 Meter im Kubik pro Kilogramm pro Sekunde zum Quadrat beträgt. Das ist eine ziemlich wichtige Zahl, wenn dein Name Isaac Newton oder Albert Einstein ist. Es ist keine wichtige Zahl, wenn du ein ProcessingJS-Programmierer bist. Auch hier handelt es sich um eine Konstante, die wir verwenden können, um die Kräfte in unserer Welt schwächer oder stärker zu machen. Sie einfach gleich eins zu setzen und zu ignorieren, ist auch keine so schlechte Wahl. und sind die Massen der Objekte1
und2
. Wie wir bei Newtons zweitem Gesetz ( ) gesehen haben, ist die Masse auch etwas, das wir ignorieren können. Schließlich haben die auf dem Bildschirm gezeichneten Formen keine physikalische Masse. Wenn wir diese Werte jedoch beibehalten, können wir interessantere Simulationen erstellen, in denen "größere" Objekte eine stärkere Gravitationskraft ausüben als kleinere. bezieht sich auf den Einheitsvektor, der von Objekt1
zu Objekt2
zeigt. Wie wir gleich sehen werden, können wir diesen Richtungsvektor berechnen, indem wir den Standort des einen Objekts vom anderen subtrahieren. bezieht sich auf den Abstand zwischen den beiden Objekten im Quadrat. Nehmen wir uns einen Moment Zeit, um das Ganze etwas genauer zu betrachten. Bei allem, was oben in der Formel steht —G
, , —gilt: je größer der Wert, desto stärker die Kraft. Große Masse, große Kraft. GroßesG
, große Kraft. Wenn wir nun durch etwas dividieren, haben wir das Gegenteil. Die Stärke der Kraft verhält sich umgekehrt proportional zum Abstand im Quadrat. Je weiter ein Objekt entfernt ist, desto schwächer ist die Kraft; je näher, desto stärker.
Hoffentlich macht die Formel nun etwas mehr Sinn. Wir haben uns eine Abbildung angeschaut und die einzelnen Komponenten der Formel zerlegt. Nun müssen wir uns überlegen, wie wir die Mathematik mit ProcessingJS implementieren. Wir treffen dazu aber ein paar Annahmen.
Wir haben zwei Objekte und:
- Jedes Objekt hat einen
PVector
für die Position:location1
undlocation2
. - Jedes Objekt hat eine numerische Masse:
mass1
undmass2
. - Es gibt eine numerische Variable für die universelle Gravitationskonstante
G
.
Mit diesen Annahmen wollen wir die Schwerkraft als mit der Formel von weiter oben. Danach berechnen wir die Stärke der Kraft mit der Masse und dem Abstand.
PVector
berechnen. Dies machen wir in zwei Schritten. Zuerst berechnen wir die Richtung der Kraft Erinnerst du dich, wie wir herausgefunden haben, wie sich ein Objekt in Richtung der Maus beschleunigt? Hier verwenden wir nun die gleiche Logik.
Ein Vektor ist der Abstand zwischen zwei Punkten. Um einen Vektor vom Kreis zur Maus zeigen zu lassen, haben wir einen Punkt vom anderen subtrahiert:
var dir = PVector.sub(mouse, location);
In unserem Fall ist die Richtung der Anziehungskraft, die Objekt 1 auf Objekt 2 ausübt, gleich:
var dir = PVector.sub(location1, location2);
Vergiss nicht, da wir einen Einheitsvektor benötigen, einen Vektor der uns nur die Richtung angibt, müssen wir den Vektor nach der Subtraktion normieren.
dir.normalize();
Gut, wir haben die Richtung der Kraft. Nun müssen wir nur noch den Betrag berechnen und den Vektor entsprechend skalieren.
var m = (G * mass1 * mass2) / (distance * distance);
dir.mult(m);
Das einzige Problem ist, dass wir den Abstand nicht kennen.
G
, mass1
und mass2
sind alle gegeben, aber wir müssen den Abstand zuerst berechnen, bevor der Code oben funktionieren kann. Haben wir nicht soeben einen Vektor der von einer Position zur anderen zeigt erzeugt? Wäre die Länge dieses Vektors nicht der Abstand zwischen zwei Objekten?Nun, wenn wir nur eine Zeile Code hinzufügen und den Betrag des Vektors vor der Normierung berechnen, dann haben wir den Abstand.
// Der Vektor, der vom einen Objekt zum anderen zeigt
var force = PVector.sub(location1, location2);
// Die Länge (Betrag) des Vektors entspricht dem Abstand der zwei Objekte.
var distance = force.mag();
// Verwende die Formel für die Schwerkraft, um die Stärke der Kraft zu berechnen.
var strength = (G * mass1 * mass2) / (distance * distance);
// Normiere und skaliere den Kraftvektor auf den entsprechenden Betrag.
force.normalize();
force.mult(strength);
Beachte, das wir den
PVector
von “dir” in “force” unbenannt haben. Sobald wir mit der Berechnung fertig sind, wird der PVector
mit dem wir begonnen haben zum Kraftvektor den wir eigentlich wollen.Nun da wir die Mathematik und den Code für die Berechnung der Anziehungskraft (zur Simulation der Schwerkraft) ausgearbeitet haben, schauen wir uns an, wie wir diese Methode in ProcessingJS-Programmen verwenden. Zuvor in diesem Kapitel haben wir schon einen einfachen
Mover
, ein Objekt mit den PVector
en "location", "velocity" und "acceleration" sowie der Funktion applyForce()
erstellt. Wir nehmen genau diese Klasse und verwenden sie in einem neuen Programm:- Ein einzelnes
Mover
-Objekt. - Ein einzelnes
Attractor
-Objekt (ein neuer Objekttyp mit einer fixen Position).
Auf den
Mover
wird eine Anziehungkraft ausgeübt, welche ihn in Richtung des Attractor
s zieht, wie in dem Bild unten dargestellt.Wir beginnen, indem wir den neuen
Attractor
ganz einfach mit nur einer Position und Masse und einer Methode für die Darstellung (Größe entsprechend der Masse) implementieren.var Attractor = function() {
this.position = new PVector(width/2, height/2);
this.mass = 20;
this.G = 1;
this.dragOffset = new PVector(0, 0);
this.dragging = false;
this.rollover = false;
};
// Methode für die Darstellung
Attractor.prototype.display = function() {
ellipseMode(CENTER);
strokeWeight(4);
stroke(0);
fill(175, 175, 175, 200);
ellipse(this.position.x, this.position.y, this.mass*2, this.mass*2);
};
Nachdem wir dies definiert haben, können wir eine Instanz vom Objekttyp
Attractor
erstellen.var mover = new Mover();
var attractor = new Attractor();
draw = function() {
background(50, 50, 50);
attractor.display();
mover.update();
mover.display();
};
Dies ist eine gute Struktur: ein Hauptprogramm mit einem
Mover
und einem Attractor
-Objekt. Das letzte Stück des Puzzles ist, wie ein Objekt das andere anzieht. Wie bringen wir diese beiden Objekte dazu miteinander zu interagieren?Es gibt eine Reihe von Design-Möglichkeiten dafür. Hier ein paar davon:
Aufgabe | Funktion |
---|---|
1. Eine Funktion erhält sowohl einen Attractor als auch einen Mover als Parameter: | attraction(a, m); |
2. Eine Methode im Attractor , welche einen Mover als Parameter erhält: | a.attract(m); |
3. Eine Methode im Mover , welche einen Attractor als Parameter erhält: | mover.attractedTo(a); |
4. Eine Methode im Attractor , welche einen Mover als Parameter erhält und einen PVector , die Anziehungskraft, zurückgibt. Die Anziehungskraft wird dann der Methode applyForce() des Mover s übergeben. | var f = a.calculateAttraction(m); mover.applyForce(f); |
Es ist immer gut, wenn man sich mehrere Möglichkeiten für die Interaktion von Objekten anschaut. Du findest wohl für jede dieser Möglichkeiten gute Argumente. Vergessen wir einfach mal die erste, denn ein objektorientiertes Vorgehen ist einfach besser als eine einfache Funktion ohne Verknüfung mit Objekten für
Mover
und Attractor
. Ob du die 2. oder 3. Möglichkeit wählst, hängt davon ab, ob du denkst, “der Attractor zieht den Mover an” oder “der Mover wird vom Attractor angezogen”. Die 4. Möglichkeit scheint aber die beste zu sein, vom Standpunkt unserers Kursfortschritts aus gesehen. Denn wir haben viel Zeit damit verbracht die Methode applyForce()
auszuarbeiten und ich glaube unsere Beispiele werden viel klarer wenn wir damit fortfahren.Mit anderen Worten, wo wir vorher...
var f = new PVector(0{,}1, 0); // Ausgedachte Kraft
mover.applyForce(f);
...hatten, haben wir nun:
var f = a.calculateAttraction(m); // Anziehungskraft zwischen zwei Objekten
mover.applyForce(f);
Und so kann unsere Funktion
draw()
nun folgendermaßen geschrieben werden:draw = function() {
background(50, 50, 50);
// Anziehungskraft berechnen und anwenden
var f = a.calculateAttraction(m);
mover.applyForce(f);
attractor.display();
mover.update();
mover.display();
};
Wir haben es fast geschafft. Da wir uns entschieden haben die Methode
calculateAttraction()
im Attractor
zu implementieren, müssen wir nun noch diese Funktion schreiben. Der Funktion wird ein Mover
übergeben und sie gibt einen PVector
zurück. Und was passiert in der Funktion? All diese schöne Mathematik zur Anziehungskraft welche wir uns vorhin angeschaut haben!Attractor.prototype.calculateAttraction = function(mover) {
// Was ist die Richtung der Kraft?
var force = PVector.sub(this.position, mover.position);
var distance = force.mag();
force.normalize();
// Was ist der Betrag der Kraft?
var strength = (this.G * this.mass * mover.mass) / (distance * distance);
force.mult(strength);
// Kraft zurückgeben, damit sie verwendet werden kann!
return force;
};
Und nun sind wir fertig. Mehr oder weniger. Fast. Es gibt noch einen kleinen Punkt, den wir angehen müssen. Schauen wir uns den Code oben nochmals an. Siehst du das Symbol für die Division, den Schrägstrich? Immer wenn wir dies sehen, müssen wir uns überlegen: Was würde passieren, wenn der Abstand eine ganz, ganz kleine Zahl oder (sogar schlimmer!) Null wäre? Nun, wir wissen, dass wir nicht durch 0 teilen können. Und wenn wir durch eine ganz kleine Zahl wie z.B. 0,0001 teilen, dann ist dies das gleiche wie wenn wir mit 10000 multiplizieren! Ja, dies ist zwar die Formel für die Stärke der Anziehungskraft aus der realen Welt, aber wir leben zum Glück nicht in der realen Welt. Wir leben in der ProcessingJS-Welt. Und in der Welt von ProcessingJS kann der Mover ganz, ganz nahe am Attractor sein und dann würde die Kraft so stark werden, dass der Mover weit aus dem Bildschirm herausfliegt. Daher macht es mit dieser Formel Sinn, dass wir nah an der Realität bleiben und eine Beschränkung für den Bereich des gültigen Abstandes einführen. Vielleicht sollte, egal wo sich der
Mover
gerade befindet, der Abstand zum Attractor nie weniger als 5 Pixel oder mehr als 25 Pixel betragen.distance = constrain(distance, 5, 25);
Aus dem gleichen Grund, aus dem wir eine Einschränkung für den Mindestabstand vornehmen, sollten wir ebenfalls eine für den Maximalabstand machen. Immerhin, wenn der Mover z.B. 500 Pixel vom Attractor entfernt wäre (was nicht unmöglich ist), dann würden wir die Kraft durch 250.000 dividieren. Die Kraft wäre dann schlussendlich so schwach, dass sie fast gar keine Wirkung hätte.
Nun liegt es aber wirklich an dir, zu entscheiden, was für ein Verhalten du möchtest. Aber im Fall von “Ich möchte eine vernünftig aussehende Anziehungskraft, welche nie enorm schwach oder stark wird” macht es Sinn, den Abstand einzuschränken.
Fügen wir nun alles in einem Programm zusammen. Der Objekttyp
Mover
wurde gar nicht verändert, aber unser Programm enthält nun auch einen Objekttyp Attractor
und beide interagieren durch Code. Wir haben ebenfalls Code zum Programm hinzugefügt, welcher den Attractor mit der Maus steuert, so dass es einfacher wird die Auswirkungen zu beobachten.Ebenfalls könnten wir diese Beispiele, wie im Kapitel von Reibung und Widerstand, mit einem Array mit vielen
Mover
-Objekten erweitern. Die wichtigste Änderung war aber die, dass der Mover
jetzt Masse, x und y (wie schon vorher) akzeptiert, im Programm ein Array mit zufällig platzierten Mover
-Objekten initialisiert wird und eine Schleife über das Array die Anziehungskräfte für jeden Mover berechnet:var movers = [];
var attractor = new Attractor();
for (var i = 0; i < 10; i++) {
movers[i] = new Mover(random(0{,}1, 2), random(width), random(height));
}
draw = function() {
background(50, 50, 50);
attractor.display();
for (var i = 0; i < movers.length; i++) {
var force = attractor.calculateAttraction(movers[i]);
movers[i].applyForce(force);
movers[i].update();
movers[i].display();
}
};
Der Kurs "Natürliche Simulationen" ist eine Bearbeitung von "The Nature of Code" von Daniel Shiffman, und wird unter der Creative Commons Attribution-NonCommercial 3,0 Unported Lizenz verwendet.
Willst du an der Diskussion teilnehmen?
Noch keine Beiträge.