Zufall & Events

random

Für Anzahl, Farbe, Form und Position die Würfel fliegen lassen.

  • random(a) erzeugt eine Zufallszahl zwischen 0 und a, wobei a eine rationale oder gebrochen rationale Zahl sein kann. Bei dieser Parameteranzahl legen wir demnach nur die Obergrenze des möglichen Wertebereiches fest. Die Untergrenze ist durch Processing auf 0 gesetzt.
    // z.B.: 0.8751683
    println (random (1));
    
  • random(a, b) erzeugt eine Zufallszahl zwischen a und b, wobei a und b rationale oder gebrochenrationale Zahlen seien können. Beide, Unter- und Obergrenze, werden von uns festgelegt.
    // z.B.: 3.9300842
    println (random (1, 10);
    

Als Ergebnis liefert uns die random() Funktion immer einen gebrochen rationalen Wert. Das Befüllen eines int mit dem Resultat ist uns demnach nicht gestattet – wir müssen den Datentyp float verwenden.

Bsp.: random 1

void setup () {
  size(200, 200);
}
 
void draw () {
  ellipse (100, 100, random (200), random (200));
}

In jedem Einzelbild (einem draw() Durchlauf) wird eine Ellipse gezeichnet. Breite und Höhe werden jedes Mal zufällig bestimmt – zwischen 0 und 200 Pixel. Eine Variable zur Zwischenablage der Zufallszahlen wird dabei nicht benötigt. Das Resultat der random() Funktion wird direkt als Parameter an die ellipse() Funktion weitergereicht.

Bsp.: random 2

void setup () {
  size(200, 200);
}
 
void draw () {
  // erstelle eine Variable "durchmesser"
  // und lege in ihr einen zufälligen Wert
  // zwischen 0 und 200 ab
  float durchmesser = random (200);
 
  // zeichne einen Kreis in die Mitte der
  // Zeichenfläche – verwende für Breite
  // und Höhe den Wert der Variable "durchmesser"
  ellipse (100, 100, durchmesser, durchmesser);
}

Im zweiten Beispiel erzeugen wir gleichförmige Kreise deren Durchmesser ebenfalls zufällig ist. Dies geht nur mittels Zuhilfenahme von einer Variable deren Wert bei der Breite und Höhe der Ellipse verwendet wird. Beachte das sie vom Datentyp float zu sein hat. Da das Resultat des random() Aufrufs eine gebrochen rationale Zahl zurück gibt – int kann nur mit Ganzzahlen gefüllt werden.

Bsp.: random 3

void setup () {
  size(200, 200);
  // aktiviert Kantenglättung
  smooth ();
  // begrenzung der Einzelbilder pro
  // Sekunde auf 5 (besser für die augen)
  frameRate (5);
}
 
void draw () {
  background (255);
 
  // bestimmung der Kreisanzahl für
  // dieses Einzelbild (Maxima ist 40)
  float anzahl = random (40);
 
  // für jeden Kreis werden position
  // und Farbe neubestimmt
  for (int i=0; i < anzahl; i = i + 1) {
    // random Position auf der x-Achse
    float posX = random (width);
    // random Position auf der y-Achse
    float posY = random (height);
 
    // random Werte für alle drei Farbkanäle RGB
    fill (random (255), random (255), random (255));
    // zeichnen des Kreises an den vorher
    // ermittelten Koordinaten
    ellipse (posX, posY, 20, 20);
  }
}

Bis auf die Abmaße haben wir im dritten Beispiel mit Anzahl, Position und Farbe fast alle möglichen Attribute in unserer simplen Darstellung vom Zufall bestimmt. Die Verwendung von random() ist also nicht automatisch ein Rezept für die Erstellung von hochwertigen Grafiken. Setze es mit Bedacht ein um geringe Abweichungen in deinem Arrangement zu generieren oder die Verteilung im Aufbau deines Programmes zu organisieren – für abwechslungsreiche Resultate.

noise

Im Gegensatz zu random() ist noise() eine kontrollierbarere Methode um Zufall zu erzeugen. Sie basiert auf der Theorie des Perlin Noise, 1982 von Ken Perlin für den legendären Film Tron entwickelt. random() führt die Bestimmung des Zufallswertest jedes Mal auf neue aus – unabhänig von vorherigen Ergebnissen. Dieser Aspekt unterscheidet beide Funktionen. noise() bezieht sich auf das Resultat des letzten Aufrufes und fügt ihm eine leichte Varianz hinzu. Auf dieser Grundlage werden in der Computergrafik natürlich wirkende Texturen, Gelände und Wolken generiert. Die Varianz verteilt sich auf eine bestimmte Anzahl von Funktionen die unterschiedliche Frequenzen und Amplituden besitzen. Durch Addition all dieser Wellen erhählt man ein harmonisches/gleichmäßiges Rauschen. Weiterführend

  • noise(x) Zufallszahl in eindimensionaler Abfolge.
  • noise(x, y) Zufallszahl in zweidimensionaler Abfolge, z.B. für eine 2d Textur.
  • noise(x, y, z) Zufallszahl in dreidimensionaler Abfolge, z.B. für eine räumlichen Wolke.
  • noiseDetail(octaves) definiert die Anzahl an Wellen die addiert das Rauschen ergeben. Je größer die Anzahl – umso feiner die Varianz. Processing arbeitet standardmäßig mit vier Oktaven.

Bsp.: random() vs. noise()

size(600, 170);
background (255);
noStroke ();
fill (0);
 
float v = 0;
for (int i=0; i < width; i += 3) {
  float n = 90 + noise (v) * 40;
  rect (i, n, 2, 20);
  v = v + 0.15;
}
 
for (int i=0; i < width; i += 3) {
  float r = random (10, 30);
  rect (i, r, 2, 20);
}

Input

Mausinteraktion

Bisher haben wir um den Programmfluss zu steuern zwei Funktionsblöcke kennengelernt: void setup() als statischen Modus der nur einmal ausgeführt wird und dem Befehle nacheinander einmal ausgeführt werden und void draw(), das solange wiederholt wird, bis der Benutzer das Programm unterbricht.

Um verschiedene Tastatureingaben oder Mausbefehle (man spricht auch von Tastatur oder Maus Events) abzufragen gibt es neben der der if() abfrage von Processing eigens zur Verfügung gestellte Funktionen. Diese Funktionen werden nach dem draw() block geschrieben. Den Abfrage ob die Maus gedrückt wurde haben wir bisher mit

if (mousePressed) {
  //tue etwas
}

kennengelernt. Um komplexere Programme zu schreiben und den Programmfluss sinnvoll und übersichtlich zu gestalten bedienen wir uns nun der Funktion:

void mousePressed () {
  //tue etwas
}

Wie alle Funktionen wird auch diese mit void eingeleitet und von geschweiften Klammern umrahmt. Diese Funktion wird einmal aufgerufen, nachdem ein Mausknopf gedrückt wurde und unterscheidet sich dadurch durch die if(mousePressed) Abfrage, da diese, solange sie im draw() loop steht immer wieder durchlaufen wird.

Bsp. mousePressed ()

void setup () {
  //setze die größe der Zeichenfläche auf 100 *100 Pixel
  size(100, 100);
  // lösche die Zeichenfläche und fülle sie mit weiss
  background(255);
  //antialiasing aktivieren
  smooth();
}
 
void draw () {
  // draw muss existieren damit unser 
  // programm am Leben bleibt
}
 
void mousePressed() {
  // Outline deaktivieren
  noStroke();
 
  // Füllfarbe auf schwarz & semitransparent setzen
  fill(0, 0, 0, 125);
 
  // Ellipse an der Mausposition zeichnen
  ellipse(mouseX, mouseY, 10, 10);
}

Man kann nicht nur abfragen, ob die Maus gedrückt wurde, sondern auch auf die anderen Stati können wir wie folgt zugreifen:

  • mousePressed() die Maustaste wurde gedrückt
  • mouseReleased() die Maustaste wurde losgelassen
  • mouseMoved() die Maus wird bewegt & es ist kein Knopf gedrückt
  • mouseDragged() der Mausknopf ist gedrückt und die Maus wird dabei bewegt

Auch für diese Stati müssen wir natürlich Funktionen festlegen:

Bsp. mousePressed() & mouseReleased()

void setup () {
  // setze die größe der Zeichenfläche auf 100x100 Pixel
  size(100, 100);
  // lösche die Zeichenfläche und fülle sie mit weiss
  background (255);
  // Antialiasing aktivieren
  smooth ();
}
 
void draw() {
}
 
void mousePressed() {
  // Outline deaktivieren
  noStroke ();
 
  //Füllfarbe auf schwarz & semitransparent setzen
  fill (0, 0, 0, 125);
 
  //Ellipse an der Mausposition zeichnen
  ellipse (mouseX, mouseY, 10, 10);
}
 
void mouseReleased() {
  // Füllfarbe deaktivieren
  noFill ();
 
  // Strichfarbe auf rot & semitransparent setzen
  stroke (255, 0, 0, 125);
 
  // Rechteck von der Mitte aus zeichnen
  rectMode (CENTER);
  // Rechteck an der Mausposition zeichnen
  rect (mouseX, mouseY, 15, 15);
}

Nun soll noch ein Punkt an den Maus X 6 Maus Y Koordinaten gezeichnet werden, sobald die Maus bewegt wurde, aber keine Taste gedrückt ist

Bsp.: mousePressed() & mouseReleased() & mouseMoved()

void setup () {
  // setze die größe der Zeichenfläche auf 100x100 Pixel
  size(100, 100);
  // lösche die Zeichenfläche und fülle sie mit weiss
  background (255);
  // Antialiasing aktivieren
  smooth ();
}
 
void draw () {
}
 
void mousePressed () {
  // Outline deaktivieren
  noStroke ();
 
  // Füllfarbe auf schwarz & semitransparent setzen
  fill (0, 0, 0, 125);
 
  //Ellipse an der Mausposition zeichnen
  ellipse (mouseX, mouseY, 10, 10);
}
 
void mouseReleased() {
  // Strichfarbe deaktivieren
  noFill ();
 
  // Strichfarbe auf schwarz & semitransparent setzen
  stroke (255, 0, 0, 125);
 
  // Rechteck vom Mittelpunkt aus zeichnen
  rectMode (CENTER);
 
  // Rechteck an der Mausposition zeichnen
  rect (mouseX, mouseY, 15, 15);
}
 
void mouseMoved() {
  // Strichfarbe auf schwarz & semitransparent setzen
  stroke (0, 0, 0, 125);
 
  //Punkt an der Mausposition zeichnen
  point (mouseX, mouseY);
}

Im nächsten Beispiel soll der Punkt nur dann gezeichnet werden, wenn der Mausknopf gedrückt und die Maus dabei bewegt wird. Dazu müssen wir lediglich den mouseMoved() Block in mouseDragged() umbenennen:

void setup(){
  // setze die größe der Zeichenfläche auf 100x100 Pixel
  size(100, 100);
  // lösche die Zeichenfläche und fülle sie mit weiss
  background (255);
  // Antialiasing aktivieren
  smooth ();
}
 
void draw () {
}
 
void mousePressed () {
  // Outline deaktivieren
  noStroke ();
 
  // Füllfarbe auf schwarz & semitransparent setzen
  fill (0, 0, 0, 125);
 
  // Ellipse an der Mausposition zeichnen
  ellipse(mouseX, mouseY, 10, 10);
}
 
void mouseReleased () {
  // Strichfarbe deaktivieren
  noFill ();
 
  // Strichfarbe auf schwarz & semitransparent setzen
  stroke (255, 0, 0, 125);
 
  // Rechteck vom Mittelpunkt aus zeichnen
  rectMode (CENTER);
 
  // Rechteck an der Mausposition zeichnen
  rect (mouseX, mouseY, 15, 15);
}
 
void mouseDragged() {
  // Strichfarbe auf schwarz & semitransparent setzen
  stroke (0, 0, 0, 125);
 
  // Punkt an der Mausposition zeichnen
  point (mouseX, mouseY);
}

Tastaturinteraktion

Genau wie mit der Maus können auch Tastatur Events abgefragt werden. Dabei wird jeder Tastendruck durch die Funktion keyPressed() (Taste wurde gedrückt) und keyReleased() (Taste wurde losgelassen) registriert. Wie oben beschrieben wird der Code in dem keyPressed() Block einmal ausgeführt, wenn eine Taste gedrückt wurde.

Bsp.: keyPressed()

void setup () {
  // setze die größe der Zeichenfläche auf 100x100 Pixel
  size(100, 100);
  // lösche die Zeichenfläche und fülle sie mit weiss
  background (255);
  // antialiasing aktivieren
  smooth();
}
 
void draw () {
}
 
void keyPressed () {
  // Outline deaktivieren
  noStroke();
 
  // Füllfarbe auf schwarz & semitransparent setzen
  fill(0, 0, 0, 125);
 
  // Ellipse an einer zufälligen Position in der Zeichenfläche zeichnen
  ellipse(random(height), random(width), 10, 10);
}

Im keyPressed() Block ist es zus&ätzlich möglich abzufragen, welche Taste gedrückt wurde:

Bsp.: keyPressed() 2

void setup () {
  // Setze die größe der Zeichenfläche auf 100x100 Pixel
  size(100, 100);
  // lösche die Zeichenfläche und fülle sie mit weiss
  background(255);
  //antialiasing aktivieren
  smooth();
}
 
void draw() {
}
 
void keyPressed() {
  // Abfrage ob die Taste 'e' gedrückt wurde
  if (key == 'e') {
    // Outline deaktivieren
    noStroke ();
    // Füllfarbe auf schwarz & semitransparent setzen
    fill(0, 0, 0, 125);
    // Ellipse an der Mausposition zeichnen
    ellipse(random(height), random(width), 10, 10);
  }
 
  // Abfrage ob die Taste 'r' gedrückt wurde
  if (key == 'r') {
    // Füllfarbe deaktivieren
    noFill ();
    //Strichfarbe auf schwarz & semitransparent setzen
    stroke (255, 0, 0, 125);
    //Rechteck an einer zufälligen Position in der Zeichenfläche zeichnen
    rect (random (height), random (width), 10, 10);
  }
}

Neben den Buchstabentasten kennt Processing soggenannte Konstanten für die Abfrage spezieller Tasten: (BACKSPACE, TAB, ENTER, RETURN, ESC, DELETE, UP, DOWN, LEFT und RIGHT, …)

Bsp.: keyPressed() 3

void setup() {
  // Setze die Größe der Zeichenfläche auf 100x100 Pixel
  size(100, 100);
  // lösche die Zeichenfläche und fülle sie mit weiss
  background(255);
  // Antialiasing aktivieren
  smooth();
}
 
void draw () {
}
 
void keyPressed () {
  // Abfrage ob die Taste 'e' gedrückt wurde
  if (key == 'e') {
    // Outline deaktivieren
    noStroke ();
    // Füllfarbe auf schwarz & semitransparent setzen
    fill (0, 0, 0, 125);
    //Ellipse an der Mausposition zeichnen
    ellipse(random (height), random (width), 10, 10);
  }
 
  // Abfrage ob die Taste 'r' gedrückt wurde
  if(key == 'r') {
    // Füllfarbe deaktivieren
    noFill ();
    // Strichfarbe auf schwarz & semitransparent setzen
    stroke (255, 0, 0, 125);
    //Rechteck an einer zufälligen Position in der Zeichenfläche zeichnen
    rect (random (height), random (width), 10, 10);
  }
  if (key == BACKSPACE) {
    // fülle die Zeichenfläche mit weiss
    background(255);
  }
}