Creative Coding mit Processing
Digitale Kunst für Webworker
Die Experimente mit Perlin Noise aus dem letzten Teil helfen uns dabei, interessante Animationen mit Partikelsystemen zu programmieren. Falls Sie die ersten drei Teile verpasst haben sollten: Sie finden alle bisherigen Artikel zusammen mit kommentierten Code-Beispielen auf der beiliegenden DVD.
Wir starten mit einem einzelnen Partikel, das sich auf der Leinwand bewegen soll. Um das Teilchen zu verfolgen, benötigen wir seine aktuelle Position und seine Geschwindigkeit. Damit sich das Teilchen etwas dynamischer bewegt, sehen wir auch eine Beschleunigung vor. In jedem Schritt ändert die Beschleunigung die aktuelle Geschwindigkeit. Die aktuelle Position und die Geschwindigkeit führen zur neuen Position. Alle drei Variablen – Position pos, Geschwindigkeit v und Beschleunigung acc – lassen sich in Processing am besten über die Klasse PVector abbilden.
Betrachten wir zunächst einen Regentropfen, der einfach nur zu Boden fällt. Der Tropfen soll am oberen Rand der Grafik mit einer Geschwindigkeit von 0 starten. Die Beschleunigung ist ein fester Wert. Sobald der Tropfen unten aus der Grafik „herausfällt“, setzen wir seine Werte zurück. Der Tropfen startet also wieder oben, an einer zufälligen Position, mit der Geschwindigkeit 0. Da wir mit Vektoren arbeiten, können wir die neue Position und die neue Geschwindigkeit
bequem ausrechnen, indem wir Vektoren über die Funktion add() addieren.
Eine Klasse für Partikel
In einem richtigen Partikelsystem wollen wir mehrere Teilchen auf einmal beobachten. Wir könnten einfach verschiedene Arrays anlegen, die für sich jeweils Position, Geschwindigkeit und Beschleunigung speichern. Da es hier aber um feste Eigenschaften eines einzelnen Teilchens bzw. Objektes geht, können wir besser eine eigene Klasse für unser Partikel p anlegen. Alle nötigen Werte und Funktionen, die sich rund um ein einzelnes Partikel drehen, wandern in die neue Klasse Particle. Innerhalb der Klasse sorgt Particle() dafür, dass ein neues Partikel mit den Grundwerten angelegt wird. Über die update()- Funktion ändern wir die Werte des Partikels.
Das komplette Programm finden Sie auf der DVD ( teil4_02). Falls Sie noch nie mit Klassen gearbeitet haben: Auf processing.org gibt es eine ausführlichere Erklärung zum Thema Klassen und Objekte ( bit.ly/2C7RE2U).
Mehrere Partikel in der Praxis
Dank der neuen Klasse können wir nun beliebig viele Partikel erschaffen. Für ein umfangreicheres Projekt würden Sie vermutlich noch eine Klasse für das gesamte Partikelsystem schreiben und mit einer ArrayList arbeiten ( bit.ly/34tqZth). Aus Platzgründen nutzen wir im Folgenden lediglich ein Array mit Objekten der Klasse Particle. Für das nächste Beispiel verteilen wir 300 Partikel. Für jedes Partikel setzen wir einen zufälligen Winkel an. Mit der Funktion PVector.fromAngle() können wir den Winkel direkt in einen Vektor umwandeln. Dieser Vektor hat eine Länge von 1, mit .mult() ändern wir diese Länge auf einen Wert zwischen 300 und 400. Effektiv verteilen wir damit alle Partikel in einer Kreisform rund um den Mittelpunkt der Grafik. Im setup() ändern wir das Farbschema auf den HSBFarbraum und können den Winkel gleich auch als Wert für die Farbe des Partikels nutzen. Die Beschleunigung geht immer in Richtung des Mittelpunktes. Damit sich die Partikel nicht zu schnell bewegen, normalisieren wir den Vektor acc über .normalize() – damit wird die Länge des Vektors auf 1 gesetzt. Außerdem malen wir in jedem Frame ein halbtransparentes Rechteck über die gesamte Fläche. Das führt dazu, dass die Partikel „nachleuchten“(siehe Abbildung).
Durch die Beschleunigung wird die Geschwindigkeit immer größer, sodass die Partikel in der Nähe des Zentrums deutliche Sprünge machen. Wenn Sie eine gleichmäßigere Bewegung erhalten möchten, könnten Sie die Beschleunigung zwar einsetzen, um die Richtung der Geschwindigkeit zu ändern. Im Anschluss sorgen Sie aber über v.normalize() oder v.limit() dafür, dass die Geschwindigkeit einen bestimmten Wert nicht überschreitet. So können Sie zusammenhängende Linien zeichnen.
Ein Flow Field mit Perlin Noise
Beim Regen haben wir eine feste Beschleunigung nach unten angesetzt. Im letzten Beispiel zeigte die Beschleunigung immer in die Mitte. Spannendere Muster erhalten
Sie, wenn Sie ein sogenanntes Flow Field einsetzen. Als Basis dient dabei zweidimensionaler Perlin Noise (siehe Teil 3 in der letzten Ausgabe). Perlin Noise erzeugt an jedem Punkt einen Wert zwischen 0 und 1. Wir können diesen Wert mit 360 multiplizieren, um daraus wieder per .fromAngle() einen Richtungsvektor abzuleiten, den wir für die Beschleunigung verwenden. Dabei sollten Sie aber beachten, dass Perlin Noise eher Werte um 0,5 herum erzeugt. Daraus erzeugte Vektoren zeigen dementsprechend bevorzugt nach links. Wenn Sie eine andere Richtung benötigen, können Sie die Vektoren über .rotate() drehen.
Im folgenden Beispiel gehen wir von 2.000 Partikeln aus, die zufällig in einem Kreis in der Mitte der Grafik verteilt werden. Die Anfangsgeschwindigkeit setzen wir auf 0. Für jedes Teilchen ermitteln wir anhand der aktuellen Position und einer Zeit-Komponente den Perlin Noise und wandeln diesen Wert in einen Vektor für die Beschleunigung um. Außerdem sehen wir für jedes Partikel ein Lebensalter vor, das bei 0 beginnt und langsam heraufgezählt wird. Bei einem Wert von 255 setzen wir das Partikel wieder auf einen neuen Punkt innerhalb des
Ausgangskreises zurück. Das Lebensalter bewegt sich also von 0 bis 255, so dass wir den Wert als Graustufe benutzen können.
void update() { noise_x = pos.x * 0.01; noise_y = pos.y * 0.01; float noise_angle = noise(noise_x,
noise_y, noise_z)*360; acc = PVector.
fromAngle(radians(noise_angle)); v.add(acc); v.normalize(); pos.add(v); fill(age); circle(pos.x, pos.y, 1); age++; if (age == 255) {
reset(); } } }
Das Ergebnis sieht zwar schon einigermaßen interessant aus, aber so richtig überzeugend ist es noch nicht. Es fehlt eine gewisse ästhetische Qualität. Tatsächlich haben wir nun aber alle Grundvoraussetzungen, um mit vielen Partikeln in einem Flow Fields eine ansprechende Animation zu programmieren. Wie in vielen anderen
Fällen, gilt es auch hier, selbst kreativ zu werden und verschiedene Ideen auszuprobieren bzw. mit den Parametern zu spielen. Sie können zum Beispiel die Anfangsposition der Teilchen auf bestimmte Gebiete beschränken. Die Partikel könnten verschiedene Startgeschwindigkeiten erhalten. Statt mit einem Flow Field zu arbeiten, könnten Sie Punkte vorgeben, die ähnlich zu Planeten ein Gravitationsfeld für die Partikel erzeugen. Partikel könnten eine Farbe bekommen, die im Laufe der Bewegung verblasst – wie beim Titelbild. Sie können Symmetrien bilden oder Teilchen miteinander kollidieren lassen. Je nachdem, was Sie sich hier ausdenken, können Ihre Partikelsysteme völlig unterschiedliche Grafiken erzeugen. Auf der beiliegenden DVD finden Sie ein paar einfache Varianten von unserem bisherigen Programm. Für weitere Experimente bietet die Website openprocessing.org eine gute Inspirationsquelle. Dort können Sie auch gleich die entsprechenden Quellcodes einsehen bzw. kopieren.