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

Wenn du hinter einem Webfilter bist, stelle sicher, dass die Domänen *. kastatic.org und *. kasandbox.org nicht blockiert sind.

Hauptinhalt

Federkräfte

Zu Beginn dieses Abschnitts haben wir uns die Modellierung einfacher harmonischer Bewegungen durch Abbildung einer Sinnuswelle auf einen Pixelbereich angesehen, und dich mithilfe dieser Sinuswelle ein Gewicht an einer Feder modellieren lassen. Auch wenn die Verwendung der Funktion sin() eine einfache Art ist, mit nur einer Codezeile etwas zum Laufen zu bringen, so reicht dies nicht aus, wenn wir ein Gewicht an einer Feder in einem zweidimensionalen Raum simulieren wollen, das auf andere Umgebungskräfte (Wind, Schwerkraft, usw.) reagiert. Für so eine Simulation (identisch zum Pendel-Beispiel, außer das der Arm nun gefedert ist) müssen wir die Federkräfte über PVector modellieren.
Die Federkraft wird mit dem hookeschen Gesetz berechnet, welches nach dem britischen Physiker Robert Hooke benannt ist, der die Formel 1660 entwickelt hat. Hooke schrieb das Gesetz ursprünglich auf Lateinisch: "Ut tensio, sic vis", oder: “Wie die Auslenkung, so die Kraft”. Wir können es auch so sagen:
Die Federkraft ist direkt proportional zur Auslenkung der Feder.
In anderen Worten: Wenn man stark am Gewicht zieht, wird die Kraft stark sein. Wenn man schwach am Gewicht zieht, wird die Kraft schwach sein. Mathematisch sieht das so aus:
FFeder=k×x
  • k ist konstant und sein Wert wird am Ende die stärke der Kraft bestimmen. Ist die Feder sehr elastisch oder sehr steif?
  • x bezieht sich auf die Auslenkung der Feder, also den Unterschied zwischen ihrer aktuellen Länge und der Ruhelänge. Die Ruhelänge ist definiert als die Länge der Feder im Gleichgewichtszustand.
Beachte nun aber, dass Kraft ein Vektor ist, wir müssen also sowohl den Betrag als auch die Richtung berechnen. Schauen wir uns ein weiteres Diagramm zur Feder an und benennen wir alle möglichen gegebenen Werte in einem Programm.
Definieren wir die folgenden drei Startvariablen aus dem vorherigen Diagramm mit ein paar realistischen Werten.
var anchor = new PVector(100, 10);
var bob = new PVector(110, 100);
var restLength = 20;
Wir verwenden zunächst das Hooksche Gesetz, um den Betrag der Kraft zu berechnen. Wir brauchen also k und x. k ist einfach: Es ist bloß eine Konstante, also können wir uns etwas ausdenken.
var k = 0{,}1;
x ist vielleicht ein bisschen schwieriger. Wir müssen den Unterschied zwischen der aktuellen Länge und der Ruhelänge kennen. Die Länge in Ruhe ist definiert als die Variable restLength. Was ist die aktuelle Länge? Der Abstand zwischen dem Ankerpunkt und dem Pendel. Und wie können wir diesen Abstand berechnen? Wie wäre es mit dem Betrag eines Vektors, der vom Ankerpunkt zum Gewicht zeigt? (Dies ist genau der gleiche Prozess, den wir angewandt haben, als wir den Abstand im Kapitel Anziehungskraft der Gravitation berechnet haben.)
var dir = PVector.sub(bob, anchor);
var currentLength = dir.mag();
var x = currentLength - restLength;
Nun da wir die nötigen Bestandteile für den Betrag der Kraft (-1 * k * x) beisammen haben, müssen wir noch die Richtung bestimmen - also einen Einheitsvektor, der in Richtung der Kraft zeigt. Die gute Nachricht ist, dass es diesen Vektor schon gibt. Richtig? Vor einem Moment haben wir erst überlegt: “Wie können wir diesen Abstand berechnen? Vielleicht über den Betrag eines Vektors, der vom Ankerpunkt zum Gewicht zeigt?” Naja, der gleiche Vektor ist doch die Richtung der Kraft!
Im vorherigen Diagramm sehen wir: Wenn wir die Feder über ihre Ruhelänge hinweg ausziehen, sollte es eine Kraft geben, die sie wieder zurück zum Ankerpunkt zieht. Und wenn sie sich über ihre Ruhelänge hinaus zusammenzieht, sollte die Kraft sie wieder vom Anker weg drücken. Diese Richtungsumkehr macht sich in der Formel über -1 bemerkbar. Wir müssen jetzt also nur noch den PVector normieren, den wir für die Abstandsberechnung verwendet haben! Schauen wir uns den Code an und benennen die Variable PVector in “force” um.
var k = 0.01;
var force = PVector.sub(bob, anchor);
var currentLength = force.mag();
var x = currentLength - restLength;
// Richtung der Federkraft, ein Einheitsvektor
force.normalize();
//Multipliziere Richtung und Betrag!
force.mult(-1 * k * x);
Nun da wir den kompletten Algorithmus zur Berechnung des Federkraftvektors gefunden haben, bleibt noch die Frage: Welche objektorientierte Programmierungsstruktur sollen wir verwenden? Auch bei dieser Frage gibt es mal wieder keine “richtige” Antwort. Es gibt mehrere Möglichkeiten. Welche wir wählen, hängt von den Zielen unseres Programms und unserem eigenen Programmierstil ab. Da wir die ganze Zeit mit einem Objekt Mover gearbeitet haben, bleiben wir einfach mal bei diesem Framework. Stellen wir uns unser Objekt Mover mal als das Federgewicht (“bob”) vor. Das Gewicht braucht einen Ort, eine Geschwindigkeit und Beschleunigungsvektoren, um sich über den Bildschirm zu bewegen. Perfekt, das haben wir alles schon! Vielleicht wird auf das Gewicht noch eine Schwerkraft mittels der Methode applyForce() ausgeübt. Nur noch ein Schritt, wir müssen noch die Federkraft anwenden:
var bob = new Bob();

