Marek Slipek
Gestalten mit Processing


Gestalten mit Processing

Programmieren ist eine Kulturtechnik wie Schreiben, Sprechen oder Zeichnen. Sie hat ihre eigenen Regeln und eine innere Logik. Programmieren ist kein Programm und somit keine Anwendung. Vielmehr können wir mit Programmieren selbst Anwendungen und Programme schreiben, die uns die größtmöglichen kreativen Freiheitsgrade in digitaler Gestaltung erlauben. Wir sind nicht an die Algorithmen von Softwareschmieden gebunden, deren Parameter wir lediglich bedienen. Wir können unsere eigenen Algorithmen schreiben. Dazu verfassen wir Texte, die von einer Maschine "dem Computer" gelesen und ausgeführt werden. Auf diese Art kommunizieren wir mit der Maschine.

Processing ist eine grafisch orientierte Programmierumgebung auf Opensource-Basis, speziell für Künstler und Gestalter entwickelt. Es handelt sich um ein digitales Skizzenbuch mit dem wir generative und interaktive Ideen schnell entwickeln, testen und variieren können. Die Sprache ist vergleichsweise einfach zu erlernen und bietet einen guten Einstieg in die Welt der Programmierung. Die Prinzipien aller Programmiersprachen sind ähnlich und lassen sich übertragen. Programmieren besteht aus Daten und Methoden. Für grafisch orientiertes Programmieren erfassen wir beispielsweise Daten in Form von Koordinaten und Abmessungen von Punkten, Linien, Kreisen, Quadraten. Wir verwenden Methoden um bespielsweise diese Formen zu zeichnen.

Dieser Kurs besteht aus neun Einheiten und hat zum Ziel algorithmische Buchstabenbilder zu entwicklen und zu gestalten. Davon ausgehend können wir die zur Grafik gewordenen Buchstaben als PDFs exportieren und in Illustrator zu Plakaten arrangieren. Anhand des Ziels generative Typobilder zu erstellen, lernen wir die meisten grundlegenden Prinzipien einer Programmiersprache kennen. Jede Lerneinheit enthält Beispielcodes, die wir direkt in Processing hineinkopieren und testen können. Die Beispielcodes dienen als Grundlage für die Aufgaben jeder Lerneinheit.

 Variable
 Rechnen
 Aufbau
 Grundform
 Einfachschleife
 Doppelschleife
 Rauschen
 Buchstabe
 Export


Variable

Methoden und Parameter

size(800, 800);
println ("Hallo Welt");
ellipse (400, 400, 500, 500);

Datentypen

Ganze Zahl
int

Zahl mit Nachkommastelle
float

true oder false
boolean

Einzelner Buchstaben
char

Wort oder Satz
String

Daten in Variablen speichern

float katzen;
katzen = 12;

float hunde = 3;
float maeuse = 10;
float tiere;

tiere = katzen + hunde + maeuse;

println ("Tiere: " + tiere);

Variablen verschiedenen Datentyps

int stueckzahl = 12;
float menge = 2.1;
boolean pendel = true;
char initiale = 'T';
String wort = "Thorsten";

println("Obst: " + stueckzahl);
println("Wasser: " + menge + " Liter");
println("Wahrsager: " + pendel);
println("Anfangsbuchstabe: " + initiale);
println("Vorname: " + wort);

Warmup

Kopiere die mitgelieferten Beispielcodes "Methoden und Parameter", "Daten in Variablen speichern" und "Variablen verschiedenen Datentyps". Teste jedes der drei Programme mit unterschiedlichen Variablenwerten und Variablennamen. Starte bei jeder Veränderung eines Variablenwertes und Variablennamens das Programm neu.

Variable / Aufgabe 1

Erstelle ein neues Programm mit zwei Variablen des Datentyps String – eine für den Vornamen und eine weitere für den Nachnamen. Erstelle eine dritte Variable des Datentyps String für den Gesamtnamen. Addiere den Vornamen und den Nachnamen und speichere das Ergebnis im Gesamtnamen. Lass dir den Inhalt des Gesamtnamens im Kontrollfenster anzeigen. Drücke dazu den Play-Button im Processingfenster links oben - damit startest du das Programm. Es wird Zeile für Zeile ausgeführt. Nach Ausführung der letzten Zeile stoppt das Programm automatisch.

Variable / Aufgabe 2

Erstelle ein neues Programm mit einer Variable des Datentyps boolean – die Variable soll den Namen kristallkugel tragen. Weise der Variable den Wert true zu. Lass dir den Inhalt von kristallkugel im Kontrollfenster anzeigen. Weise der Variable den Wert false zu. Lass dir den Inhalt der Variable erneut im Kontrollfenster anzeigen. Die Lösung der Aufgabe muss vier Zeilen umfassen.

Variable / Aufgabe 3

Definiere drei Variablen des Datentyps int mit den Variablennamen a, b und division. Weise der Variable a den Wert 11 und der Variable b den Wert 2 zu. Dividiere a durch b und speichere das Ergebnis in division. Lass dir den Inhalt der Variable division im Kontrollfenster anzeigen. Warum produziert dieses Programm ein falsches Ergebnis ?

Variable / Aufgabe 4

Definiere mehrere Variablen des Datentyps float mit den Variablennamen a, b, summe, differenz, multiplikation und division. Weise a und b jeweils einen Variablenwert zu. Addiere a mit b und speichere das Ergebnis in der Variable summe. Subtrahiere b von a und speichere das Ergebnis in der Variable differenz. Multipliziere a mit b und speichere das Ergebnis in der Variable multiplikation. Das Zeichen fürs Multiplizieren ist ein Stern. Teile a durch b und speichere das Ergebnis in der Variable division. Das Zeichen fürs Teilen ist ein Schrägstrich den du am Mac mit SHIFT + 7 erzeugst. Lass dir nach den Berechnungen alle Variablenwerte inklusive a und b im Kontrollfenster anzeigen. Beschrifte hierzu mit der Methode println jeden Variablenwert mit vorangestelltem Text.

Variable / Aufgabe 5

Du hast in Aufgabe 4 die Minimalversion eines Taschenrechners erstellt. Verändere die Werte von a und b und starte das Programm jeweils neu.

Variable / Aufgabe 6

Entwerfe auf Grundlage des bisherigen Inputs eine eigene Idee und formuliere diese als Programm.

Handshake

Daten speichern wir in Variablen. Um unterschiedliche Daten zu erfassen, stehen uns in Processing verschiedene Datentypen zur Verfügung: int für ganze Zahlen, float für Nachkommazahlen, String für Wörter, char für Buchstaben, boolean für einen Zustand der wahr oder falsch sein kann. Um eine Variable in Processing zu verwenden, müssen wir diese zuerst dem Computer mit einem Handshake vorstellen. Dazu nennen wir zuerst den Datentyp, den die Variable haben soll und fügen durch ein Leerzeichen getrennt einen frei wählbaren Variablennamen hinzu. Jede Zeile in Processing schließen wir mit einem Semikolon ab, was einem Punkt in der geschriebenen klassischen Sprache entspricht.

Zuweisen

Daten bestehen aus Werten. Um einen Wert in einer Variable zu speichern brauchen wir ein Gleichheitszeichen: Links des Gleichheitszeichens schreiben wir den Variablennamen und rechts davon einen Wert. Dies bezeichnet man als Zuweisen. Der Wert kann eine Zahl, ein Wort, ein Buchstabe oder ein Zustand sein. Es hängt davon ab, welchen Datentyp wir für unseren Variablennamen zuvor gewählt haben.

Rechnen

Wir können rechts des Gleichheitszeichens statt eines Wertes ebenfalls Variablen hinschreiben und diese durch Grundrechenarten zu einem mathematischen Ausdruck verbinden. In einem laufenden Program werden die Variablen auf der rechten Seite durch den Wert der ihnen zuvor zugewiesen wurde ersetzt. Das passiert unsichtbar im Hintergrund. Stehen bleibt ein mathematischer Ausdruck der berechnet wird und als neuer Wert der Variable auf der linken Seite zugewiesen wird. Im Beispiel wird die Anzahl von Katzen, Hunden und Mäusen in der Variable Tiere gespeichert.

