Wiederholung der Gesamtkurve mit einer for-Schleife

Ergebnis der swf-Datei

Die Gesamtkurve wird mit einer for-Schleife von oben nach unten wiederholt.

Der Programmcode ohne Erklärungen

Codeabschnitte, die sich nicht vom vorigen Arbeitsschritt unterscheiden, werden grau geschrieben.

// BÜHNENRECHTECK MIT FARBE FÜLLEN UND KONTURIEREN
fillStage(1, 0xFF0000, 0xCCCCFF);
//
// ZEICHNEN EINER ABFOLGE VON WELLENLINIEN
//
var point = new Array();
for (var i:Number = 0; i<Stage.height; i=i+12) {
   point.x = 0;
   point.y = i;
   curve(point, 100, 80, 1, 0x000000);
}
/*
DEKLARATION DER FUNKTIONEN curve(), baseCurve() UND fillStage()
*/
function curve(pt:Array, a:Number, b:Number, lineWidth:Number, lineColor:Number):Void {
   this.lineStyle(lineWidth, lineColor);
   this.moveTo(pt.x, pt.y);
   do {
      pt = baseCurve(pt, a, b);
   } while (0<=pt.x && pt.x<Stage.width && 0<=pt.y && pt.y<Stage.height);
}
function baseCurve(pt:Array, a:Number, b:Number):Array {
   this.curveTo(pt.x+a/4, pt.y-b/2, pt.x+a/2, pt.y);
   this.curveTo(pt.x+3*a/4, pt.y+b/2, pt.x+a, pt.y);
   pt.x = pt.x+a;
   return pt;
}
function fillStage(lineWidth:Number, lineColor:Number, fillColor:Number):Void {
   this.lineStyle(lineWidth, lineColor);
   this.beginFill(fillColor);
   this.moveTo(0, 0);
   this.lineTo(Stage.width-1, 0);
   this.lineTo(Stage.width-1, Stage.height-1);
   this.lineTo(0, Stage.height-1);
   this.lineTo(0, 0);
   this.endFill();
}

 

Der Programmcode mit Erklärungen

Wiederholung der Gesamtkurve

Durch var point = new Array(); wird eine Variable vom Typ Array definiert, in der bei jedem Schleifendurchlauf der jeweilige Startpunkt der Gesamtkurve abgespeichert wird.

for (var i:Number = 0; i<Stage.height; i=i+12) {
   point.x = 0;
   point.y = i;
   curve(point, 100, 80, 1, 0x000000);
}

Über die Schleifenvariable i wird die y-Koordinate der Startpunkte gesteuert point.y = i;. Die x-Koordinate bleibt immer auf 0 point.x = 0;, damit die Kurven beim linken Rand beginnen.
i beginnt bei 0 var i:Number = 0, d.h. die erste Kurve wird ausgehend von der linken oberen Ecke gezeichnet.
Bei jedem Schleifendurchlauf wird i um 12 erhöht i=i+12. Dadurch springen die Startpunkte entlang der linken Bühnenkante in 12er-Schritten nach unten.
Solange i innerhalb der Bühnenhöhe liegt i<Stage.height, wird die Schleife wiederholt.
Alle Kurven werden abgesehen vom Startpunkt mit fixen Eingabewerten gezeichnet curve(point, 100, 80, 1, 0x000000).

Variation der Kurvenparameter

Im nachfolgenden Beispiel wurden die Kurvenparameter im Schleifendurchlauf variiert.

Betrachtet man den Kurvenverlauf auch außerhalb der Bühne ergibt sich folgendes Bild:

Der Startpunkt wird in Abhängigkeit von i bei jedem Schleifendurchlauf nach links verschoben point.x = 0-i/2; .
Die Breite der Basiskurve wird in Abhängigkeit von i vergrößert: 150+i/4. 150 ist der Startwert für die erste Kurve.
Die Höhe der Basiskurve wird ebenfalls in Abhängigkeit von i vergrößert: i/2. 0 ist somit der Wert für die erste Kurve, d.h. die erste Kurve ist eine Gerade.
Die Strichstärke und -farbe werden nicht variiert.

