FileDocCategorySizeDatePackage
CLSFractal.javaAPI DocSun JDK 1.5.0 Example12117Sat Jan 08 15:09:02 GMT 2005None

CLSFractal

public class CLSFractal extends Applet implements MouseListener, Runnable
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

Fields Summary
Thread
kicker
ContextLSystem
cls
int
fractLevel
int
repaintDelay
boolean
incrementalUpdates
float
startAngle
float
rotAngle
float
Xmin
float
Xmax
float
Ymin
float
Ymax
int
border
boolean
normalizescaling
String
savedPath
Constructors Summary
Methods Summary
public voiddestroy()

        removeMouseListener(this);
    
public java.lang.StringgetAppletInfo()

    return "Title: CLSFractal 1.1f, 27 Mar 1995 \nAuthor: Jim Graham \nA (not yet) Context Sensitive L-System production rule. \nThis class encapsulates a production rule for a Context Sensitive\n L-System \n(pred, succ, lContext, rContext).  The matches() method, however, does not \n(yet) verify the lContext and rContext parts of the rule.";
  
public java.lang.String[][]getParameterInfo()

    String[][] info = {
      {"level", "int", "Maximum number of recursions.  Default is 1."},
      {"incremental","boolean","Whether or not to repaint between recursions.  Default is true."},
      {"delay","integer","Sets delay between repaints.  Default is 50."},
      {"startAngle","float","Sets the starting angle.  Default is 0."},
      {"rotAngle","float","Sets the rotation angle.  Default is 45."},
      {"border","integer","Width of border.  Default is 2."},
      {"normalizeScale","boolean","Whether or not to normalize the scaling.  Default is true."},
      {"pred","String","Initializes the rules for Context Sensitive L-Systems."},
      {"succ","String","Initializes the rules for Context Sensitive L-Systems."},
      {"lContext","String","Initializes the rules for Context Sensitive L-Systems."},
      {"rContext","String","Initializes the rules for Context Sensitive L-Systems."}
    };
    return info;
  
voidincludePt(float x, float y)

	if (x < Xmin)
	    Xmin = x;
	if (x > Xmax)
	    Xmax = x;
	if (y < Ymin)
	    Ymin = y;
	if (y > Ymax)
	    Ymax = y;
    
public voidinit()


       
	String s;
	cls = new ContextLSystem(this);
	s = getParameter("level");
	if (s != null) fractLevel = Integer.parseInt(s);
	s = getParameter("incremental");
	if (s != null) incrementalUpdates = s.equalsIgnoreCase("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.equalsIgnoreCase("true");
	addMouseListener(this);
    
public voidmouseClicked(java.awt.event.MouseEvent e)

    
public voidmouseEntered(java.awt.event.MouseEvent e)

    
public voidmouseExited(java.awt.event.MouseEvent e)

    
public voidmousePressed(java.awt.event.MouseEvent e)

    
public voidmouseReleased(java.awt.event.MouseEvent e)

        cls = new ContextLSystem(this);
        savedPath = null;
        start();
        e.consume();
    
public voidpaint(java.awt.Graphics g)

	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, getSize().width - i * 2, getSize().height - i * 2,false);
	}
	render(g, fractalPath);
    
voidrender(java.awt.Graphics g, java.lang.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 = (getSize().width - border * 2 - 1) / frwidth;
	    float yscale = (getSize().height - border * 2 - 1) / frheight;
	    int xoff = border;
	    int yoff = border;
	    if (normalizescaling) {
		if (xscale < yscale) {
		    yoff += ((getSize().height - border * 2)
			     - ((Ymax - Ymin) * xscale)) / 2;
		    yscale = xscale;
		} else if (yscale < xscale) {
		    xoff += ((getSize().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;
	    }
	}
    
public voidrun()

	Thread me = Thread.currentThread();
	boolean needsRepaint = false;
	while (kicker == me && cls.getLevel() < fractLevel) {
	    cls.generate();
	    if (kicker == me && incrementalUpdates) {
		repaint();
		try {Thread.sleep(repaintDelay);} catch (InterruptedException e){}
	    } else {
		needsRepaint = true;
	    }
	}
	if (kicker == me) {
	    kicker = null;
	    if (needsRepaint) {
		repaint();
	    }
	}
    
public voidstart()

	kicker = new Thread(this);
	kicker.start();
    
public voidstop()

	kicker = null;