Was du hier lernst
- Gedämpfte Schwingung
- cos und e-Funktion
- Klassen mit privaten Attributen
- Winkel in Koordinaten umrechnen
- Tupel tauschen
- Parameter ausprobieren
So schwingt die Pendelkette
Eine echte Pendelkette ist ein kleines Physiklabor: Kugeln stoßen zusammen, Impuls und Energie wandern durch die Reihe. Das Programm simuliert diese Stöße nicht Kugel für Kugel. Es beschreibt die Schwingung mit einer Formel und verteilt sie mit einem Trick auf die richtigen Kugeln. Das Ergebnis sieht erstaunlich echt aus.
1. Eine Formel für die Schwingung
Ein Pendel schwingt hin und her, und mit der Zeit wird der Ausschlag kleiner. Beides steckt in calculateAlpha:
damping = 1.0 / math.exp(self.__dampingConstant * time)
alpha = self.__alphaMax * math.cos(math.sqrt(self.__gravity / self.__wireLength) * time) * damping
Die Formel hat drei Teile:
alphaMaxist der größte Ausschlag, hier 45 Grad.cos(√(g/l) · t)schwingt gleichmäßig zwischen −1 und 1. Wie schnell, bestimmt√(g/l): Mehr Schwerkraftgmacht das Pendel schneller, ein längerer Fadenllangsamer.dampingist die Dämpfung.1 / e^(d·t)beginnt bei 1 und schrumpft mit der Zeit gegen 0 – so verliert das Pendel langsam Schwung, wie durch Luftreibung.
Mathematisches Pendel
Die Formel beschreibt ein »mathematisches Pendel«: eine punktförmige Masse an einem masselosen Faden. Genau genommen stimmt sie nur für kleine Ausschläge. Für die Pendelkette ist die Näherung gut genug. Ein echtes, physikalisches Pendel bräuchte eine aufwendigere Rechnung – daran erinnert auch der Kommentar über der Klasse.
2. Eine Klasse für ein Pendel
Jedes Pendel hat seinen Aufhängepunkt, seine Farbe, Fadenlänge, Kugelgröße und die physikalischen Werte. Die Klasse Pendulum bündelt all das. Die Attribute beginnen mit zwei Unterstrichen, etwa self.__alphaMax. Python versteckt solche Namen vor dem Zugriff von außen – ein Hinweis: Diese Werte gehören dem Pendel allein.
Nach außen bietet die Klasse nur zwei Methoden an: calculateAlpha(time) für den Winkel zu einem Zeitpunkt und draw(screen, position, scale) fürs Zeichnen.
3. Vom Winkel zur Kugel
Das Zeichnen kennst du vielleicht von der analogen Uhr: Aus einem Winkel wird mit Kosinus und Sinus ein Punkt auf einem Kreis um den Aufhängepunkt.
def __getWirePositionDegrees(self, position, scale):
offset = -270
degrees = 360 / scale * position + offset
return degrees
Der Versatz von −270 Grad sorgt dafür, dass ein Winkel von 0 senkrecht nach unten zeigt. Positive Winkel lenken das Pendel nach links aus, negative nach rechts. Dann zeichnet draw den Faden als Linie, die Kugel als Kreis und einen kleinen Punkt an der Aufhängung.
4. Fünf Kugeln, drei Winkel
Die Kette hat fünf Pendel, aber das Programm rechnet nur mit drei Winkeln:
pendulum1.draw(screen, alpha1, 360)
pendulum2.draw(screen, alpha1, 360)
pendulum3.draw(screen, alpha2, 360)
pendulum4.draw(screen, alpha3, 360)
pendulum5.draw(screen, alpha3, 360)
Die beiden linken Kugeln teilen sich alpha1, die beiden rechten alpha3. Die mittlere bekommt alpha2, der immer 0 bleibt – sie hängt still und gibt den Stoß nur weiter.
5. Klack: der Trick mit dem Tauschen
Jetzt kommt der Kniff. Schwingen die linken Kugeln zurück und würden über die Senkrechte hinaus nach rechts ausschlagen, wird alpha1 negativ. Genau in diesem Moment tauscht das Programm die Winkel:
if alpha1 < 0:
alpha1, alpha3 = alpha3, alpha1
Die linken Kugeln bleiben in der Mitte stehen, die rechten übernehmen den Schwung. Beim Zurückschwingen passiert dasselbe in die andere Richtung. Python kann zwei Variablen in einer Zeile tauschen, ohne Hilfsvariable – das Tupel rechts wird erst komplett gebildet und dann verteilt.
6. Die Wirkung der Parameter
Alle Größen stehen am Anfang von main(): Schwerkraft, Fadenlänge, Dämpfung und Startwinkel. Unter »Probier mal« kannst du sie verändern. Interessant ist dabei: Der Startwinkel verändert die Höhe, aber nicht das Tempo der Schwingung. Die Schwingungsdauer hängt in der Formel nur von g und l ab.
Zeit ist keine echte Zeit
time wächst pro Bild um 0,2, bei 50 Bildern pro Sekunde also um 10 pro Sekunde. Die Simulation läuft damit schneller als die Wirklichkeit – bei einem 280 Pixel langen »Faden« und 9,81 m/s² sähe das Pendel sonst sehr träge aus. Mit dem Faktor kannst du das Tempo einstellen, ohne die Physik anzufassen.
Probier mal
Jede Variante ändert den Code oben. Ein Klick auf »Ausprobieren« übernimmt die Änderung in den Editor und startet das Programm. »Zurücksetzen« holt das Original zurück.
-
01Nur eine Kugel anheben
Das klassische Bild: Links schwingt eine einzige Kugel los, rechts fliegt eine davon. Dafür hängen jetzt die zweite und die vierte Kugel fest in der Mitte, sie bekommen den Winkel
alpha2, der immer 0 bleibt.- pendulum2.draw(screen, alpha1, 360) + pendulum2.draw(screen, alpha2, 360) - pendulum4.draw(screen, alpha3, 360) + pendulum4.draw(screen, alpha2, 360) -
02Auf dem Mond
Auf dem Mond beträgt die Schwerebeschleunigung nur 1,62 m/s² statt 9,81 m/s². In der Formel steckt
gravityunter der Wurzel: Die Pendel schwingen gut zweieinhalbmal langsamer.- gravity = 9.81 + gravity = 1.62 -
03Ohne Reibung
Mit einer Dämpfungskonstante von 0 wird der Dämpfungsfaktor
1 / e^0 = 1– die Kette klackt für immer. In der Wirklichkeit gibt es so ein Perpetuum mobile nicht.- dampingConstant = 1.0 / 200.0 + dampingConstant = 0.0 -
04Honig statt Luft
Eine zehnmal stärkere Dämpfung: Die Schwingung stirbt nach wenigen Stößen. Beobachte, wie die e-Funktion den Ausschlag immer schneller schrumpfen lässt.
- dampingConstant = 1.0 / 200.0 + dampingConstant = 1.0 / 20.0 -
05Weiter ausholen
Starte mit 75 statt 45 Grad. Die Kugeln fliegen höher – schwingen aber gleich schnell, denn die Schwingungsdauer hängt in dieser Formel nicht vom Ausschlag ab.
- alpha1 = 45.0 + alpha1 = 75.0
Vom Buch in den Browser
Im Buch liegt die Klasse Pendulum in pendulum.py, das Programm für die Pendelkette in pendulum_v4.py. Hier stehen beide in einer Datei. Die Klasse ist unverändert, nur die drei Zeichenbefehle nutzen jetzt c4f statt pygame:
| Im Buch (pygame) | Hier (c4f) |
|---|---|
pygame.draw.line(screen, farbe, start, ende, dicke) |
screen.line(start, ende, farbe, dicke) |
pygame.draw.circle(screen, farbe, mitte, radius) |
screen.circle(mitte, radius, farbe) |
screen.fill(farbe) |
screen.fill(farbe) – gleich geblieben |
pygame.display.flip() + pygame.time.delay(20) |
await screen.frame(50) |
Die Hauptschleife steht in einer async-Funktion main(), die am Ende mit await main() startet – nötig, damit der Browser zwischen den Bildern zeichnen kann.
Die Ereignisbehandlung des Originals entfällt: Sie beendete das Programm bei einem Tastendruck, dafür gibt es hier den Knopf »Stopp«. Bei einem Mausklick rief sie event.position_window() auf – eine Methode, die es in pygame nicht gibt. Ein Klick ins Fenster hätte das Programm deshalb mit einem Fehler beendet.
Python 3 ändert an diesem Programm fast nichts: Alle Rechnungen verwenden Kommazahlen, die Division verhält sich also in beiden Versionen gleich.