Methoden und Parameter

Mit der Methode ellipse zeichnen wir einen Kreis auf eine Zeichenfläche. Mit der Methode println lässt sich der Wert einer Variable im schwarzen Kontrollfenster von Processing anzeigen. Wir übergeben an eine Methode Parameter durch ein Komma getrennt und durch runde Klammern zusammengefasst. Die Methode ellipse braucht vier Parameter. Die Reihenfolge gibt deren Deutung vor. Der erste Parameter ist der x-Wert der Ellipse, der zweite der y-Wert, der dritte die Ellipsenbreite und der vierte die Ellipsenhöhe. Bei der Methode println übergeben wir Text oder Variablen als Parameter, Text in Anführungszeichen, Variablen ohne. Variablen und Text kombinieren wir durch ein Pluszeichen. Das Pluszeichen klebt – ohne Leerzeichen - den Wert der Variable unmittelbar an den Text im Kontrollfenster.

Weiterführende Themen

Ein Array ist die nächsthöhere Organisationseinheit für Variablen. Mehrere Variablen können in einem sogenanntem Feld gespeichert werden. In Verbindung mit Schleifen, die du bald kennenlernen wirst, kannst du Daten in einem Array auf eine effiziente Art speichern und wieder abrufen.

 zurück zur Übersicht 


Rechnen

Parameteraddition

size(800, 800);
int radius = 250;
int mitteX = 400;
int mitteY = 400;
noFill();
ellipse (mitteX, mitteY, radius, radius);
ellipse (mitteX, mitteY, radius + 250, radius + 250);

Variablenaddition

size(800, 800);
int radius = 250;
int mitteX = 400;
int mitteY = 400;
noFill();
ellipse (mitteX, mitteY, radius, radius);
radius = radius + 250;
ellipse (mitteX, mitteY, radius, radius);

Relativ statt Absolut

int x = 50;
int y = 50;
line (x, y, x + 20, y - 20);

Grundrechenarten

Variablenaddition
radius = radius + 1;

Variablensubtraktion
radius = radius - 1;

Variablendivision
radius = radius / 4;

Variabelenmultiplikation
radius = radius * 4;


Parameteraddition
ellipse(400, 400, radius + 1, radius + 1);

Parametersubtraktion
ellipse(400, 400, radius - 1, radius - 1);

Parameterdivision
ellipse(400, 400, radius / 4, radius / 4);

Parametermultiplikation
ellipse(400, 400, radius * 4, radius * 4);


Codebeispiel
int radius = 7;
radius = radius + 1;
radius = radius * 4;
println("radius " + radius);

Warmup

Kopiere die mitgelieferten Beispielcodes "Parameteraddition", Variablenaddition" und "Variablenaddition und Division". Teste jedes der drei Programme mit unterschiedlichen Variablenwerten. Starte bei jeder Veränderung eines Variablenwertes das Programm neu.

Rechnen / Aufgabe 1

+

-

Verwende drei Variablen, um einen Kreis zu zeichnen: eine für den Kreisradius radius, eine für x-Position mitteX und eine für die y-Position der Kreismitte mitteY.

Erstelle mit der Methode size eine 800 mal 800 Pixel große Zeichenfläche. Definiere drei Variablen des Datentyp float – eine für den Kreisradius mit dem Namen radius, eine für die x-Position der Kreismitte mit dem Namen mitteX und eine für die y-Position des Kreismitte mit dem Namen mitteY. Weise mitteX, mitteY und radius jeweils den Variablenwert 400 zu. Verwende die Methode noFill um vom folgenden Kreis nur die Outline zu zeichnen. Verwende die Methode ellipse mit den erstellten Variablen als Parameter, um einen Kreis auf der Zeichenfläche zu zeichnen.

Rechnen / Aufgabe 2

+

-

Erweitere Aufgabe 1. Zeichne einen weiteren Kreis links und einen weiteren rechts vom ersten. Verwende dazu eine weitere Variable für den Abstand zwischen zwei Kreisen mit dem Namen abstand und eine Parameteraddition sowie eine Parametersubtraktion.

Erweitere Aufgabe 1. Zeichne einen zweiten Kreis rechts vom ersten Kreis mit der Methode ellipse und einer Parameteraddition – verändere die Kreisposition um 150 Pixel. Zeichne einen dritten Kreis links vom ersten Kreis mit der Methode ellipse und einer Parametersubtraktion – verändere die Kreisposition ebenfalls um 150 Pixel.

Rechnen / Aufgabe 3

+

-

Erweitere Aufgabe 2. Zeichne einen weiteren Kreis oben und einen weiteren unten. Verwende dazu die Variable abstand und erneut eine Parameteraddition sowie eine Parametersubtraktion.

Erweitere Aufgabe 1. Erstelle eine neue Variable des Datentyps float für den Abstand zwischen zwei Kreisen mit dem Variablennamen abstand. Weise der Variable abstand den Variablenwert 150 zu. Ersetze in der Parameteraddition den konstanten Wert – um den du den zweiten Kreis nach links verschoben hast – durch die Variable abstand. Ersetze bei deinem dritten Kreis in der Parametersubtraktion den konstanten Wert ebenfalls durch die Variable abstand. Zeichne einen vierten Kreis oberhalb des mittleren Kreises – verwende dazu die Methode ellipse, eine Parametersubtraktion und die Variable abstand. Zeichne einen fünften Kreis unterhalb des mittleren Kreises – verwende dazu die Methode ellipse, eine Parameteraddition und ebenfalls die Variable abstand.

Rechnen / Aufgabe 4

Du hast in Aufgabe 3 deine erste minimalistische generative Grafik erstellt. Die Regel ordnet die fünf Kreise in einem Kreuzmuster gleichabständig an. Der Abstand zwischen zwei Kreisen ist der Parameter, der deiner Grafik eine Varianz verleiht. Teste den Abstand zwischen zwei Kreisen mit verschiedenen Werten für die Variable abstand und starte das Programm jeweils neu.

Rechnen / Aufgabe 5

Erstelle ein neues generatives Muster nach dem gleichen Prinzip. Verwende einen Kreis als Ursprungselement und bestimmte die Position der nachfolgenden Kreise mit Parameterveränderungen.

Variable mit Selbstbezug

Bisher haben wir so gerechnet, dass wir auf der rechten Seite des Gleichheitszeichens andere Variablen hatten als auf der linken Seite. Wir können den Wert einer Variable auch in der Art verändern, dass wir die Variable von der linken Seite des Gleichheitszeichen auf der rechten Seite wiederholen und dieser beispielsweise einen Wert hinzu addieren, subtrahieren, durch einen Wert teilen oder mit einem Wert multiplizieren. In diesem Fall wird die Variable in einem laufenden Programm auf der rechten Seite durch einen Wert ersetzt, den wir ihr zuvor zugewiesen haben. Auf der rechten Seite bleibt danach ein mathematischer Ausdruck stehen, der berechnet wird und der Variable auf der linken Seite zugewiesen wird. Der neue Wert überschreibt den alten Wert.

Parameteraddition und Variablenaddition

Verändern wir den Wert einer Variable durch ein Gleichheitszeichen mit einer der vier Grundrechenarten, so sprechen wir von Variablenaddition, Variablensubtraktion, Variablendivision oder Variablenmultiplikation. Verändern wir einen Parameter in einer Methode mit einer der Grundrechenarten, so sprechen wir von Parameteraddition, Parametersubtraktion, Parameterdivision oder Parametermultiplikation. Wenn wir also als Parameter einer Methode eine Variable einsetzen und diese durch eine Grundrechenart verändern, so bleibt der Wert der Variable unverändert. Im laufenden Programm wird die Variable durch einen Wert ersetzt, der ihr zuvor zugewiesen wurde. Es bleibt ein mathematischer Ausdruck stehen der zusammengerechnet wird, jedoch wird das Ergebnis nicht in einer Variable gespeichert, da hier das Gleichheitszeichen fehlt. Eine Parameterrechnung wirkt demnach punktuell in einer Methode wie beispielsweise ellipse, eine Variablenrechnung wirkt dagegen nachhaltig, indem sich der Wert der Variable ändert.

 zurück zur Übersicht 


