Fraktale Geometrie Leitseite URL haftendorn.uni-lueneburg.de/mathe-lehramt/fraktale/fraktale.htm |
[Fraktale (Leitseite)] [Wegfraktale] [Galerie] [Wegfraktale mit Java] [Programme] |
Javaprogramm aus dem Internet 1995 von Jim Graham Es ermöglicht die Eingabe des Lindenmayeraxioms und der Regeln sowie der Parameter auf der Html-Seite beim Appletaufruf. Wer sich also so eine Seite speichert, kann dann eigene Fraktale erfinden. |
Quellcode:
import java.awt.Graphics; import java.awt.Color; import java.util.Stack; import java.util.Vector; /** * A (not-yet) Context sensitive L-System Fractal applet class. * * The rules for the Context L-system are read from the java.applet.Applet's * attributes and then the system is iteratively applied for the * given number of levels, possibly drawing each generation as it * is generated. Note that the ContextLSystem class does not yet * handle the lContext and rContext attributes, although this * class is already designed to parse the '[' and ']' characters * typically used in Context sensitive L-Systems. * * @author Jim Graham * @version 1.1f, 27 Mar 1995 */ public class CLSFractal extends java.applet.Applet implements Runnable { ContextLSystem cls; int fractLevel = 1; int repaintDelay = 50; boolean incrementalUpdates; float startAngle; float rotAngle; float Xmin; float Xmax; float Ymin; float Ymax; int border; boolean normalizescaling; public void init() { String s; cls = new ContextLSystem(this); s = getParameter("level"); if (s != null) fractLevel = Integer.parseInt(s); s = getParameter("incremental"); if (s != null) incrementalUpdates = s.equals("true"); s = getParameter("delay"); if (s != null) repaintDelay = Integer.parseInt(s); s = getParameter("startAngle"); if (s != null) startAngle = Float.valueOf(s).floatValue(); s = getParameter("rotAngle"); if (s != null) rotAngle = Float.valueOf(s).floatValue(); rotAngle = rotAngle / 360 * 2 * 3.14159265358f; s = getParameter("border"); if (s != null) border = Integer.parseInt(s); s = getParameter("normalizescale"); if (s != null) normalizescaling = s.equals("true"); } Thread kicker; public void run() { Thread me = Thread.currentThread(); boolean needsRepaint = false; while (kicker == me && cls.getLevel() < fractLevel) { cls.generate(); if (kicker == me && incrementalUpdates) { if(cls.getLevel() >6 && cls.getLevel() < fractLevel) { needsRepaint = false; } else { repaint(); } //repaint(); try {Thread.sleep(repaintDelay);} catch (InterruptedException e){} } else { if(cls.getLevel() > 6 && cls.getLevel() < fractLevel) { needsRepaint = false; } else { needsRepaint = true; } } } if (kicker == me) { kicker = null; if (needsRepaint) { repaint(); } } } public void start() { kicker = new Thread(this); kicker.start(); } public void stop() { kicker = null; } public boolean mouseUp(java.awt.Event evt, int x, int y) { cls = new ContextLSystem(this); savedPath = null; start(); return true; } String savedPath; public void paint(Graphics g) { //Color hellgruen=new Color(100,255,200); //setBackground(hellgruen); //Color hellblau=new Color(200,200,255); //setBackground(hellblau); Color hellgelb=new Color(255,255,170); setBackground(hellgelb); Color dunkelgruen=new Color(0,170,0); g.setColor(dunkelgruen); String fractalPath = cls.getPath(); if (fractalPath == null) { super.paint(g); return; } if (savedPath == null || !savedPath.equals(fractalPath)) { savedPath = fractalPath; render(null, fractalPath); } for (int i = 0; i < border; i++) { g.draw3DRect(i, i, size().width - i * 2, size().height - i * 2,false); } render(g, fractalPath); } void render(Graphics g, String path) { Stack turtleStack = new Stack(); CLSTurtle turtle; if (g == null) { Xmin = 1E20f; Ymin = 1E20f; Xmax = -1E20f; Ymax = -1E20f; turtle = new CLSTurtle(startAngle, 0, 0, 0, 0, 1, 1); } else { float frwidth = Xmax - Xmin; if (frwidth == 0) frwidth = 1; float frheight = Ymax - Ymin; if (frheight == 0) frheight = 1; float xscale = (size().width - border * 2 - 1) / frwidth; float yscale = (size().height - border * 2 - 1) / frheight; int xoff = border; int yoff = border; if (normalizescaling) { if (xscale < yscale) { yoff += ((size().height - border * 2) - ((Ymax - Ymin) * xscale)) / 2; yscale = xscale; } else if (yscale < xscale) { xoff += ((size().width - border * 2) - ((Xmax - Xmin) * yscale)) / 2; xscale = yscale; } } turtle = new CLSTurtle(startAngle, 0 - Xmin, 0 - Ymin, xoff, yoff, xscale, yscale); } for (int pos = 0; pos < path.length(); pos++) { switch (path.charAt(pos)) { case '+': turtle.rotate(rotAngle); break; case '-': turtle.rotate(-rotAngle); break; case '(': turtleStack.push(turtle); turtle = new CLSTurtle(turtle); break; case ')': turtle = (CLSTurtle) turtleStack.pop(); break; case 'f': turtle.jump(); break; case 'F': if (g == null) { includePt(turtle.X, turtle.Y); turtle.jump(); includePt(turtle.X, turtle.Y); } else { turtle.draw(g); } break; default: break; } } } void includePt(float x, float y) { if (x < Xmin) Xmin = x; if (x > Xmax) Xmax = x; if (y < Ymin) Ymin = y; if (y > Ymax) Ymax = y; } } /** * A Logo turtle class designed to support Context sensitive L-Systems. * * This turtle performs a few basic maneuvers needed to support the * set of characters used in Context sensitive L-Systems "+-fF[]". * * @author Jim Graham * @version 1.1f, 27 Mar 1995 */ class CLSTurtle { float angle; float X; float Y; float scaleX; float scaleY; int xoff; int yoff; public CLSTurtle(float ang, float x, float y, int xorg, int yorg, float sx, float sy) { angle = ang; scaleX = sx; scaleY = sy; X = x * sx; Y = y * sy; xoff = xorg; yoff = yorg; } public CLSTurtle(CLSTurtle turtle) { angle = turtle.angle; X = turtle.X; Y = turtle.Y; scaleX = turtle.scaleX; scaleY = turtle.scaleY; xoff = turtle.xoff; yoff = turtle.yoff; } public void rotate(float theta) { angle += theta; } public void jump() { X += (float) Math.cos(angle) * scaleX; Y += (float) Math.sin(angle) * scaleY; } public void draw(Graphics g) { float x = X + (float) Math.cos(angle) * scaleX; float y = Y + (float) Math.sin(angle) * scaleY; g.drawLine((int) X + xoff, (int) Y + yoff, (int) x + xoff, (int) y + yoff); X = x; Y = y; } } /** * A (non-)Context sensitive L-System class. * * This class initializes the rules for Context sensitive L-Systems * (pred, succ, lContext, rContext) from the given java.applet.Applet's attributes. * The generate() method, however, does not (yet) apply the lContext * and rContext parts of the rules. * * @author Jim Graham * @version 1.1f, 27 Mar 1995 */ class ContextLSystem { String axiom; Vector rules = new Vector(); int level; public ContextLSystem(java.applet.Applet app) { axiom = app.getParameter("axiom"); int num = 1; while (true) { String pred = app.getParameter("pred"+num); String succ = app.getParameter("succ"+num); if (pred == null || succ == null) { break; } rules.addElement(new CLSRule(pred, succ, app.getParameter("lContext"+num), app.getParameter("rContext"+num))); num++; } currentPath = new StringBuffer(axiom); level = 0; } public int getLevel() { return level; } StringBuffer currentPath; public synchronized String getPath() { return ((currentPath == null) ? null : currentPath.toString()); } private synchronized void setPath(StringBuffer path) { currentPath = path; level++; } public void generate() { StringBuffer newPath = new StringBuffer(); int pos = 0; while (pos < currentPath.length()) { CLSRule rule = findRule(pos); if (rule == null) { newPath.append(currentPath.charAt(pos)); pos++; } else { newPath.append(rule.succ); pos += rule.pred.length(); } } setPath(newPath); } public CLSRule findRule(int pos) { for (int i = 0; i < rules.size(); i++) { CLSRule rule = (CLSRule) rules.elementAt(i); if (rule.matches(currentPath, pos)) { return rule; } } return null; } } /** * A Context sensitive L-System production rule. * * This class encapsulates a production rule for a Context sensitive * L-System (pred, succ, lContext, rContext). * The matches() method, however, does not (yet) verify the lContext * and rContext parts of the rule. * * @author Jim Graham * @version 1.1f, 27 Mar 1995 */ class CLSRule { String pred; String succ; String lContext; String rContext; public CLSRule(String p, String d, String l, String r) { pred = p; succ = d; lContext = l; rContext = r; } public boolean matches(StringBuffer sb, int pos) { if (pos + pred.length() > sb.length()) { return false; } char cb[] = new char[pred.length()]; sb.getChars(pos, pos + pred.length(), cb, 0); return pred.equals(new String(cb)); } } |
[Fraktale (Leitseite)] [Wegfraktale] [Galerie] [Wegfraktale mit Java] [Programme] |
Inhalt und Webbetreuung ©Prof. Dr. Dörte Haftendorn (1996)(2002) Apr. 2005, update |
Direkte Internetadressen [www.doerte-haftendorn.de] [haftendorn.uni-lueneburg.de/mathe-lehramt] |