GMU:Einführung ins Programmieren mit Processing/final/Sinus Wave

From Medien Wiki

Sinus Wave

Idee

Mein Ziel war es, ein dreidimensionales Ebenenraster zu generieren, das aus mehreren geometrischen, an den Rasterpunkten angeordneten Objekten besteht und durch deren sinusartige Auf und Abwärtsbewegung ein natürliche Wellenbewegung grafisch beschreibt.

Umsetzung

Für dessen Umsetzung war es zunächst erforderlich, mir die Funktionsweise einer beweglichen Sinuskurve auf zweidimensionaler Ebene zu vergegenwärtigen: Die Berechnung in Programmiersprache erfolgt im Grunde durch eine einfachen Sinuskalkulation eines fortlaufenden Wertes(Theta), multipliziert mit dem maximalen Höhenwert der Kurve. Durch den fortlaufenden Wert des Winkels ergeben sich bei jeder Berechnungsabfolge einer Schleife periodische Werte, die der Reihe nach in einem 'Array' gelistet werden.

yvalues = new float[10]; //Array hat zunächst noch eine Länge in der Größe von 10 Schleifendurchläufen
theta += 0.08;
   float x = theta;
   for (int i = 0; i < 10; i++) {
        yvalues[i] = sin(x)*30;
        x+=dx;
}

Zur grafischen Darstellung erfolgt der Aufruf einer separaten Funktion, in dieser das Geometrische Objekt (Kubus), mittels einer Schleife, jeweils neu erstellt und in horizontaler Achsenrichtung, um einen definierten Abstandswert(50 Pixel) verschoben werden soll. Für jedes einzelne Objekt wird bei erneutem Schleifendurchlauf ein neuer Y-Wert aus dem Array geschöpft.

for (int x = 0; x < 10; x++) {
  pushMatrix();
  translate(50*x+50, 500+yvalues[x], 0);
  box(15);
  popMatrix();
  line(50+(x*50), 500+yvalues[x], 0, 100+(x*50), 500+yvalues[x+1], 0); //Verbindungslinien
}

Für eine dreidimensionale Darstellung der Objekte in Reihen (in Richtung x-Achse) und Spalten (in Richtung z-Achse), ist eine Doppelschleife erforderlich:

for (int x = 0; x < 10; x++) {
  for (int z = 0; z < 10; z++) {
    pushMatrix();
    translate(50*x+50, 500+yvalues[x+z], z*-50);
    box(15);
    popMatrix();
    line(50+(x*50), 500+yvalues[z+x], z*-50, 100+(x*50), 500+yvalues[z+x+1], z*-50);
    line(50+(x*50), 500+yvalues[z+x], z*-50, 50+(x*50), 500+yvalues[z+x+1], (z*-50)-50);
  }
}

Hierbei wird, um eine diagonale Wellenbewegung zu erzielen, dem Listenindex des Arrays der Zählwert der Variable 'z' hinzu addiert. Das Array muss jedoch bei der Deklaration den doppelten Längenwert aufweisen, da sonst seine Liste überfüllt wäre. Das gleiche gilt für die Anzahl der Schleifendurchläufe bei der Sinusberechnung. Andere Formen der Darstellung mittels 'translate' sind jedoch möglich:

for (int x = 0; x < 10; x++) {
  for (int z = 0; z < 10; z++) {
    pushMatrix();
    translate(50*x+50, 500+yvalues[x], z*-50);
    translate(0, yvalues[z], 0);
    box(15);
    popMatrix();
    line(50+(x*50), 500+yvalues[z]+yvalues[x], z*-50, 100+(x*50), 500+yvalues[z]+yvalues[x+1], 
    z*-50);
    line(50+(x*50), 500+yvalues[z]+yvalues[x], z*-50, 50+(x*50), 500+yvalues[z+1]+yvalues[x], 
    (z*-50)-50);
  }
}


PROGRAMM

 

float theta;  // Start angle at 0
float dx;  // Value for incrementing X, a function of period and xspacing
float[] yvalues;  // array in dem die höhenwerte der jeweiligen boxen gespeichert werden

void setup() {
  smooth();
  size(600, 600, P3D);
  frameRate(30);
  dx = (TWO_PI / 500) * 60; //anzahl bzw. abstand der wellenberge
  yvalues = new float[20];
  translate(width/2, height/2);
}

void draw() {
  rotateX(-0.5);
}

void keyPressed() {
  background(55);
  theta += 0.08; //geschwindigkeit
  float x = theta;
  for (int i = 0; i < 20; i++) {
    yvalues[i] = sin(x)*30; //höhe des wellenbergs
    x+=dx;
  } 

  if (key == '1') {
    renderWave1();
  } 

  if (key == '2') {
    renderWave2();
  }
}

void  renderWave1() {
  for (int x = 0; x < 10; x++) {
    for (int z = 0; z < 10; z++) {
      pushMatrix();
      translate(50*x+50, 500+yvalues[x+z], z*-50); 
      //translate(0, yvalues[z], 0); 
      box(15);
      popMatrix();
      line(50+(x*50), 500+yvalues[z+x], z*-50, 100+(x*50), 500+yvalues[z+x+1], z*-50);
      line(50+(x*50), 500+yvalues[z+x], z*-50, 50+(x*50), 500+yvalues[z+x+1], (z*-50)-50);
    }
  }
}


void  renderWave2() {
  for (int x = 0; x < 10; x++) {
    for (int z = 0; z < 10; z++) {
      pushMatrix();
      translate(50*x+50, 500+yvalues[x], z*-50); 
      translate(0, yvalues[z], 0); 
      box(15);
      popMatrix();
      line(50+(x*50), 500+yvalues[z]+yvalues[x], z*-50, 100+(x*50), 500+yvalues[z]+yvalues[x+1], z*-50);
      line(50+(x*50), 500+yvalues[z]+yvalues[x], z*-50, 50+(x*50), 500+yvalues[z+1]+yvalues[x], (z*-50)-50);
    }
  }
}