42 import java.awt.Graphics;
43 import java.util.Stack;
44 import java.awt.event.*;
45 import java.util.ArrayList;
46 import java.util.List;
62 @SuppressWarnings(
"serial")
65 implements Runnable, MouseListener {
70 int repaintDelay = 50;
85 s = getParameter(
"level");
87 fractLevel = Integer.parseInt(s);
89 s = getParameter(
"incremental");
91 incrementalUpdates = s.equalsIgnoreCase(
"true");
93 s = getParameter(
"delay");
95 repaintDelay = Integer.parseInt(s);
97 s = getParameter(
"startAngle");
99 startAngle = Float.valueOf(s).floatValue();
101 s = getParameter(
"rotAngle");
103 rotAngle = Float.valueOf(s).floatValue();
105 rotAngle = rotAngle / 360 * 2 * 3.14159265358f;
106 s = getParameter(
"border");
108 border = Integer.parseInt(s);
110 s = getParameter(
"normalizescale");
112 normalizescaling = s.equalsIgnoreCase(
"true");
114 addMouseListener(
this);
119 removeMouseListener(
this);
124 Thread me = Thread.currentThread();
125 boolean needsRepaint =
false;
126 while (kicker == me && cls.
getLevel() < fractLevel) {
128 if (kicker == me && incrementalUpdates) {
131 Thread.sleep(repaintDelay);
132 }
catch (InterruptedException ignored) {
148 kicker =
new Thread(
this);
185 String fractalPath = cls.
getPath();
186 if (fractalPath ==
null) {
190 if (savedPath ==
null || !savedPath.equals(fractalPath)) {
191 savedPath = fractalPath;
192 render(
null, fractalPath);
195 for (
int i = 0; i < border; i++) {
196 g.draw3DRect(i, i, getSize().width - i * 2, getSize().height - i * 2,
199 render(g, fractalPath);
203 Stack<CLSTurtle> turtleStack =
new Stack<CLSTurtle>();
211 turtle =
new CLSTurtle(startAngle, 0, 0, 0, 0, 1, 1);
213 float frwidth = Xmax - Xmin;
217 float frheight = Ymax - Ymin;
221 float xscale = (getSize().width - border * 2 - 1) / frwidth;
222 float yscale = (getSize().height - border * 2 - 1) / frheight;
225 if (normalizescaling) {
226 if (xscale < yscale) {
227 yoff += ((getSize().height - border * 2)
228 - ((Ymax - Ymin) * xscale)) / 2;
230 }
else if (yscale < xscale) {
231 xoff += ((getSize().width - border * 2)
232 - ((Xmax - Xmin) * yscale)) / 2;
236 turtle =
new CLSTurtle(startAngle, 0 - Xmin, 0 - Ymin,
237 xoff, yoff, xscale, yscale);
240 for (
int pos = 0; pos <
path.length(); pos++) {
241 switch (
path.charAt(pos)) {
249 turtleStack.push(turtle);
253 turtle = turtleStack.pop();
260 includePt(turtle.
X, turtle.
Y);
262 includePt(turtle.
X, turtle.
Y);
290 return "Title: CLSFractal 1.1f, 27 Mar 1995 \nAuthor: Jim Graham \nA "
291 +
"(not yet) Context Sensitive L-System production rule. \n"
292 +
"This class encapsulates a production rule for a Context "
293 +
"Sensitive\n L-System \n(pred, succ, lContext, rContext)."
294 +
" The matches() method, however, does not \n(yet) verify "
295 +
"the lContext and rContext parts of the rule.";
301 {
"level",
"int",
"Maximum number of recursions. Default is 1." },
302 {
"incremental",
"boolean",
"Whether or not to repaint between "
303 +
"recursions. Default is true." },
304 {
"delay",
"integer",
"Sets delay between repaints. Default is 50." },
305 {
"startAngle",
"float",
"Sets the starting angle. Default is 0." },
306 {
"rotAngle",
"float",
"Sets the rotation angle. Default is 45." },
307 {
"border",
"integer",
"Width of border. Default is 2." },
308 {
"normalizeScale",
"boolean",
"Whether or not to normalize "
309 +
"the scaling. Default is true." },
311 "Initializes the rules for Context Sensitive L-Systems." },
313 "Initializes the rules for Context Sensitive L-Systems." },
314 {
"lContext",
"String",
315 "Initializes the rules for Context Sensitive L-Systems." },
316 {
"rContext",
"String",
317 "Initializes the rules for Context Sensitive L-Systems." }
343 int xorg,
int yorg,
float sx,
float sy) {
396 List<CLSRule>
rules =
new ArrayList<CLSRule>();
400 axiom = app.getParameter(
"axiom");
403 String pred = app.getParameter(
"pred" + num);
404 String succ = app.getParameter(
"succ" + num);
405 if (pred ==
null || succ ==
null) {
409 app.getParameter(
"lContext" + num),
410 app.getParameter(
"rContext" + num)));
432 StringBuffer newPath =
new StringBuffer();
440 newPath.append(rule.
succ);
441 pos += rule.
pred.length();
448 for (
int i = 0; i <
rules.size(); i++) {
476 public CLSRule(String p, String d, String l, String r) {
483 public boolean matches(StringBuffer sb,
int pos) {
484 if (pos +
pred.length() > sb.length()) {
487 char cb[] =
new char[
pred.length()];
488 sb.getChars(pos, pos +
pred.length(), cb, 0);
489 return pred.equals(
new String(cb));