Adventskalender 2009: Türchen 12: Unterschied zwischen den Versionen

Aus testwiki
Zur Navigation springen Zur Suche springen
imported>Zase Wieder
K source syntaxhighlight
 
(kein Unterschied)

Aktuelle Version vom 29. September 2022, 21:52 Uhr

Das Schneeflöckchen

Manchmal ist es im Dezember so warm, dass man keine Schneeflöckchen sehen kann. Sie kommen einfach nicht bis zur Erde, werden auf Ihrem Weg vom Himmel zu Wasser, der als Regen auf uns herniedergeht.

Schneeflöckchen kann man sich am Computer selber bauen. Man benötigt etwas Mathematik der Oberstufe, einen Computer, mit dem man Computerprogramme schreiben kann, und etwas Muße. Davon hat man in der Vorweihnachtszeit leider zu wenig. Nehmen Sie dieses Türchen als Anregung, sich über die Weihnachtszeit mit Mathematik und Programmierung zu beschäftigen.

Schneeflöckchenmathematik

Aus einer Seite wird ein Stückchen Schneeflocke

Wir beginnen mit einem Dreieck. Ein Dreieck hat drei Seiten, mit jeder der Seiten wollen wir das Gleiche machen. Wir wollen zeigen, was mit jeder dieser Seiten zu tun ist.

Eine Seite ist erstmal eine Linie. Nichts weiter. Diese Linie hat einen Anfang und ein Ende, die wir P1 und P2 nennen wollen. P1 und P2 fassen wir als Vektoren mit zwei Komponenten auf.

Möchte man diese Linie als Gerade beschreiben, dann macht man das so:

  • g:X=P1+λ(P2P1)

Wenn wir also den Parameter λ verändern, dann können wir jeden Punkt der Linie "anfahren".

Die Länge der Linie zwischen P1 und P2 ist

  • d=|P2P1|

Auf dieser Linie interessieren uns zwischen P1 und P2 drei weitere Punkte. Ein Mittelpunkt Pm und zwei Punkte, die die Linie jeweils Dritteln PD1 und PD2. Wenn wir für λ die Werte 0,33, 0,5 und 0,66 nacheinander einsetzen, bekommen wir genau diese Punkte heraus.

Ein Einheitsvektor ist ein Vektor, dessen Betrag genau 1 ist und der uns die Richtung unserer Gerade vorgibt. Man erhält ihn, wenn man folgendermassen rechnet:

  • e=P2P1d

Wir können nun unsere obere Geradengleichung auch schreiben als:

  • g:X=P1+λe

Haben wir nun all diese Punkte, eine Geradengleichung und den Einheitsvektor, dann suchen wir eine weitere Gerade, die durch den Punkt Pm geht, und zwar im Winkel von 90° und genau d3 lang ist.

Diese Gerade findet man, in dem man entweder die Steigung als 1λ rechnet oder einfach die Komponenten des Einheitsvektors vertauscht und auf die Vorzeichen achtet (die neue X-Komponente bekommt ein negatives Vorzeichen). Die neue Gerade mit passendem Einheitsvektor f ist dann:

  • h:X=Pm+μf

Diese beiden Geraden g und h schneiden sich im Punkt Pm und haben einen Winkel von 90° zueinander. Setzt man nun für μ den Wert 0,33d ein, dann bekommen wir einen neuen Punkt Ps auf der Geraden, der von Punkt Pm ein Stückchen entfernt ist und auf der Geraden h liegt.

Zuletzt verbindet man die Punkte P1, PD1, Ps, PD2 und P2 miteinander und hat nun auf der Dreieckslinie einen Zacken geschlagen. Dieses ist ein Stückchen Schneeflocke.

Das Verfahren wiederholen wir für alle Seiten des Dreiecks. Und dann nochmal für alle neuen Linien, die so entstanden sind. Und dann nochmal.... und nochmal.... und erhalten eine Schneeflocke. Vorlage:Clear

Schneeflockenprogramm

Viel leichter geht es, wenn man sowas mit dem Computer macht. Das folgende Python-Programm rechnet und zeigt Ihnen, wie Computerschneeflocken aussehen. Auch hier starten wir mit einem Dreieck, ein Druck auf die ENTER-Taste führt den nächsten Schritt aus, alle anderen Tasten beenden das Programm:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import pygame
import sys
import math


WINWIDTH = 640
WINHEIGHT = 480


def init(breite, hoehe):
    pygame.init()
    screen = pygame.display.set_mode((breite, hoehe))
    return screen


def schneeflocke_iteration(liste):
    liste_neu = []
    length = len(liste)
    for i in xrange(length):
        x1, y1 = liste[i]
        x2, y2 = liste[(i+1) % length]
        dx = x2 - x1
        dy = y2 - y1
        dist = math.sqrt( dx**2 + dy**2 )
        if dist > 0.01:
            # Mittelpunkt auf dieser Geraden
            xm = x1 + 0.5 * dx
            ym = y1 + 0.5 * dy
            # Drittelpunkte der Geraden
            xd1 = x1 + 0.33 * dx
            yd1 = y1 + 0.33 * dy
            xd2 = x1 + 0.66 * dx
            yd2 = y1 + 0.66 * dy
            # vertauschen, Einheitsvektor
            ex = dy / dist
            ey = -dx / dist
            # neuer Punkt
            x_neu = xm + 0.33 * dist * ex
            y_neu = ym + 0.33 * dist * ey
            liste_neu.append((x1, y1))
            liste_neu.append((int(xd1), int(yd1)))
            liste_neu.append((int(x_neu), int(y_neu)))
            liste_neu.append((int(xd2), int(yd2)))
        else:
            liste_neu.append((x1, y1))
    return liste_neu


def male_schneeflocke(floeckchen):
    screen.fill((255, 255, 255))
    pygame.draw.lines(screen, (0, 0, 0), True, floeckchen)
    pygame.display.update()


def hauptschleife():
    mitteX = WINWIDTH / 2
    mitteY = WINHEIGHT / 2 + 50
    schneeflocke = [(mitteX - 150, mitteY - 150), (mitteX + 150, mitteY - 150), (mitteX, mitteY + 150)]
    male_schneeflocke(schneeflocke)
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    # Nicht zu viele Punkte aufnehmen!
                    if len(schneeflocke) < 2000:
                        schneeflocke = schneeflocke_iteration(schneeflocke)
                    male_schneeflocke(schneeflocke)
                else:
                    sys.exit()


if __name__ == '__main__':
    screen = init(WINWIDTH, WINHEIGHT)
    hauptschleife()


Und so sieht das Programm aus, wenn es läuft:

Anfang...
nach einigen Iterationen

Bemerkung



Das Türchen vom 11 Dez.09 Das Türchen vom 13 Dez.09