提交 ed328ea1 编写于 作者: M mrkam

7027682: /applets/Fractal demo needs to be improved

Reviewed-by: alexp
上级 4e480fb9
/* /*
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
...@@ -29,13 +29,13 @@ ...@@ -29,13 +29,13 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*
*/
import java.awt.Graphics; import java.awt.Graphics;
import java.util.Stack; import java.util.Stack;
import java.util.Vector;
import java.awt.event.*; import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
/** /**
* A (not-yet) Context sensitive L-System Fractal applet class. * A (not-yet) Context sensitive L-System Fractal applet class.
...@@ -50,9 +50,11 @@ import java.awt.event.*; ...@@ -50,9 +50,11 @@ import java.awt.event.*;
* *
* @author Jim Graham * @author Jim Graham
*/ */
@SuppressWarnings("serial")
public class CLSFractal public class CLSFractal
extends java.applet.Applet extends java.applet.Applet
implements Runnable, MouseListener { implements Runnable, MouseListener {
Thread kicker; Thread kicker;
ContextLSystem cls; ContextLSystem cls;
int fractLevel = 1; int fractLevel = 1;
...@@ -67,31 +69,48 @@ public class CLSFractal ...@@ -67,31 +69,48 @@ public class CLSFractal
int border; int border;
boolean normalizescaling; boolean normalizescaling;
@Override
public void init() { public void init() {
String s; String s;
cls = new ContextLSystem(this); cls = new ContextLSystem(this);
s = getParameter("level"); s = getParameter("level");
if (s != null) fractLevel = Integer.parseInt(s); if (s != null) {
fractLevel = Integer.parseInt(s);
}
s = getParameter("incremental"); s = getParameter("incremental");
if (s != null) incrementalUpdates = s.equalsIgnoreCase("true"); if (s != null) {
incrementalUpdates = s.equalsIgnoreCase("true");
}
s = getParameter("delay"); s = getParameter("delay");
if (s != null) repaintDelay = Integer.parseInt(s); if (s != null) {
repaintDelay = Integer.parseInt(s);
}
s = getParameter("startAngle"); s = getParameter("startAngle");
if (s != null) startAngle = Float.valueOf(s).floatValue(); if (s != null) {
startAngle = Float.valueOf(s).floatValue();
}
s = getParameter("rotAngle"); s = getParameter("rotAngle");
if (s != null) rotAngle = Float.valueOf(s).floatValue(); if (s != null) {
rotAngle = Float.valueOf(s).floatValue();
}
rotAngle = rotAngle / 360 * 2 * 3.14159265358f; rotAngle = rotAngle / 360 * 2 * 3.14159265358f;
s = getParameter("border"); s = getParameter("border");
if (s != null) border = Integer.parseInt(s); if (s != null) {
border = Integer.parseInt(s);
}
s = getParameter("normalizescale"); s = getParameter("normalizescale");
if (s != null) normalizescaling = s.equalsIgnoreCase("true"); if (s != null) {
normalizescaling = s.equalsIgnoreCase("true");
}
addMouseListener(this); addMouseListener(this);
} }
@Override
public void destroy() { public void destroy() {
removeMouseListener(this); removeMouseListener(this);
} }
@Override
public void run() { public void run() {
Thread me = Thread.currentThread(); Thread me = Thread.currentThread();
boolean needsRepaint = false; boolean needsRepaint = false;
...@@ -99,7 +118,10 @@ public class CLSFractal ...@@ -99,7 +118,10 @@ public class CLSFractal
cls.generate(); cls.generate();
if (kicker == me && incrementalUpdates) { if (kicker == me && incrementalUpdates) {
repaint(); repaint();
try {Thread.sleep(repaintDelay);} catch (InterruptedException e){} try {
Thread.sleep(repaintDelay);
} catch (InterruptedException ignored) {
}
} else { } else {
needsRepaint = true; needsRepaint = true;
} }
...@@ -112,22 +134,27 @@ public class CLSFractal ...@@ -112,22 +134,27 @@ public class CLSFractal
} }
} }
@Override
public void start() { public void start() {
kicker = new Thread(this); kicker = new Thread(this);
kicker.start(); kicker.start();
} }
@Override
public void stop() { public void stop() {
kicker = null; kicker = null;
} }
/*1.1 event handling */ /*1.1 event handling */
@Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
} }
@Override
public void mousePressed(MouseEvent e) { public void mousePressed(MouseEvent e) {
} }
@Override
public void mouseReleased(MouseEvent e) { public void mouseReleased(MouseEvent e) {
cls = new ContextLSystem(this); cls = new ContextLSystem(this);
savedPath = null; savedPath = null;
...@@ -135,14 +162,16 @@ public class CLSFractal ...@@ -135,14 +162,16 @@ public class CLSFractal
e.consume(); e.consume();
} }
@Override
public void mouseEntered(MouseEvent e) { public void mouseEntered(MouseEvent e) {
} }
@Override
public void mouseExited(MouseEvent e) { public void mouseExited(MouseEvent e) {
} }
String savedPath; String savedPath;
@Override
public void paint(Graphics g) { public void paint(Graphics g) {
String fractalPath = cls.getPath(); String fractalPath = cls.getPath();
if (fractalPath == null) { if (fractalPath == null) {
...@@ -155,13 +184,14 @@ public class CLSFractal ...@@ -155,13 +184,14 @@ public class CLSFractal
} }
for (int i = 0; i < border; i++) { for (int i = 0; i < border; i++) {
g.draw3DRect(i, i, getSize().width - i * 2, getSize().height - i * 2,false); g.draw3DRect(i, i, getSize().width - i * 2, getSize().height - i * 2,
false);
} }
render(g, fractalPath); render(g, fractalPath);
} }
void render(Graphics g, String path) { void render(Graphics g, String path) {
Stack turtleStack = new Stack(); Stack<CLSTurtle> turtleStack = new Stack<CLSTurtle>();
CLSTurtle turtle; CLSTurtle turtle;
if (g == null) { if (g == null) {
...@@ -172,11 +202,13 @@ public class CLSFractal ...@@ -172,11 +202,13 @@ public class CLSFractal
turtle = new CLSTurtle(startAngle, 0, 0, 0, 0, 1, 1); turtle = new CLSTurtle(startAngle, 0, 0, 0, 0, 1, 1);
} else { } else {
float frwidth = Xmax - Xmin; float frwidth = Xmax - Xmin;
if (frwidth == 0) if (frwidth == 0) {
frwidth = 1; frwidth = 1;
}
float frheight = Ymax - Ymin; float frheight = Ymax - Ymin;
if (frheight == 0) if (frheight == 0) {
frheight = 1; frheight = 1;
}
float xscale = (getSize().width - border * 2 - 1) / frwidth; float xscale = (getSize().width - border * 2 - 1) / frwidth;
float yscale = (getSize().height - border * 2 - 1) / frheight; float yscale = (getSize().height - border * 2 - 1) / frheight;
int xoff = border; int xoff = border;
...@@ -184,84 +216,102 @@ public class CLSFractal ...@@ -184,84 +216,102 @@ public class CLSFractal
if (normalizescaling) { if (normalizescaling) {
if (xscale < yscale) { if (xscale < yscale) {
yoff += ((getSize().height - border * 2) yoff += ((getSize().height - border * 2)
- ((Ymax - Ymin) * xscale)) / 2; - ((Ymax - Ymin) * xscale)) / 2;
yscale = xscale; yscale = xscale;
} else if (yscale < xscale) { } else if (yscale < xscale) {
xoff += ((getSize().width - border * 2) xoff += ((getSize().width - border * 2)
- ((Xmax - Xmin) * yscale)) / 2; - ((Xmax - Xmin) * yscale)) / 2;
xscale = yscale; xscale = yscale;
} }
} }
turtle = new CLSTurtle(startAngle, 0 - Xmin, 0 - Ymin, turtle = new CLSTurtle(startAngle, 0 - Xmin, 0 - Ymin,
xoff, yoff, xscale, yscale); xoff, yoff, xscale, yscale);
} }
for (int pos = 0; pos < path.length(); pos++) { for (int pos = 0; pos < path.length(); pos++) {
switch (path.charAt(pos)) { switch (path.charAt(pos)) {
case '+': case '+':
turtle.rotate(rotAngle); turtle.rotate(rotAngle);
break; break;
case '-': case '-':
turtle.rotate(-rotAngle); turtle.rotate(-rotAngle);
break; break;
case '[': case '[':
turtleStack.push(turtle); turtleStack.push(turtle);
turtle = new CLSTurtle(turtle); turtle = new CLSTurtle(turtle);
break; break;
case ']': case ']':
turtle = (CLSTurtle) turtleStack.pop(); turtle = turtleStack.pop();
break; break;
case 'f': case 'f':
turtle.jump();
break;
case 'F':
if (g == null) {
includePt(turtle.X, turtle.Y);
turtle.jump(); turtle.jump();
includePt(turtle.X, turtle.Y); break;
} else { case 'F':
turtle.draw(g); if (g == null) {
} includePt(turtle.X, turtle.Y);
break; turtle.jump();
default: includePt(turtle.X, turtle.Y);
break; } else {
turtle.draw(g);
}
break;
default:
break;
} }
} }
} }
void includePt(float x, float y) { void includePt(float x, float y) {
if (x < Xmin) if (x < Xmin) {
Xmin = x; Xmin = x;
if (x > Xmax) }
if (x > Xmax) {
Xmax = x; Xmax = x;
if (y < Ymin) }
if (y < Ymin) {
Ymin = y; Ymin = y;
if (y > Ymax) }
if (y > Ymax) {
Ymax = y; Ymax = y;
}
}
@Override
public String getAppletInfo() {
return "Title: CLSFractal 1.1f, 27 Mar 1995 \nAuthor: Jim Graham \nA "
+ "(not yet) Context Sensitive L-System production rule. \n"
+ "This 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 String getAppletInfo() { @Override
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 String[][] getParameterInfo() {
} String[][] info = {
{ "level", "int", "Maximum number of recursions. Default is 1." },
public String[][] getParameterInfo() { { "incremental", "boolean", "Whether or not to repaint between "
String[][] info = { + "recursions. Default is true." },
{"level", "int", "Maximum number of recursions. Default is 1."}, { "delay", "integer", "Sets delay between repaints. Default is 50." },
{"incremental","boolean","Whether or not to repaint between recursions. Default is true."}, { "startAngle", "float", "Sets the starting angle. Default is 0." },
{"delay","integer","Sets delay between repaints. Default is 50."}, { "rotAngle", "float", "Sets the rotation angle. Default is 45." },
{"startAngle","float","Sets the starting angle. Default is 0."}, { "border", "integer", "Width of border. Default is 2." },
{"rotAngle","float","Sets the rotation angle. Default is 45."}, { "normalizeScale", "boolean", "Whether or not to normalize "
{"border","integer","Width of border. Default is 2."}, + "the scaling. Default is true." },
{"normalizeScale","boolean","Whether or not to normalize the scaling. Default is true."}, { "pred", "String",
{"pred","String","Initializes the rules for Context Sensitive L-Systems."}, "Initializes the rules for Context Sensitive L-Systems." },
{"succ","String","Initializes the rules for Context Sensitive L-Systems."}, { "succ", "String",
{"lContext","String","Initializes the rules for Context Sensitive L-Systems."}, "Initializes the rules for Context Sensitive L-Systems." },
{"rContext","String","Initializes the rules for Context Sensitive L-Systems."} { "lContext", "String",
}; "Initializes the rules for Context Sensitive L-Systems." },
return info; { "rContext", "String",
} "Initializes the rules for Context Sensitive L-Systems." }
};
return info;
}
} }
/** /**
* A Logo turtle class designed to support Context sensitive L-Systems. * A Logo turtle class designed to support Context sensitive L-Systems.
* *
...@@ -271,6 +321,7 @@ public class CLSFractal ...@@ -271,6 +321,7 @@ public class CLSFractal
* @author Jim Graham * @author Jim Graham
*/ */
class CLSTurtle { class CLSTurtle {
float angle; float angle;
float X; float X;
float Y; float Y;
...@@ -280,7 +331,7 @@ class CLSTurtle { ...@@ -280,7 +331,7 @@ class CLSTurtle {
int yoff; int yoff;
public CLSTurtle(float ang, float x, float y, public CLSTurtle(float ang, float x, float y,
int xorg, int yorg, float sx, float sy) { int xorg, int yorg, float sx, float sy) {
angle = ang; angle = ang;
scaleX = sx; scaleX = sx;
scaleY = sy; scaleY = sy;
...@@ -313,12 +364,13 @@ class CLSTurtle { ...@@ -313,12 +364,13 @@ class CLSTurtle {
float x = X + (float) Math.cos(angle) * scaleX; float x = X + (float) Math.cos(angle) * scaleX;
float y = Y + (float) Math.sin(angle) * scaleY; float y = Y + (float) Math.sin(angle) * scaleY;
g.drawLine((int) X + xoff, (int) Y + yoff, g.drawLine((int) X + xoff, (int) Y + yoff,
(int) x + xoff, (int) y + yoff); (int) x + xoff, (int) y + yoff);
X = x; X = x;
Y = y; Y = y;
} }
} }
/** /**
* A (non-)Context sensitive L-System class. * A (non-)Context sensitive L-System class.
* *
...@@ -330,22 +382,23 @@ class CLSTurtle { ...@@ -330,22 +382,23 @@ class CLSTurtle {
* @author Jim Graham * @author Jim Graham
*/ */
class ContextLSystem { class ContextLSystem {
String axiom; String axiom;
Vector rules = new Vector(); List<CLSRule> rules = new ArrayList<CLSRule>();
int level; int level;
public ContextLSystem(java.applet.Applet app) { public ContextLSystem(java.applet.Applet app) {
axiom = app.getParameter("axiom"); axiom = app.getParameter("axiom");
int num = 1; int num = 1;
while (true) { while (true) {
String pred = app.getParameter("pred"+num); String pred = app.getParameter("pred" + num);
String succ = app.getParameter("succ"+num); String succ = app.getParameter("succ" + num);
if (pred == null || succ == null) { if (pred == null || succ == null) {
break; break;
} }
rules.addElement(new CLSRule(pred, succ, rules.add(new CLSRule(pred, succ,
app.getParameter("lContext"+num), app.getParameter("lContext" + num),
app.getParameter("rContext"+num))); app.getParameter("rContext" + num)));
num++; num++;
} }
currentPath = new StringBuffer(axiom); currentPath = new StringBuffer(axiom);
...@@ -355,7 +408,6 @@ class ContextLSystem { ...@@ -355,7 +408,6 @@ class ContextLSystem {
public int getLevel() { public int getLevel() {
return level; return level;
} }
StringBuffer currentPath; StringBuffer currentPath;
public synchronized String getPath() { public synchronized String getPath() {
...@@ -385,7 +437,7 @@ class ContextLSystem { ...@@ -385,7 +437,7 @@ class ContextLSystem {
public CLSRule findRule(int pos) { public CLSRule findRule(int pos) {
for (int i = 0; i < rules.size(); i++) { for (int i = 0; i < rules.size(); i++) {
CLSRule rule = (CLSRule) rules.elementAt(i); CLSRule rule = rules.get(i);
if (rule.matches(currentPath, pos)) { if (rule.matches(currentPath, pos)) {
return rule; return rule;
} }
...@@ -394,6 +446,7 @@ class ContextLSystem { ...@@ -394,6 +446,7 @@ class ContextLSystem {
} }
} }
/** /**
* A Context sensitive L-System production rule. * A Context sensitive L-System production rule.
* *
...@@ -405,6 +458,7 @@ class ContextLSystem { ...@@ -405,6 +458,7 @@ class ContextLSystem {
* @author Jim Graham * @author Jim Graham
*/ */
class CLSRule { class CLSRule {
String pred; String pred;
String succ; String succ;
String lContext; String lContext;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<body> <body>
<h1>Fractals 1.1</h1> <h1>Fractals 1.1</h1>
<hr> <hr>
<applet applet code="CLSFractal.class" width=500 height=120> <applet code="CLSFractal.class" width=500 height=120>
<param name=level value="5"> <param name=level value="5">
<param name=rotangle value="45"> <param name=rotangle value="45">
<param name=succ1 value="F-F++F-F"> <param name=succ1 value="F-F++F-F">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册