Adventskalender 2009: Türchen 12

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