Zum Inhalt springen

Adventskalender 2009: Türchen 12

Aus Wikibooks

Das Schneeflöckchen

[Bearbeiten]

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

[Bearbeiten]
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 und nennen wollen. und fassen wir als Vektoren mit zwei Komponenten auf.

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

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

Die Länge der Linie zwischen und ist

Auf dieser Linie interessieren uns zwischen und drei weitere Punkte. Ein Mittelpunkt und zwei Punkte, die die Linie jeweils Dritteln und . 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:

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

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

Diese Gerade findet man, in dem man entweder die Steigung als 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 ist dann:

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

Zuletzt verbindet man die Punkte , , , und 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.

Schneeflockenprogramm

[Bearbeiten]

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

[Bearbeiten]



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