Aufbau

Linear

int x = 50;
size(100, 100);
background(255);
noFill();
ellipse (x, 50, 75, 75);

noLoop

int x = 50;

void setup() {
  size(100, 100);
  background(255);
  noLoop();
}

void draw() {
  noFill();
  ellipse (x, 50, 75, 75);
}

Loop

int x = 50;

void setup() {
  size(100, 100);
  background(255);
}
void draw() {
  noFill();
  ellipse (x, 50, 75, 75);
}

Warmup

Kopiere den Code von "Linear" und starte das Programm. Kopiere den Code von "noLoop". Verwende die Tastenkombination APFEL + T, um den Code automatisch mit Tabulatoren einzurücken und aufzuräumen. Starte das Programm. Kopiere den Code von "Loop", verwende APFEL + T und starte das Programm. Siehst du den Unterschied in der Darstellung des Kreises in "Loop" im Vergleich zu den anderen beiden Codes "noLoop" und "Linear" ? In "Loop" wird der Kreis unendlich oft übereinander gezeichnet – solange das Programm läuft.

Aufbau / Aufgabe 1

Kopiere den Code von "Loop". Füge nach der Methode ellipse – jedoch vor der schließenden geschweiften Klammer – eine neue Zeile ein: Wende eine Variablenaddition auf die Variable x an – erhöhe dazu den Wert der Variable x um 5. Starte das Programm.

Aufbau / Aufgabe 2

Kopiere den Code von "noLoop". Füge analog zu Aufgabe 1 eine Variablenadditon für die Variable x hinzu. Starte das Programm.

Aufbau / Aufgabe 3

Verwende den modifizierten Code aus Aufgabe 1. Lösche die Methode background aus dem setup-Bereich und füge sie als erste Zeile in den draw-Bereich ein; nach der sich öffnenden geschweiften Klammer und vor noFill . Starte das Programm – Das ist der Animations- und Interaktionsmodus.

Koordinatensystem

Unsere Zeichenfläche in Processing besteht aus einem Koordinatensystem mit einer x-Achse und einer y-Achse. Die y-Achse wird in der Informatik im Gegensatz zur Mathematik umgedreht verwendet, mit positiven Zahlen im unteren Bereich und negativen Zahlen im oberen Bereich. Mit der Methode size legen wir die Größe unserer Zeichenfläche fest, mit der Methode background die Hintergrundfarbe.

Standbild und Interaktionsmodus

Die meisten Beispiele dieser Lektionen verwenden einen vereinfachten linearen Aufbau, der für die Erzeugung von Standbildern genügt. Hierbei arbeitet sich das Programm von der obersten bis zur untersten Zeile durch und bleibt danach stehen. Bei interaktiven Projekten und beim Einsatz von externen Bibliotheken brauchen wir einen interaktiven Modus. Dieser Modus besteht aus einem setup-Bereich und einem draw-Bereich. Beide Bereiche werden mit dem Schlüsselwort void gekennzeichnet. Der setup-Bereich läuft zu Beginn einmal durch und enthält allgemeingültige Voreinstellungen. Danach folgt der draw-Bereich, dessen Inhalt dauerhaft wiederholt wird, beispielweise um die Mausposition zu ermitteln. Wir können den Loop des draw-Bereichs mit der Methode noLoop im setup-Bereich unterbinden. Der interaktive Modus verhält sich in diesem Fall wie der lineare Modus.

 zurück zur Übersicht 


Grundform

Punkt

size(800, 800);
float px = 400;
float py = 400;
strokeWeight(3);
point (px, py);

Linie

size(800, 800);
float ax = 150;
float ay = 400;
float bx = 650;
float by = 400;
line (ax, ay, bx, by);

Kreis

size(800, 800);
float mitteX = 400;
float mitteY = 400;
float breite = 500;
float hoehe = 500;
ellipse (mitteX, mitteY, breite, hoehe);

Kreisbogen

size(800, 800);
float mitteX = 400;
float mitteY = 400;
float breite = 500;
float hoehe = 500;
float start = radians(0); // Startwinkel
float ende = radians(270); // Endwinkel
arc (mitteX, mitteY, breite, hoehe, start, ende);

Rechteck

size(800, 800);
float eckeX = 150;
float eckeY = 150;
float breite = 500;
float hoehe = 500;
rect (eckeX, eckeY, breite, hoehe);

Bezier

size(800, 800);
float ax = 200;
float ay = 600;
float bx = 200;
float by = 300;
float cx = 300;
float cy = 200;
float dx = 600;
float dy = 200;
bezier(ax,ay,bx,by,cx,cy,dx,dy);

Attribute

size (800, 800);
int radius = 200;
int mitteX = 400;
int mitteY = 400;
noFill();
stroke (0, 0, 255);
ellipse (mitteX, mitteY, radius*3, radius*3);
stroke (0, 255, 255);
ellipse (mitteX, mitteY, radius*2, radius*2);
stroke (255, 0, 255);
ellipse (mitteX, mitteY, radius, radius);

Attribute

Flächengraustufe 0 bis 255
fill(255);

Flächenfarbe(RGB) 0 bis 255
fill(0,0,255);

Keine Füllung
noFill();


Konturgraustufe 0 bis 255
stroke(0);

Konturfarbe(RGB) 0 bis 255
stroke(0,0,255);

Konturstärke 0.1 bis ...
strokeWeight(1);

Keine Kontur
noStroke();


Graustufentransparenz 0 bis 255
fill(255,100);

Farbtransparenz 0 bis 255
fill(0,0,255,100);

Warmup

Kopiere die mitgelieferten Beispielcodes. Teste jedes der Programme mit unterschiedlichen Variablenwerten und unterschiedlichen Attributen. Starte bei jeder Veränderung eines Variablenwertes oder Attributwertes das Programm neu.

Grundform / Aufgabe 1

Schreibe die Codebeispiele für Punkt, Linie, Kreis, Kreisbogen, Rechteck und Bezier um. Verwende ausschließlich Konstanten statt Variablen, um die verschieden Formen zu zeichnen. Lösche anschließend die verwendeten Variablen aus dem Code.

Grundform / Aufgabe 2a bis 2d

+

-

Zeichne vier verschiedene Linien von ihrem Mittelpunkt aus. Verwende für den Mittelpunkt die Variablen x und y. Bestimme die Eckpunkte der Linien relativ zum Mittelpunkt mit Parameteraddition und Parametersubtraktion.

Erstelle mit der Methode size eine 800 mal 800 Pixel große Zeichenfläche. Definiere zwei Variablen des Datentyp int mit den Variablennamen x und y. Weise der Variable x den Wert 400 zu. Weise der Variable y ebenfalls den Wert 400 zu. Verwende ausgehend von den Variablen x und y die Methode line sowie Parameteraddition beziehungsweise Parametersubtraktion, um jeweils eine Linie zu zeichnen.

Grundform / Aufgabe 3a und 3b

+

-

Erstelle einen Kreisbogen mit der Methode arc. Es gibt zwei Wege, die Winkel zu bestimmen, um die Aufgabe zu lösen.

Erstelle einen Kreisbogen mit der Methode arc. Beachte, dass 0° auf 3 Uhr liegt und Winkelangaben im Uhrzeigersinn ansteigen – dabei fällt 360° mit 0° zusammen. Es ist jedoch zum einen möglich, Winkelangaben größer als 360° anzugeben, zum anderen ist es möglich, negative Winkel anzugeben. Es gibt also zwei Wege die Aufgabe zu lösen. Führe beide Wege aus. Weiterhin ist es nicht notwendig, im Kopf zu rechnen – denn radians(360 + 90) führt zum selben Ergebnis wie radians(450).

Grundform / Aufgabe 4

+

-

Zeichne drei Kreise mit einem gemeinsamen Mittelpunkt. Verwende dazu drei Variablen radius, mitteX und mitteY. Zeichne zuerst den kleinen Kreis, dann den mittleren und zum Schluß den großen. Gib dem mittleren Kreis eine größere Strichstärke.

