|
- Applets : Fraktale : Sierpinski-Dreieck 3 -
Das fraktale Sierpinski-Dreieck im Lindenmayer-System.
Ein linker bzw. rechter Mausklick auf das Applet vergrößert oder verringert die Iterationstiefe.
Das verwendete L-System Schema: FXF--FF--FF, X -> --FXF++FXF++FXF--, F -> FF, 60°
Sierpinski3.java
import java.awt.*;
import java.applet.*;
public class Sierpinski3 extends Applet {
Point a, b; // Verbindungspunkte eines Einzelschritts
int lengthF = 128; // Schrittlänge Startwert
double direction; // Richtung in Grad
double rotation = 60; // Drehung in Grad
int depth = 1; // Iterationen Startwert
Image buffer;
Graphics gBuffer;
Graphics g;
public void init() {
setBackground(new Color(255,255,255));
}
public boolean mouseDown(Event ev, int x, int y) {
buffer = null;
if (!ev.metaDown()) {
if (depth<7) lengthF = (int) Math.floor(lengthF/2);
depth += 1;
}
else if (depth>1) {
lengthF = (int) Math.ceil(lengthF*2);
depth -= 1;
}
if (depth>7) depth = 7;
else repaint();
return true;
}
public void paint(Graphics g) {
if (buffer!=null) {
g.drawImage (buffer, 0, 0, this);
return;
}
buffer = createImage(size().width,size().height);
gBuffer = buffer.getGraphics();
gBuffer.setColor(new Color(160,0,0)); // Farbe
a = new Point(10,265); // Start-Punkt
direction = 0; // Start-Richtung in Grad
turtleGraphic(g, gBuffer, "FXF--FF--FF", depth);
}
public void turtleGraphic(Graphics g, Graphics gBuffer, String instruction, int depth) {
if (depth==0) return;
depth -= 1;
Point aMark = new Point(0,0);
double directionMark = 0;
// Dummy-Werte
int i;
char c;
for (i=0;i<instruction.length();i++) {
c = instruction.charAt(i);
// Produktionsregeln iterieren, solange Tiefe nicht erreicht ist
if (c=='X') turtleGraphic(g, gBuffer, "--FXF++FXF++FXF--", depth);
// Schritt Vorwärts
else if (c=='F') {
// Produktionsregel iterieren, solange Tiefe nicht erreicht ist
turtleGraphic(g, gBuffer, "FF", depth);
// Zeichnen: Ab 'a' in Richtung 'direction' einen Schritt der Länge 'lengthF'
if (depth==0) {
double rad = 2*Math.PI/360 * direction; // Grad -> Radiant
int p = (int) Math.round(lengthF * Math.cos(rad));
int q = (int) Math.round(lengthF * Math.sin(rad));
b = new Point(a.x+p, a.y+q);
// Animations-Effekt
try {Thread.sleep(20);}
catch (InterruptedException e) {}
gBuffer.drawLine(a.x, a.y, b.x ,b.y);
g.drawImage (buffer, 0, 0, this);
a = b; // Neuer Startpunkt
}
}
// Drehung links herum
else if (c=='+') direction += rotation;
// Drehung rechts herum
else if (c=='-') direction -= rotation;
// Position und Richtung speichern
else if (c=='[') {
aMark = a;
directionMark = direction;
}
// Zurück zu gespeicherter Position und Richtung
else if (c==']') {
a = aMark;
direction = directionMark;
}
}
}
}
Ab 6 Iterationen zeigt sich in der schwankenden Gesamtgröße des Dreiecks ein rundungsbedingtes Fehlverhalten. Bei 7 Iterationen ist schon das hier mögliche Maximum erreicht. Die Schrittlängen betragen dann nur noch ein Pixel.
Mehr zum Konstruktionsprinzip des Lindenmayer-Systems finden Sie unter L-System
Download Sierpinski_Dreieck_3.zip (Applet und Code ca. 3 kb)
© 2001-2004 Albert Kluge - Alle Rechte vorbehalten
Impressum | Datenschutz | Nutzung | eMail
|