draw = function()  {
  // Our “make-up-a-gravity force”
  var gravity = new PVector(0, 1);
  bob.applyForce(gravity);
  // We need to also calculate and apply a spring force!
  var spring = ????
  bob.applyForce(spring);

  // Our standard update() and display() methods
  bob.update();
  bob.display();
};
Eine Möglichkeit wäre es, den gesamten Code für die Federkraft in die Hauptschleife draw() zu schreiben. Aber wenn wir in die Zukunft denken, wo wir vielleicht viele Gewichte und Federverbindungen haben, macht es mehr Sinn, ein zusätzliches Objekt Spring anzulegen. Wie im Diagramm oben gezeigt: Das Objekt Bob verfolgt die Bewegungen des Gewichts, und das Objekt Spring verfolgt den Ankerpunkt und die Ruhelänge und berechnet die Federkraft am Gewicht.
Damit können wir nun diesen wunderschönen Code schreiben, der sie zusammenbringt:
var bob = new Bob();
var spring = new Spring();

draw = function()  {
  // Our “make-up-a-gravity force”
  var gravity = new PVector(0, 1);
  bob.applyForce(gravity);
  // Spring.connect() will take care of 
  // computing and applying the spring force
  spring.connect(bob);

  // Our standard update() and display() methods
  bob.update();
  bob.display();
};
Dir fällt hier vielleicht auf, dass wir etwas Ähnliches im Kapitel über die Schwerkraft mit einem Attractor programmiert haben. Dort hieß es:
var force = attractor.calculateAttraction(mover);
mover.applyForce(force);
Die analoge Situation mit einer Feder wäre dann:
var force = spring.calculateForce(bob);
bob.applyForce(force);
Trotzdem haben wir in diesem Beispiel nichts anderes gemacht als:
spring.connect(bob);
Was geht da vor? Warum müssen wir applyForce() auf bob nicht aufrufen? Die Antwort ist, natürlich müssen wir applyForce() auf bob aufrufen. Aber anstatt das in draw() zu tun, sehen wir hier, dass es eine vernünftige (und manchmal sogar bessere) Alternative ist, die Methode connect() den Aufruf von applyForce() für das Gewicht durchführen zu lassen.
Spring.prototype.connect(bob) {
  var force = /* some fancy calculations */;
  bob.applyForce(force);
};
Warum gehen wir beim Objekt Attractor und beim Objekt Spring unterschiedlich vor? Zu Beginn unserer Lektion über Kräfte war es deutlicher, alle Kräfte in der Hauptschleife draw() aufzuzeigen. Das hat dir hoffentlich gehofen, die Kräfteaddition zu verstehen. Nun da wir uns damit besser auskennen, ist es vielleicht einfacher, einige Details direkt in den Objekten anzulegen.
In folgendem Programm ist nun alles zusammengefügt. Wir haben ein paar Dinge ergänzt: (1) Das Objekt Bob enthält Funktionen zur Maussteuerung, um das Gewicht über den Bildschirm zu ziehen. (2) Das Objekt Spring enthält eine Funktion, um die Länge des System auf ein Minimum und Maximum zu begrenzen.

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.
Verstehst du Englisch? Klick hier, um weitere Diskussionen auf der englischen Khan Academy Seite zu sehen.