Erstelle eine 800 mal 800 Pixel große Zeichenfläche. Definiere drei Variablen des Datentyps float mit den Variablennamen mitteX, mitteY und radius. Weise den Variablen mitteX und mitteY jeweils den Variablenwert 400 zu. Weise der Variable radius den Wert 500 zu. Verwende die Methode noFill, um Konturen ohne Füllung zu zeichnen. Verwende die Methode ellipse mit den Variablen mitteX, mitteY und radius als Parameter, um einen Kreis zu zeichnen. Verwende eine Variablendivision für radius – teile dazu radius durch den Faktor 1.5 und weise das Ergebnis radius erneut zu. Kopiere die beiden zuletzt erstellten Anweisungen – Methode ellipse und die Variablendivision – zweimal um zwei weitere Kreise zu zeichnen. Stelle beim mittlerem Kreis eine andere Strichstärke ein.

Grundformen

Uns stehen verschiedene geometrische Grundformen als Methoden zur Verfügung wie Punkt, Linie, Kreis, Quadrat und andere. Jede Methode braucht eine andere Anzahl an Parametern, damit sie funktioniert. Ein Punkt braucht zwei Parameter, eine Ellipse vier. Bei manchen Methoden variiert die Anzahl. Die Methode fill färbt bei einem Parameter Objekte in Graustufen, bei drei Parametern Objekte in Farbe.

Attribute

Attribute beeinflußen Farbe, Strichstärke und Transparenz von Objekten. Mit fill färben wir die Füllung von Objekten, mit stroke die Kontur. Mit noFill entfernen wir die Füllung, mit noStroke die Kontur. Für Transparenz geben wir zusätzlich zur Farbe oder zur Graustufe einen weiteren Parameter an. Mit strokeWeight bestimmen wir die Strichstärke der Kontur. Generell sind bei Programmstart Attribute ohne unser weiteres Zutun voreingestellt. So ist der Hintergrund mittelgrau, Flächenfüllungen weiß und Konturen schwarz. Man kann sich die Attributsammlung als einen bunten Blumenstrauß vorstellen, der immer auf einmal wirkt. Ändern wir im Verlauf unseres Codes ein Attribut, verändern wir auch die Gesamtheit des Blumenstraußes: Die Wirksamkeit bleibt fortbestehen – bis zum Zeitpunkt einer erneuten Änderung. Attibutänderungen wirken sich immer nur auf nachfolgende Objekte aus, nicht auf vorhergehende. Man kann sich die Codezeilen wie Ebenen vorstellen, die aufeinander abgelegt werden. Je früher eine Zeile geschrieben wurde, desto weiter oben befindet sie sich.

Möchten wir beispielsweise drei Kreise in rot, grün und blau nebeneinander zeichnen, verwenden wir vor jeder neuen Methode ellipse jeweils einen neue Methode fill für jede neue Farbe. Zeichnen wir im Anschluss weitere Kreise ohne einen erneuten fill-Befehl, bleibt die zuletzt eingestellte Füllfarbe – bis wir diese erneut ändern.

Absolut und Relativ

Bei der Angabe von Koordinaten können wir zum einem zwischen Konstanten und Variablen unterscheiden, zum anderen zwischen absoluten Koordinaten und relativen Koordinaten. Absolute Koordinaten geben einen festen Ort an, entweder durch eine Konstante oder eine Variable. Relative Koordinaten geben einen zweiten Ort, der mit einem ersten verbunden ist. Verändern wir den ersten Ort, verändert sich der zweite automatisch mit. Ein gutes Beispiel dafür ist eine Linie die aus zwei Punkten besteht. Den ersten Punkt geben wir durch die Variablen x und y an. Den zweiten Punkt geben wir durch einen Parameterrechung an – beispielsweise eine Parameteraddition und -subtraktion. Mit x + 100 und und y - 100 zeichnen wir eine Diagonale, die in einem 45 Grad Winkel nach rechts oben verläuft. Ändern wir den ersten Punkt, indem wir die Werte von x und y verändern, wird der zweite Punkt automatisch berechnet. Relative Angaben sind effizient und ein grundlegendes Prinzip, um Zusammenhänge zwischen Objekten zu abstrahieren. Konstante Angaben entsprechen eher der händischen Arbeit, die wir aus den klassischen Grafikprogrammen kennen: Das kostet viel Zeit.

Weiterführende Themen

triangle(), curve(), vertex(), quad() sind weitere Zeichenmethoden, die du dir anschauen solltest. Insbesondere wenn du organisch wirkende und gebogene Formen erstellen möchtest, wirst du entweder die Methode curve() oder bezier() brauchen. Es lohnt sich aufwändige Zeichenformen einzusetzen, weil diese oft überraschendere Ergebnisse liefern.

 zurück zur Übersicht 


Einfachschleife

Schleifenarten

while-Schleife
int x = 40;
while (x <= 60) {
  point (x, 50);
  x = x + 10;
}

for-Schleife
for (int x = 40; x <= 60; x = x + 10) {
  point (x, 50);
}

Konzentrische Wiederholung

size(800, 800);
noFill();
float radius = 50;
while (radius < 600) {
  ellipse(400, 400, radius, radius);
  radius = radius + 50;
}

Horizontale Wiederholung

size(800, 800);
fill(0);
float radius = 8;
for (int x = 40; x <= 760; x = x + 40) {
  ellipse (x, 400, radius, radius);
}

Vertikale Wiederholung

size(800, 800);
fill(0);
float radius = 8;
for (int y = 40; y <= 760; y = y + 40) {
  ellipse (400, y, radius, radius);
}

Einfachschleife / Aufgabe 1a und 1b

Kopiere den Code "Konzentrische Wiederholung" und modifiziere ihn. Halbiere die Anzahl der Ringe in Aufgabe 1a. Verändere die Position und Anzahl deiner konzentrischen Kreissammlung in Aufgabe 1b.

Einfachschleife / Aufgabe 2a bis 2c

Kopiere den Code "Horizontale Wiederholung" und modifiziere ihn. Verdopple in der ersten Aufgabe den Abstand zwischen den Punkten. Halbiere in der zweiten Aufgabe den Abstand zwischen den Punkten. Verkürze in den dritten Aufgabe den Start- und Endpunkt der horizontalen Wiederholung.

Einfachschleife / Aufgabe 3a bis 3c

Verwende für Aufgabe 3a die Lösung aus Aufgabe 2c und modifiziere diese. Verschiebe in Aufgabe 3b deine vertikale Wiederholung nach links. Verschiebe in Aufgabe 3c deine vertikale Wiederholung nach rechts.

Einfachschleife / Aufgabe 4a bis 4d

+

-

Du kannst Aufgabe 4a aus den bisherigen Lösungen zusammenkopieren und in Position der Linien und Abstand der Punkte anpassen. Füge in Aufgabe 4b zusätzlich zu der Lösung in Aufgabe 4a unterschiedliche Radien für deine Kreispunkte – der Kreisradius verdoppelt sich von Linie zur Linie.

Verwende für Aufgabe 4a die Lösung aus Aufgabe 3c und modifiziere diese. Verschiebe in Aufgabe 4b deine vertikale Wiederholung nach links. Verschiebe in Aufgabe 3c deine vertikale Wiederholung nach rechts.

Einfachschleife / Aufgabe 5a und 5b

+

-

In Aufgabe 5a brauchst du neben der einfachen Schleife für die Position der Linie eine zusätzliche Variable für die Höhe der Linie. Dreh den Höhenverlauf in Aufgabe 5b um.