for (var i:Number = 0; i<Stage.height; i=i+10) {
   point.x = 0-i/2;
   point.y = i;
   curve(point, 150+i/4, i/2, 2, 0x0000AA);
}

Ein möglicher Fehler

point.x = 0;
for (var i:Number = 0; i<Stage.height; i=i+12) {
   point.y = i;
   curve(point, 100, 80, 1, 0x000000);
}

Man könnte annehmen, dass man die Anweisung point.x = 0; vor die for-Schleife setzen kann, da sie im Schleifenkörper nicht verändert wird.
Das ist aber nicht möglich, denn man erhält mit dieser Veränderung folgendes Ergebnis:

Beim Aufruf von curve(point, 100, 80, 1, 0x000000) werden nicht die x- und y-Werte von point übergeben, sondern nur die Adresse des Arrays. D.h. es wird der Funktion nur mitgeteilt, wo im Speicher das Array "liegt". Über diese Adresse kann die Funktion dann die gespeicherten Arraywerte abrufen.
Diese Adresse wird in der Funktion curve an die Funktion baseCurve weitergeleitet baseCurve(pt, a, b). In der Funktion baseCurve wird der x-Wert des Arrays verändert pt.x=pt.x+a. Der letzte x-Wert nach dem Zeichnen der ersten Gesamtkurve liegt außerhalb der Bühne. Wenn nun für den in der for-Schleife veränderten y-Wert des neuen Startpunktes die nächste Gesamtkurve gezeichnet werden soll, liegt der x-Wert aber außerhalb der Bühne. Daher wird nichts mehr gezeichnet und wir sehen in der obigen Abbildung nur die erste Gesamtkurve.

Das Problem kann nur gelöst werden, wenn beim Aufruf von curve(point, 100, 80, 1, 0x000000); nicht point sondern die Adresse einer echten Kopie des Arrays point an curve übergeben wird.
Mit der Array-Funktion slice wird eine echte Kopie eines Array erstellt. Allerdings funktioniert das nur bei Arrays, die über Zahlen indiziert sind und nicht bei Arrays, bei denen die Elemente über Namen angesprochen werden.
Daher werden im folgenden Programmcode die x-Koordinate über point[0] bzw. pt[0] und die y-Koordinate über point[1] bzw. pt[1] angesprochen.
point.slice(0) ist eine echte Kopie des Arrays point beginnend beim Index 0.

Damit lässt sich die Anweisung point[0] = 0; vor die for-Schleife setzen.

// BÜHNENRECHTECK MIT FARBE FÜLLEN UND KONTURIEREN
fillStage(1, 0xFF0000, 0xCCCCFF);
//
// ZEICHNEN EINER ABFOLGE VON WELLENLINIEN
//
var point = new Array();
point[0] = 0;
for (var i:Number = 0; i<Stage.height; i=i+12) {
   point[1] = i;
   curve(point.slice(0), 100, 80, 1, 0x000000);
}
/*
DEKLARATION DER FUNKTIONEN curve(), baseCurve() UND fillStage()
*/
function curve(pt:Array, a:Number, b:Number, lineWidth:Number, lineColor:Number):Void {
   this.lineStyle(lineWidth, lineColor);
   this.moveTo(
pt[0], pt[1]);
   do {
      pt = baseCurve(pt, a, b);
   } while (0<=
pt[0] && pt[0]<Stage.width && 0<=pt[1] && pt[1]<Stage.height);
}
function baseCurve(pt:Array, a:Number, b:Number):Array {
   this.curveTo(
pt[0]+a/4, pt[1]-b/2, pt[0]+a/2, pt[1]);
   this.curveTo(
pt[0]+3*a/4, pt[1]+b/2, pt[0]+a, pt[1]);
   
pt[0] = pt[0]+a;
   return pt;
}
function fillStage(lineWidth:Number, lineColor:Number, fillColor:Number):Void {
   this.lineStyle(lineWidth, lineColor);
   this.beginFill(fillColor);
   this.moveTo(0, 0);
   this.lineTo(Stage.width-1, 0);
   this.lineTo(Stage.width-1, Stage.height-1);
   this.lineTo(0, Stage.height-1);
   this.lineTo(0, 0);
   this.endFill();
}