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
Widerstand in Luft und Flüssigkeit
Reibung tritt auch dann auf, wenn sich ein Körper durch eine Flüssigkeit oder ein Gas bewegt. Diese Kraft hat viele verschiedene Namen, die alle wirklich das gleiche bedeuten: Viskosität, Zähflüssigkeit, Widerstandskraft, Flüssigkeitswiderstand, etc. Während das Ergebnis letztlich dasselbe wie in unseren vorherigen Beispielen mit der Reibung ist (das Objekt verlangsamt sich), werden wir nun die Widerstandskraft auf eine andere Art berechnen. Schauen wir uns die Formel an:
Wir zerlegen nun diese Formel und schauen sie uns genau an, damit wir in eine einfachere Version der Formel effektiv in ProcessingJS programmieren und simulieren können.
- F, start subscript, d, end subscript bezieht sich auf die Luftwiderstandskraft, den Vektor, den wir letztendlich berechnen und an unsere Funktion
applyForce()
übergeben wollen. - -1/2 ist eine Konstante: -0.5. Das ist für unsere ProcessingJS-Welt ziemlich irrelevant, da wir uns ohnehin Werte für andere Konstanten ausdenken werden. Die Tatsache, dass sie negativ ist, ist jedoch wichtig, da sie uns sagt, dass die Kraft in die entgegengesetzte Richtung der Geschwindigkeit wirkt (genau wie bei der Reibung).
- rho ist der griechische Buchstabe rho und bezieht sich auf die Dichte der Flüssigkeit, etwas, um das wir uns nicht kümmern müssen. Wir können das Problem vereinfachen und davon ausgehen, dass dies einen konstanten Wert von 1 hat.
- v bezieht sich auf die Geschwindigkeit des sich bewegenden Objekts. OK, wir haben es kapiert! Die Geschwindigkeit des Objekts ist der Betrag des Geschwindigkeitsvektors:
velocity.mag()
. Und v, squared bedeutet einfach v zum Quadrat oder v, times, v. - A bezieht sich auf die Stirnfläche des Objekts, das sich durch die Flüssigkeit (oder das Gas) schiebt. Ein aerodynamischer Lamborghini wird beispielsweise weniger Luftwiderstand erfahren als ein kastenförmiger Volvo. Für eine einfache Simulation können wir jedoch unser Objekt als kugelförmig betrachten und dieses Element ignorieren.
- C, start subscript, d, end subscript ist der Luftwiderstandsbeiwert, genau wie der Reibungskoeffizient (μ). Dies ist eine Konstante, die wir bestimmen, je nachdem, ob die Widerstandskraft stark oder schwach sein soll.
- v, with, hat, on top Kommt dir das bekannt vor? Das sollte es auch. Dies bezieht sich auf den Einheitsvektor der Geschwindigkeit, d.h.
velocity.normalize()
. Genau wie bei der Reibung ist der Widerstand eine Kraft, die in die entgegengesetzte Richtung der Geschwindigkeit zeigt.
Nun da wir jede Komponente der Formel analysiert haben und wissen, was wir in unserer vereinfachten Simulation verwenden möchten, können wir die vereinfachte Formel zusammensetzen:
oder:
// Part 1 of our formula (magnitude): v^2 * Cd
var c = 0.1;
var speed = velocity.mag();
var dragMagnitude = c * speed * speed;
// Part 2 of our formula (direction): v unit vector * -1
var drag = velocity.get();
drag.normalize();
drag.mult(-1);
// Magnitude and direction together!
drag.mult(dragMagnitude);
Wir implementieren diese Kraft in unserem
Mover
mit einer Addition. Als wir unser Beispiel mit der Reibung geschrieben haben, war die Reibungskraft immer allgegenwärtig. Immer wenn sich ein Objekt bewegt hat, wurde es durch die Reibung verlangsamt. Hier wollen wir nun der Simulationsumgebung ein Element (eine “Flüssigkeit”) hinzufügen, durch welches sich der Mover
bewegt. Das Objekt Liquid
ist ein Rechteck und wir kennen seine Position, Breite, Höhe und seinen “Widerstandskoeffizienten”. Letzterer definiert, ob sich Objekte leicht (wie bei Luft) oder schwer (wie bei Sirup) hindurch bewegen können. Zusätzlich braucht es eine Funktion um sich selbst auf dem Canvas darzustellen und zwei weitere Funktionen welche wir schon bald anschauen.var Liquid = function(x, y, w, h, c) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.c = c;
};
Liquid.prototype.display = function() {
noStroke();
fill(50);
rect(this.x, this.y, this.w, this.h);
};
Das Hauptprogramm deklariert und initialisiert nun eine neue Instanz der Klasse
Liquid
. Beachte, dass der Koeffizient klein ist (0,1), ansonsten würde das Objekt relativ schnell zum Stillstand kommen. Eines Tages wirst du dann vielleicht gerade diesen Effekt erzielen wollen.var liquid = new Liquid(0, height/2, width, height/2, 0{,}1);
Nun kommt aber eine interessante Frage: Wie kommuniziert der
Mover
mit dem Objekt Liquid
? Mit anderen Worten:Wenn sich ein Mover durch eine Flüssigkeit bewegt, wirkt auf ihn eine Widerstandskraft.
…und in objektorientierter Sprache (wir verwenden eine Schleife für ein Array von
Mover
-Objekten mit dem Index i
)://Ist der Mover in der Flüssigkeit?
if (liquid.contains(movers[i])) {
// Berechne die Widerstandskraft
var dragForce = liquid.calculateDrag(movers[i]);
// Wende die Widerstandskraft auf den Mover an
movers[i].applyForce(dragForce);
}
Der Code oben sagt uns, dass wir dem Objektypen
Liquid
zwei Funktionen hinzufügen müssen: (1) eine Funktion welche bestimmt ob sich ein Mover
innerhalb des Liquid
-Objektes befindet und (2) eine Funktion welche die Widerstandskraft, die auf das Mover
-Objekt wirkt, berechnet.Die erste ist einfach, wir verwenden einfach eine Bedingung, um zu bestimmen, ob der Vektor für die Position des Objektes innerhalb des definierten Rechtecks der Flüssigkeit liegt.
Liquid.prototype.contains = function(m) {
var p = m.position;
return p.x > this.x && p.x < this.x + this.w &&
p.y > this.y && p.y < this.y + this.h;
};
Die Funktion
drag()
ist etwas komplizierter, wir haben den Code für dich aber schon geschrieben. Es ist einfach nur eine Implementierung unserer Formel. Die Widerstandskraft ist gleich dem Widerstandskoeffizienten multipliziert mit dem Quadrat der Geschwindigkeit des Mover
s, in die entgegengesetzte Richtung der Geschwindigkeit!Liquid.prototype.calculateDrag = function(m) {
// Magnitude is coefficient * speed squared
var speed = m.velocity.mag();
var dragMagnitude = this.c * speed * speed;
// Direction is inverse of velocity
var dragForce = m.velocity.get();
dragForce.mult(-1);
// Scale according to magnitude
dragForce.normalize();
dragForce.mult(dragMagnitude);
return dragForce;
};
Mit diesen zwei zusätzlichen Funktion im Objekttyp
Liquid
können wir nun alles in einem Programm zusammenfügen:Wenn du das Programm ausführst, wirst du feststellen, dass wir Bälle simulieren, die ins Wasser fallen. Die Objekte verlangsamen sich erst dann, wenn sie sich durch das blaue Rechteck (das Wasser) am unteren Rand bewegen. Du wirst auch feststellen, dass sich kleinere Objekte viel mehr verlangsamen als größere. Erinnerst du dich noch an das zweite newtonsche Gesetz?
A = F / M
. Beschleunigung ist gleich Kraft geteilt durch Masse. Ein Objekt mit großer Masse beschleunigt weniger. Ein Objekt mit kleiner Masse beschleunigt mehr. In diesem Fall wird die Beschleunigung durch die Widerstandskraft reduziert. Und die kleineren Objekte verlangsamen sich schneller als die großen.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.