In Aufgabe 5a brauchst du neben der einfachen Schleife für die Position der Linie eine zusätzliche Variable für die Höhe der Linie. Erstelle dazu einen "Handshake" für die Variable hoehe mit dem Datentyp float. Zeichne die Linien von unten nach oben und von links nach rechts. Verwende eine einfache Schleife mit der Variable x, um die x-Koordinate des Anfangspunktes der Linie zu bestimmen. Die y-Koordinate bleibt konstant. Bei einer Zeichenfläche von 800 mal 800 Pixeln würde die y-Koordinate 800 betragen. Den Endpunkt der Linie bestimmst du relativ zum Anfangspunkt mit Hilfe einer Parametersubtraktion. Du subtrahierst dazu die Variable hoehe. Nun musst du noch innerhalb der Schleife mit einer Variablensubtraktion den Wert der Variable Höhe verändern.

Schleife

Mit bereits drei Zeilen Code können wir eine unzählbare Menge an Elementen mit einer Schleife erzeugen. Es ist offensichtlich, dass sich hier die eigentliche Stärke von Processing zeigt. Um ein Element zu wiederholen, definieren wir einen Parameter des Elements als Variable. Die Wiederholung bezieht sich auf den Wert dieser Variable. Der Wert hat einen Anfangspunkt, einen Endpunkt und eine Schrittweite. Die Schrittweite entscheidet, wie viele Elemente erzeugt werden, bis der Endpunkt erreicht wird. Die Schrittweite wird meistens mit einer Variablenaddition angegeben. Eine Schleife hat eine Abbruchbedingung, die ihr Ende bewirkt. Dabei wird der aktuelle Wert der Variable mit dem Endwert in einer Bedingung verglichen. Meistens vergleicht die Bedingung, ob der aktuelle Wert der Variable den Endwert erreicht. Solange das Ergebnis der Bedingung wahr ist, wiederholt die Schleife ihren Inhalt.

Struktur

Innerhalb eines linearen Aufbau eines Programm bewirkt eine Schleife, dass bestimmte Teile unseres Codes in einer geordneten Zahl wiederholt werden. Wiederholt wird, was sich im Schleifenkörper befindet. Geschweifte Klammern markieren dabei eine oder mehrere Zeilen. Der Schleifenkopf bestimmt die Anzahl der Wiederholungen. Den Schleifenkopf erkennen wir an der Methode for.

 zurück zur Übersicht 




Doppelschleife

Horizontale Wiederholung

size(800, 800);
fill(0);
float radius = 8;
for (int x = 40; x < 800; x = x + 40) {
  ellipse (x, 400, radius, radius);
}

Horizontale Laufvariable

size(800, 800);
fill(0);
float radius = 2;
for (int x = 40; x < 800; x = x + 40) {
  ellipse (x, 400, radius, radius);
  radius = radius + 2;
}

Muster

size(800, 800);
fill(0);
size(800, 800);
float radius = 8;
for (int x = 40; x < 800; x = x + 40) {
  for (int y = 40; y < 800; y = y + 40) {
    ellipse (x, y, radius, radius);
  }
}

Flächenlaufvariable

size(800, 800);
fill(0);
float radius = 2;
for (int x = 40; x < 800; x = x + 40) {
  for (int y = 40; y < 800; y = y + 40) {
    ellipse (x, y, radius, radius);
    radius = radius + 0.1;
  }
}

Doppelschleife / Aufgabe 1a bis 1c

Kopiere den Code "Muster". Verdopple in Aufgabe 1a die Punktabstände sowohl in horizontaler als auch in vertikaler Richtung. Halbiere in Aufgabe 1b die Punktabstände sowohl in horizontaler als auch in vertikaler Richtung. Verändere in Aufgabe 1c Start- und Endwerte des Musters.

Doppelschleife / Aufgabe 2a und 2c

Kopiere den Code "Muster". Verdopple in Aufgabe 2a die Punktabstände in vertikaler Richtung. Verdopple in Aufgabe 2b die Punktabstände in horizontaler Richtung. Verwende in 2c die doppelte Schleife um den Anfangspunkt der Linie zu bestimmen. Den Endpunkt der Linie bestimmst du relativ zum Anfangspunkt mit einer Parameteraddition und Parametersubtraktion.

Doppelschleife / Aufgabe 3

+

-

Kopiere den Code "Flächenlaufvariable" und verändere den Verlauf in die entgegengesetzte Richtung. Finde dazu mit der Methode println heraus, welchen Wert die Variable radius am Ende des Programms hat.

Kopiere den Code "Flächenlaufvariable" und verändere den Verlauf in die entgegengesetzte Richtung. Um das zu erreichen könntest du zunächst herausfinden welchen Wert die Variable radius am Ende des Programms hat - füge dazu als letzte Zeile die Methode println mit der Variable radius als Parameter hinzu. Verwende den so ermittelten Wert als Startwert für die Variable radius. Wandle die Variablenaddition in eine Variablensubtraktion um.

Doppelschleife / Aufgabe 4

+

-

Kopiere den Code "Muster". Zeichne Kreise statt Punkte. Füge drei Laufvariablen rot, gruen und blau hinzu. Verwende die neuen Laufvariablen um deine Kreise mit einer Verlaufsfarbe zu füllen. Achte darauf, dass der Endwert deiner Laufvariablen 255 nicht übersteigt oder 0 nicht unterschreitet.

Kopiere den Code "Muster". Zeichne Kreise statt Punkte. Erstelle zunächst "Handshakes" für drei Laufvariablen rot, gruen und blau. Verwende dabei als Datentyp "float". Weise diesen Laufvariablen zunächst den Startwert 0 zu. Erhöhe innerhalb der Schleife mit einer Variablenaddition für jede der drei Laufvariablen ihren Wert. Du kannst hier durchaus sehr geringe Werte mit Nachkommastellen wählen wie zum Beispiel 0.2 oder 0.05. Das hängt ganz davon ab wie schnell sich ein Farbanteil verändern soll. Wichtig ist, das du für jede Laufvariable einen anderen Wert wählst, damit sich Farbe überhaupt bilden kann. Bei gleichen Wert für alle drei Laufvariablen würdest du lediglich Graustufen erzeugen. Bevor du die Methode ellipse anwendest, legst du mit der Methode fill und den den drei Laufvariablen die Farbe deines Kreises fest.

Du kannst den Farbverlauf eines Farbanteils umgekehrt anlegen. Als Startwert wählst du dafür 255 und erniedrigst innerhalb der Schleife die Laufvariable mit einer Variablensubtraktion. Die besten Ergebnisse bekommst du mit einer Mischung aus Laufvariablen mit aufsteigender und absteigender Wertveränderung.

Ein Farbanteil sollte weder den Wert 255 übersteigen noch den Wert 0 unterschreiten. Befindet sich ein Farbanteil außerhalb des Bereichs erzeugt die Methode fill zwar keinen Fehler, jedoch produziert sie auch keine Farbe mehr. Stattdessen sehen wir, dass die Farbe weiss oder schwarz verbleibt. Um den Wert zu überprüfen, den die Laufvariablen annehmen, fügst du die Methode println hinzu und wählst als Parameter den Namen der Laufvariable.

Doppelschleife / Aufgabe 5

+

-

Erweitere Aufgabe 4. Füge den Kreisen Transparenz und eine farbige Outline hinzu. Verändere mit Laufvariablen Kreisbreite, Kreishöhe, Strichstärke, Transparenz und Farbe während des Schleifenaufbaus. Verwende Variablen absichtlich in einem anderen Kontext oder in einer anderen Reihenfolge als vorgesehen: statt fill(rot, gruen, blau) kannst du fill(gruen, blau, rot) schreiben oder strokeWeight(gruen) verwenden. Fang an zu experimentieren. Achte dabei welche Werte deine Laufvariablen minimal und maximal annehmen.

Erweitere Aufgabe 4. Nimm dir eine der Variablen rot, gruen oder blau vor. Drehe den Farbverlauf um. Weise der Variable zunächst den Wert 255 zu und verwende für diese Variable statt einer Variablenaddition eine Variablensubtraktion.

Füge für den Radius deiner Kreises erneut eine Variablenaddition hinzu, damit sich die Größe deiner Kreise in der Schleife verändert. Füge der Methode fill einen vierten Wert hinzu, um Transparenz bei deinen Kreisen zu erzeugen.

