Sinus Wave
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);
}
}
PROGRAM
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);
}
}
}