Fang jetzt nach folgendem Schema an zu experimentieren: Erstelle eine neue Regel. Dazu machst du vor der Schleife einen "Handshake" für eine neue Variable. Innerhalb der Schleife veränderst du den Wert deiner Variable zum Beispiel durch eine Variablenaddition. Du suchst dir nun einen absoluten Parameter in einer Methode innerhalb der Schleife. Diesen absoluten Wert ersetzt du durch deine neue Variable. Alternativ fügst du einem bestehenden Parameter durch einer der Grundrechenarten deine Variable hinzu.

Eine Regel könnte auch etwa so aussehen: Du fügst deinen Kreisen in der Schleife eine Outline mit stroke hinzu und machst sie transparent. Mit der Methode strokeWeight und dem Wert 15 machst du aus deiner Outline eine zusätzliche Fläche. Nun möchtest du für deine Outline einen anderen Farbverlauf wie für deine Füllung. Nimm einfach deine Variablen rot, gruen und blau und setze diese in deine Methode stroke innerhalb der Schleife in anderer Reihenfolge hinzu als du es bei Methode fill gemacht hast.

Eine weitere Regel könnte etwa so aussehen: Du ersetzt den Wert 15 in deiner Methode strokeWeight durch eine Variable strichstaerke. Vor der Schleife machst du einen "Handshake". Innerhalb der Schleife fügst du eine Variablenaddition hinzu.

Übertreibe hierbei mit den Einstellungen deiner Parameter, zum Beispiel bei der Größe deiner Kreise beziehungsweise Ellipsen. Verwende Variablenveränderungen wie Variablenaddition und ebenso Parameterveränderungen wie Parameterdivision. Es geht darum die Linearität durch immer mehr Regeln aufzubrechen. Zum Beispiel kannst du in der Methode strokeWeight statt der Variable strichstaerke auch die Variable blau einsetzen. Du spielst mit dem generativen Material. Das ist das Ziel.

Laufvariable

In einem Schleifenkopf kann immer nur eine Variable definiert werden, deren Wert sich im Verlauf der Schleife verändert. Wenn wir innerhalb der gleichen Schleife eine weitere Variable einsetzen wollen, brauchen wir eine Hilfskonstruktion in Form einer Laufvariablen. Dazu erstellen wir einen Handshake für diese Variable vor der Schleife und weisen ihr einen Anfangswert zu. Im Schleifenkörper erstellen wir eine Variablenaddition. Dadurch koppeln wir unsere Laufvariable an die bestehende Schleifenkonstruktion und stellen sicher, dass sich unsere zusätzliche Variable ebenfalls in ihrem Wert verändert.

Doppelschleife

Fügen wir eine zweite Schleife in den Schleifenkörper der ersten hinein, verhält sich die Gesamtkonstruktion wie zwei zusammenhängende Zahnräder. Die äußere Schleife wird zum großen Zahnrad, die innere Schleife zum kleinen Zahnrad. Typischerweise verwenden wir solche Doppelschleifen um eine Fläche in horizontaler und vertikaler Richtung mit einem Element zu füllen. Kombinieren wir die Möglichkeiten von Schleifen zum Aufbau von Mustern mit der Möglichkeit von Laufvariablen, können wir monotone Fläche modulieren. Erste Modulationen können wir bereits mit den vier Grundrechenarten wie Variablenaddition, Variablensubtraktion, Variablenmultiplikation und Variablendivision herbeiführen. Wir könnten beispielsweise die Kreisgröße während eines Flächenaufbaus verändern. In den weiteren Kapiteln werden noch weitere Modulationsmöglichkeiten kennenlernen.

 zurück zur Übersicht 


Rauschen

Noise

float offset = 0;
size(800, 800);
for (int x = 0; x < 800; x = x + 1) {
float zufallszahl = noise(offset) * 800;
  point (x, zufallszahl);
  offset = offset + 0.005;
}

Noisemuster

float xoff = 0;
float yoff = 0;
float schrittweite = 0.2;
size(800, 800);
for (int x = 40; x < 800; x = x + 40) {
  xoff = xoff + schrittweite;
  yoff = 0;
  for (int y = 40; y < 800; y = y + 40) {
    yoff = yoff + schrittweite;
    float radius = noise(xoff, yoff) * 30 + 10;
    ellipse (x, y, radius, radius);
  }
}

Zwei Zufallszahlen

float offset1 = 0;
float offset2 = 0;
size(800, 800);
for (int x = 0; x < 800; x = x + 1) {
  float zufallszahl1 = noise(offset1) * 400;
  float zufallszahl2 = noise(offset2) * 800;
  point (x, zufallszahl1);
  point (x, zufallszahl2);
  offset1 = offset1 + 0.005;
  offset2 = offset2 + 0.004;
}

Methode noise

Das Ergebnis der Methode noise liegt zwischen 0 und 1 und wird in der Variable noiserauschen gespeichert. Damit die Methode noise funktioniert, braucht sie einen Parameter, der hier offset heißt. Das Ergebnis der Methode noise verändert sich nur wenn wir ihren Parameter offset durch eine Variablenaddition verändern. Für gute Ergebnisse stellen wir eine Wert zwischen 0.03 und 0.005 für die Variablenaddition ein.


Um das Ergebnis der Methode noise verwenden zu können, müssen wir es meistens vergrößern. Um das Ergebnis zu vergrößern multiplizieren wir es mit einer Zahl zum Beispiel mit 40. Danach liegen die Ergebnis zwischen 0 und 40, statt zwischen 0 und 1.



float offset = 0;
for (int anz = 0; anz < 10; anz = anz + 1) {
  float noiserauschen = noise(offset) * 40;
  println("noise: " + noiserauschen);
  offset = offset + 0.03;
}





Warmup

Starte das Codebeispiel Noise mehrfach und beobachte das Ergebnis. Warum verändert sich bei jedem Aufruf das Ergebnis ? Verändere nun die Zahl die offset hinzuaddiert wird – stellt hier Zahlen zwischen 0.03 und 0.005 ein. Wie wirkt sich die Veränderung auf den Kurvenverlauf aus ?

Um die Charakteristik des Rauschens beim Codebeispiel Noisemuster zu verändern, veränderst du den Wert von schrittweite. Stell hier verschiedene Werte ein und probier auch mal Werte zwischen 0.03 und 0.005 einzustellen anstatt 0.2. Warum ist 0.2 als Wert hier passend ?

Rauschen / Aufgabe 1a bis 1c

+

-

Kopiere das Codebeispiel Noise. Wende in 1a die Zufallszahl auf den Radius eines Kreises an. Wende in 1b die Zufallszahl auf das Ende einer Linie an. Füge in 1c eine zweite Zufallszahl für den Anfang einer Linie hinzu.

Kopiere das Codebeispiel Noise. Wende in 1a die Zufallszahl auf den Radius eines Kreises an. Wende in 1b die Zufallszahl auf das Ende einer Linie an. Füge in 1c eine zweite Zufallszahl für den Anfang einer Linie hinzu.

Der Wert, den du der Variable offset hinzuaddierst, entscheidet über das Aussehen der Grafik oder darüber ob sich überhaupt etwas in der Grafik verändert. Wenn du keine Veränderung in deiner Grafik erkennen kannst, solltest du diesen Wert verändern. Normalerweise gibst du hier Werte zwischen 0.03 und 0.005 an, manchmal sind auch größere Werte wie 0.2 oder 2 sinnvoll. Es kommt auf die Anzahl der Elemente an, die du abbildest, welcher Wert sinnvoll ist. Wählst du den Wert zu klein, wirst du kaum Veränderung erkennen. Wählst du den Wert zu groß, werden die Sprünge zu groß.

Das Ergebnis der Methode noise multiplizierst du in der Regel mit einem Wert, damit das Ergebnis größer wird als ursprünglich zwischen 0 und 1. Die Multiplikation ist deine zweite Stellschraube. Multiplizierst du mit 800 bedeutet es, dass du Zufallswerte zwischen 0 und 800 bekommst. Es bedeutet jedoch auch, dass die Werte zwar dazwischen liegen, jedoch nicht den gesamten Bereich ausfüllen müssen. Sie könnten zum Beispiel zwischen 400 und 650 liegen. Und sie können sich mit jedem neuen Start des Programms ändern. die Multiplikation legt nur mögliche Grenzen fest, sagt noch nichts über die tatsächlichen Werte aus.

In Aufgabe 1b zeichnest du die Linien von unten nach oben und von links nach rechts. Die einfache Schleife verwendest du für die x-Position des Anfangspunktes der Linie. Die y-Position bleibt konstant auf 800 bei einer Zeichenfläche von 800 mal 800 Pixeln. Den Endpunkt der Linie bestimmst du relativ zum Anfangspunkt mit einer Parametersubtraktion. Die Zufallszahl subtrahierst du dabei von der y-Position des Anfangspunktes der Linie. In Aufgabe 1c kopierst du den Code "Zwei Zufallszahlen" und passt ihn entsprechend an.

Rauschen / Aufgabe 2a bis 2c

+

-

Kopiere das Codebeispiel Noisemuster. Wende in Aufgabe 2a das Rauschen auf die Strichstärke statt auf den Radius an. Wende in Aufgabe 2b das Rauschen auf das Linienende an. Für den Linienbeginn nimmst du die Variablen x und y. Mit einer Parameteraddition und Parametersubtraktion bestimmst du das Linienende relativ zum Linienbeginn. In Aufgabe 2c brauchst du eine Zufallszahl für den Grünanteil der Farbe und eine zweite Zufallszahl für den Blauanteil der Farbe. Den Rotanteil kannst du konstant auf den Wert 0 setzen.

Kopiere das Codebeispiel Noisemuster. Wende in Aufgabe 2a das Rauschen auf die Strichstärke statt auf den Radius an. Wende in Aufgabe 2b das Rauschen auf das Linienende an. Für den Linienbeginn nimmst du die Variablen x und y. Mit einer Parameteraddition und Parametersubtraktion bestimmst du das Linienende relativ zum Linienbeginn. In Aufgabe 2c brauchst du eine Zufallszahl für den Grünanteil der Farbe und eine zweite Zufallszahl für den Blauanteil der Farbe. Den Rotanteil kannst du konstant auf den Wert 0 setzen.

Im Codebeispiel Noisemuster wird die Zufallszahl in der Variable radius gespeichert. Wenn du deine Zufallszahl für andere Zwecke einsetzen möchtest, solltest du deine Zufallszahl entsprechend umbenennen. In Aufgabe 2a ersetzt du am Besten den Variablennamen radius durch strichstaerke. Jetzt passt du den Wertebereich der Methode noise für deine Zwecke an. Eine sinnvolle Strichstärke befindet sich zwischen 0 und 10 Punkten. Das bedeutet, dass du die Methode noise mit 10 multiplizieren solltest. Um die Strichstärke auf einen Kreis anzuwenden musst vor der Methode ellipse die Methode strokeWeight mit strichstaerke als Parameter anwenden.

In Aufgabe 2b verwendest du die doppelte Schleife um den Anfangspunkt deiner Linie zu bestimmen. Den Endpunkt der Linie bestimmst du relativ zum Anfangspunkt. Dazu addierst du den Zufallswert per Parameteraddition zur x-Position deines Anfangspunktes, zum anderen subtrahierst du den gleichen Zufallswert per Parametersubtraktion von der y-Position deines Anfangspunktes. Nun passt du noch die Ergebnisse des Zufallswertes an. Die Strichlänge sollte sich an der Rasterweite deiner Doppelschleife orientieren. Beträgt die Rasterweite wie im Abbild der Lösung bei 15 px auf einer 800 mal 800 Pixel großen Zeichenfläche, solltest du die Methode noise mit 15 multiplizieren, sodass sich die diagonalen Striche maximal berühren können und minimal mit einer Länge von 0 erst gar nicht auftauchen.

In Aufgabe 2c überträgst du die Struktur aus dem Code "Zwei Zufallszahlen" auf den Code "Noisemuster". Die Variable radius ersetzt du durch die Variable gruen. Passend dazu benennst du xoff, yoff und schrittweite in xoff1, yoff2 und schrittweite1 um. Für die Variable blau erstellt du weitere Variablen xoff2, yoff2 und schrittweite2 an. Die Methode noise passt du nun an deine Zwecke an. Für Farbanteile brauchst du Werte zwischen 0 und 255. Deshalb multiplizierst du die Methode noise mit 255. Um tatsächlich Farbe zu bekommen, musst du für deine Farbanteile gruen und blau unterschiedliche Schrittweiten wählen.

Funktion

Die Methode noise gleicht einer mathematischen Funktion. noise erwartet als Parameter einen Wert und gibt als Ergebnis eine Zufallszahl zwischen 0 und 1 zurück. Wie bei anderen stetigen Funktionen auch, wird jedem Eingabewerte exakt ein Ausgabewert zugeordnet. Für jeden Wert, den wir als Parameter noise übergeben, erhalten wir exakt eine Zufallszahl zurück. Bei gleichbleibendem Wert, bleibt die Zufallszahl auch gleich. Um unterschiedliche Zufallszahlen zu erhalten, müssen wir den Wert verändern, den wir an die Methode noise als Parameter übergeben. Typischerweise legen wir für den Eingabewert eine Laufvariable an, die meistens offset heißt. Die Laufvariable verändern wir innerhalb einer Schleife mit einer Variablenaddition. Der Wert der Laufvariable wird erst durch die Methode noise in eine Zufallszahl umgewandelt. Im Ergebnis wandeln wir eine gleichmäßige Zahlenreihe in eine zufällige um. Ein zufälliges Ergebnis zwischen 0 und 1 ist jedoch so klein, dass es fast immer durch eine Multiplikation vergrößert werden muss. Dieser Vorgang ist mit einem Pullover vergleichbar, den wir dehnen, weil er in der Waschmaschine eingegangen ist.

Zweidimensionaler Noise

In einer Doppelschleife brauchen wir einen zweidimensionalen Noise mit zwei Parametern statt einem: den ersten für die x-Achse, diesen nennen wir beispielsweise xoff, den zweiten für die y-Achse, diesen nennen wir beispielsweise yoff. Beide Parameter koppeln wir an den Aufbau des eigentlichen Musters. Die äußere Schleife des Musters bestimmt die x-Koordinate unseres Elements, die innere Schleife die y-Koordinate. xoff koppeln wir an die x-Koordinate, yoff an die y-Koordinate. Für xoff machen wir einen Handshake vor der äußeren Schleife. Wir weisen ihm zur gleichen Zeit einen Anfangswert zu. Den Wert von xoff erhöhen wir innerhalb der äußeren Schleife mit einer Variablenaddition. Für yoff machen wir einen Handshake vor der inneren Schleife. Wir weisen ihm zur gleichen Zeit ebenfalls einen Anfangswert zu. Den Wert von yoff erhöhen wir innerhalb der inneren Schleife mit einer Variablenaddition. Die Methode noise rufen wir in der inneren Schleife auf. Obwohl wir noise zwei Parameter übergeben, erhalten wir dennoch nur eine einzige Zufallszahl zurück. Jedoch ist diese Zufallszahl sowohl harmonisch zu ihren vertikalen als auch horizontalen Nachbarn in einem zweidimensionalen grafischen Muster. Im Gegensatz dazu nimmt random keine Rücksicht auf seine Nachbarn und baut auch keinen Bezug zu ihnen auf.

Weiterführende Themen

Wenn du die Noisefunktion verwenden kannst, bist du auch in der Lage eine Sinusfunktion sin() einzusetzen. Die Sinusfunktion erwartet als Eingabewert einen ins Bogenmaß umgerechneten Winkel – zum Beispiel radians(45). Als Ausgabe erhälst du einen Wert zwischen -1 und 1.

Die Methode map() vereinfacht den Einsatz der Noise- und Sinusfunktion. Mit map() kannst das Ergebnis einer Funktion auf einen anderen Wertebereich automatisch umrechnen lassen. map(noise(offset), 0, 1, -10, 32) rechnet das Ergebnis der Noisefunktion mit dem Eingabewert offset - das zwischen 0 und 1 liegt - automatisch auf einen Wertebereich zwischen -10 und 32 um.

 zurück zur Übersicht 


Buchstabe

Buchstabenoutline

import geomerative.*;
RShape gruppe;
RPoint[] punkte;

void setup() {
  size (800,800);
  noLoop();
  RG.init(this);
  // nur Truetype-Font im data-Ordner!
  gruppe = RG.getText("R", "DINOT-Bold.ttf",
  800, CENTER);
}

void draw() {
  background (255);
  translate (400-50, 400+275);
  RG.setPolygonizer(RG.UNIFORMLENGTH);
  punkte = gruppe.getPoints();
  //gruppe.draw();
  
  for (int n = 0; n < punkte.length; n = n + 3) {
    float px = punkte[n].x;
    float py = punkte[n].y;
    ellipse (px, py, 6, 6);
  }
}

Buchstabenfläche

PGraphics unsichtbar;

void setup() {
  size(800, 800);
  noLoop();
  //imageMode(CENTER);
  
  PFont schrift = createFont("DINOT-Bold.otf",800);
  
  unsichtbar = createGraphics(width, height, JAVA2D);
  unsichtbar.beginDraw();
  unsichtbar.textFont(schrift);
  unsichtbar.textSize(800);
  unsichtbar.textAlign(CENTER, CENTER);
  unsichtbar.background(255);
  unsichtbar.fill(0);
  unsichtbar.text("R", unsichtbar.width/2,   unsichtbar.height/2);
  unsichtbar.endDraw();
}

void draw() {
  //image(unsichtbar, 0, 0);
  
  for (int x = 0; x < 800; x = x + 15) {
    for (int y = 0; y < 800; y = y + 15) {
      if (unsichtbar.get (x, y) == color(0)) {
        stroke(0, 255 ,0);
        line (x, y, x + 8, y - 8);
      }
    }
  }
}

Installation der Library "geomerative"

Verwende den Code "Buchstabenoutline". Speichere den Code. Erstelle in deinem aktuellem Processingcode-Ordner einen neuen Ordner mit dem Namen "data". Dorthin kopierst du einen Truetype-Font deiner Wahl. Den Dateinamen des Fonts trägst in das Script an der entsprechenden Stelle ein. Bevor du das Programm starten kannst, muss du noch eine Library installieren. im Processing 3 findest du in der Menüzeile unter "Sketch > Library importieren > Library hinzufügen" ein Dialogfenster. In diesem Dialogfenster suchst du nach der Library "geomerative", klickst diese an und löst anschließend den Installiervorgang mit dem entsprechendem Button aus. Danach kannst du das Programm starten.

Buchstabe / Aufgabe 1a und 1b

Verwende den Code "Buchstabenfläche" und "Buchstabenoutline". Zeichne in beiden Fällen statt Diagonalen beziehungsweise Punkten große ungefüllte Kreise, die sich überschneiden.

Buchstabe / Aufgabe 2

+

-

Verbinde die Lösung der Aufgabe 1a des Kapitels "Rauschen" mit dem Code "Buchstabenoutline".

Verbinde die Lösung der Aufgabe 1a des Kapitels "Rauschen" mit dem Code "Buchstabenoutline". Erstelle hierzu einen "Handshake" für die Variable offset vor setup. Der Datentyp soll "float" sein. Füge in das Innere der einfachen Schleife die Berechnung der Variable radius hinzu. Erhöhe ebenfalls am Ende im Inneren der Schleife die Variable offset mit einer Variablenaddition. Multipliziere die Methode noise mit 200 statt 800.

Buchstabe / Aufgabe 3

+

-

Verbinde die Lösung der Aufgabe 2a des Kapitels "Rauschen" mit dem Code "Buchstabenfläche".

Verbinde die Lösung der Aufgabe 2a des Kapitels "Rauschen" mit dem Code "Buchstabenfläche". Mache einen "Handshake" des Datentyps float für die Variablen xoff, yoff und schrittweitevor setup. Weise xoff und yoff den Wert 0 zu. Weise schrittweite den Wert0.2 zu. Kopiere die Variablenadditon für xoff in die äußere Schleife. Weise der Variable yoff den Wert 0 zu, ebenfalls in der äußeren Schleife. Kopiere die Variablenaddition für yoff in die innere Schleife, jedoch nach der Methode if. Kopiere dorthin ebenfalls die Methode strokeWeight und ellipse.

Buchstabenfläche

Ein Buchstabe wird aus einer Fläche ausgeschnitten. Dazu wird eine zusätzliche unsichtbare Zeichenfläche des Datentyps PGraphics angelegt. Diese ist genauso groß wie die eigentliche Zeichenfläche und liegt auch exakt über der sichtbaren Zeichenfläche. In die unsichtbare Zeichenfläche wird ein einzelner Buchstaben hineingeladen. Der unsichtbare Hintergrund wird weiß gefärbt, der unsichtbare Buchstabe schwarz. Dieser Buchstabe ist so groß, dass er zur Fläche wird.
Nun zeichnen wir mit einer Doppelschleife in unsere sichtbare Zeichenfläche ein Muster aus Elementen. Während des Aufbaus unseres Musters wird die Farbe in der unsichtbaren Zeichenfläche mit der Methode get überprüft. In der innere Schleife befindet sich ein Filter mit der Methode if angelegt: Wenn die Farbe schwarz ist, wird ein ein Element in die sichtbare Fläche gezeichnet. Wenn die Farbe weiß ist, bleibt die Stelle frei. Im Ergebnis wird der Buchstabe aus dem unsichtbaren Bereich zu einer Ansammlung von einzelnen Elementen im sichtbaren Bereich.

Buchstabenfläche verändern

Wir haben in den zurückliegenden Aufgaben Flächen gestaltet. Diese können wir nun hier einsetzen. Im einfachen Fall fügen wir unseren Code nach dem Filter ein – eine oder mehrere Zeilen. Manchmal müssen wir auch in die umgebende Struktur der Doppelschleife eingreifen. Wollen wir beispielsweise den zweidimensionalen Noise einsetzen, fügen wir sowohl in die innere Schleife als auch in die äußere Schleife Code ein. Verwenden wir Variablen, müssen wir diese vor dem setup-Bereich mit einem Handshake vorstellen. Eventuell brauchen sie einen Anfangswert.

 zurück zur Übersicht 


Export

Pixelbild

void setup() {
  size (800, 800);
  noLoop();
}

void draw() {
  background (0);
  ellipse (400, 400, 200, 200);
  saveFrame ("data/kreis.tif");
}

Vektorbild

import processing.pdf.*;

void setup() {
  size (800, 800);
  noLoop();
}

void draw() {
  beginRecord(PDF, "data/kreis.pdf");
  background (0);
  ellipse (400, 400, 200, 200);
  endRecord();
}

Export / Aufgabe 1

Verwende den Code "Vektorbild". Kopiere einen Code deiner Wahl aus den bisherigen Aufgaben und exporiere diesen als PDF. Öffne die entstandene Datei in Illustrator. Bevor du die Daten verändern kannst, musst du zunächst mit dem Inhaltswerkzeug einen mehrfachen Rahmen um die Grafik herum löschen. Danach kommst du an die einzeilen Vektorformen dran und kannst diese verändern oder weitere Formen in Illustrator hinzufügen.

Export

Wir können Processinggrafiken als Bilddaten oder Vektordaten exportieren. Vektordaten sind beliebig skalierbar. Wenn wir Standbilder erzeugen wollen, sollten wir Vektordaten verwenden. Dazu exportieren wir PDFs. Hierzu umklammern wir das grafische Material mit der Methode beginRecord und endRecord. Was sich nach beginRecord befindet landet in der Datei, alles davor dagegen nicht: Vorsicht bei Attributen, die im setup-Bereich stehen. Diese bleiben beim Export unberücksichtigt. Wenn wir Vektordaten in Illustrator öffnen, entfernen wir einen mehrfachen Inhaltsrahmen mit dem weißen Inhaltswerkzeug, bevor wir separate Formen verschieben können.

 zurück zur Übersicht