Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/demo/applets/Fractal/CLSFractal.java
38827 views
1
/*
2
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
*
8
* - Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
*
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* - Neither the name of Oracle nor the names of its
16
* contributors may be used to endorse or promote products derived
17
* from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
/*
33
* This source code is provided to illustrate the usage of a given feature
34
* or technique and has been deliberately simplified. Additional steps
35
* required for a production-quality application, such as security checks,
36
* input validation and proper error handling, might not be present in
37
* this sample code.
38
*/
39
40
41
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;
47
48
49
/**
50
* A (not-yet) Context sensitive L-System Fractal applet class.
51
*
52
* The rules for the Context L-system are read from the java.applet.Applet's
53
* attributes and then the system is iteratively applied for the
54
* given number of levels, possibly drawing each generation as it
55
* is generated. Note that the ContextLSystem class does not yet
56
* handle the lContext and rContext attributes, although this
57
* class is already designed to parse the '[' and ']' characters
58
* typically used in Context sensitive L-Systems.
59
*
60
* @author Jim Graham
61
*/
62
@SuppressWarnings("serial")
63
public class CLSFractal
64
extends java.applet.Applet
65
implements Runnable, MouseListener {
66
67
Thread kicker;
68
ContextLSystem cls;
69
int fractLevel = 1;
70
int repaintDelay = 50;
71
boolean incrementalUpdates;
72
float startAngle = 0;
73
float rotAngle = 45;
74
float Xmin;
75
float Xmax;
76
float Ymin;
77
float Ymax;
78
int border;
79
boolean normalizescaling;
80
81
@Override
82
public void init() {
83
String s;
84
cls = new ContextLSystem(this);
85
s = getParameter("level");
86
if (s != null) {
87
fractLevel = Integer.parseInt(s);
88
}
89
s = getParameter("incremental");
90
if (s != null) {
91
incrementalUpdates = s.equalsIgnoreCase("true");
92
}
93
s = getParameter("delay");
94
if (s != null) {
95
repaintDelay = Integer.parseInt(s);
96
}
97
s = getParameter("startAngle");
98
if (s != null) {
99
startAngle = Float.valueOf(s).floatValue();
100
}
101
s = getParameter("rotAngle");
102
if (s != null) {
103
rotAngle = Float.valueOf(s).floatValue();
104
}
105
rotAngle = rotAngle / 360 * 2 * 3.14159265358f;
106
s = getParameter("border");
107
if (s != null) {
108
border = Integer.parseInt(s);
109
}
110
s = getParameter("normalizescale");
111
if (s != null) {
112
normalizescaling = s.equalsIgnoreCase("true");
113
}
114
addMouseListener(this);
115
}
116
117
@Override
118
public void destroy() {
119
removeMouseListener(this);
120
}
121
122
@Override
123
public void run() {
124
Thread me = Thread.currentThread();
125
boolean needsRepaint = false;
126
while (kicker == me && cls.getLevel() < fractLevel) {
127
cls.generate();
128
if (kicker == me && incrementalUpdates) {
129
repaint();
130
try {
131
Thread.sleep(repaintDelay);
132
} catch (InterruptedException ignored) {
133
}
134
} else {
135
needsRepaint = true;
136
}
137
}
138
if (kicker == me) {
139
kicker = null;
140
if (needsRepaint) {
141
repaint();
142
}
143
}
144
}
145
146
@Override
147
public void start() {
148
kicker = new Thread(this);
149
kicker.start();
150
}
151
152
@Override
153
public void stop() {
154
kicker = null;
155
}
156
157
/*1.1 event handling */
158
@Override
159
public void mouseClicked(MouseEvent e) {
160
}
161
162
@Override
163
public void mousePressed(MouseEvent e) {
164
}
165
166
@Override
167
public void mouseReleased(MouseEvent e) {
168
cls = new ContextLSystem(this);
169
savedPath = null;
170
start();
171
e.consume();
172
}
173
174
@Override
175
public void mouseEntered(MouseEvent e) {
176
}
177
178
@Override
179
public void mouseExited(MouseEvent e) {
180
}
181
String savedPath;
182
183
@Override
184
public void paint(Graphics g) {
185
String fractalPath = cls.getPath();
186
if (fractalPath == null) {
187
super.paint(g);
188
return;
189
}
190
if (savedPath == null || !savedPath.equals(fractalPath)) {
191
savedPath = fractalPath;
192
render(null, fractalPath);
193
}
194
195
for (int i = 0; i < border; i++) {
196
g.draw3DRect(i, i, getSize().width - i * 2, getSize().height - i * 2,
197
false);
198
}
199
render(g, fractalPath);
200
}
201
202
void render(Graphics g, String path) {
203
Stack<CLSTurtle> turtleStack = new Stack<CLSTurtle>();
204
CLSTurtle turtle;
205
206
if (g == null) {
207
Xmin = 1E20f;
208
Ymin = 1E20f;
209
Xmax = -1E20f;
210
Ymax = -1E20f;
211
turtle = new CLSTurtle(startAngle, 0, 0, 0, 0, 1, 1);
212
} else {
213
float frwidth = Xmax - Xmin;
214
if (frwidth == 0) {
215
frwidth = 1;
216
}
217
float frheight = Ymax - Ymin;
218
if (frheight == 0) {
219
frheight = 1;
220
}
221
float xscale = (getSize().width - border * 2 - 1) / frwidth;
222
float yscale = (getSize().height - border * 2 - 1) / frheight;
223
int xoff = border;
224
int yoff = border;
225
if (normalizescaling) {
226
if (xscale < yscale) {
227
yoff += ((getSize().height - border * 2)
228
- ((Ymax - Ymin) * xscale)) / 2;
229
yscale = xscale;
230
} else if (yscale < xscale) {
231
xoff += ((getSize().width - border * 2)
232
- ((Xmax - Xmin) * yscale)) / 2;
233
xscale = yscale;
234
}
235
}
236
turtle = new CLSTurtle(startAngle, 0 - Xmin, 0 - Ymin,
237
xoff, yoff, xscale, yscale);
238
}
239
240
for (int pos = 0; pos < path.length(); pos++) {
241
switch (path.charAt(pos)) {
242
case '+':
243
turtle.rotate(rotAngle);
244
break;
245
case '-':
246
turtle.rotate(-rotAngle);
247
break;
248
case '[':
249
turtleStack.push(turtle);
250
turtle = new CLSTurtle(turtle);
251
break;
252
case ']':
253
turtle = turtleStack.pop();
254
break;
255
case 'f':
256
turtle.jump();
257
break;
258
case 'F':
259
if (g == null) {
260
includePt(turtle.X, turtle.Y);
261
turtle.jump();
262
includePt(turtle.X, turtle.Y);
263
} else {
264
turtle.draw(g);
265
}
266
break;
267
default:
268
break;
269
}
270
}
271
}
272
273
void includePt(float x, float y) {
274
if (x < Xmin) {
275
Xmin = x;
276
}
277
if (x > Xmax) {
278
Xmax = x;
279
}
280
if (y < Ymin) {
281
Ymin = y;
282
}
283
if (y > Ymax) {
284
Ymax = y;
285
}
286
}
287
288
@Override
289
public String getAppletInfo() {
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.";
296
}
297
298
@Override
299
public String[][] getParameterInfo() {
300
String[][] info = {
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." },
310
{ "pred", "String",
311
"Initializes the rules for Context Sensitive L-Systems." },
312
{ "succ", "String",
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." }
318
};
319
return info;
320
}
321
}
322
323
324
/**
325
* A Logo turtle class designed to support Context sensitive L-Systems.
326
*
327
* This turtle performs a few basic maneuvers needed to support the
328
* set of characters used in Context sensitive L-Systems "+-fF[]".
329
*
330
* @author Jim Graham
331
*/
332
class CLSTurtle {
333
334
float angle;
335
float X;
336
float Y;
337
float scaleX;
338
float scaleY;
339
int xoff;
340
int yoff;
341
342
public CLSTurtle(float ang, float x, float y,
343
int xorg, int yorg, float sx, float sy) {
344
angle = ang;
345
scaleX = sx;
346
scaleY = sy;
347
X = x * sx;
348
Y = y * sy;
349
xoff = xorg;
350
yoff = yorg;
351
}
352
353
public CLSTurtle(CLSTurtle turtle) {
354
angle = turtle.angle;
355
X = turtle.X;
356
Y = turtle.Y;
357
scaleX = turtle.scaleX;
358
scaleY = turtle.scaleY;
359
xoff = turtle.xoff;
360
yoff = turtle.yoff;
361
}
362
363
public void rotate(float theta) {
364
angle += theta;
365
}
366
367
public void jump() {
368
X += (float) Math.cos(angle) * scaleX;
369
Y += (float) Math.sin(angle) * scaleY;
370
}
371
372
public void draw(Graphics g) {
373
float x = X + (float) Math.cos(angle) * scaleX;
374
float y = Y + (float) Math.sin(angle) * scaleY;
375
g.drawLine((int) X + xoff, (int) Y + yoff,
376
(int) x + xoff, (int) y + yoff);
377
X = x;
378
Y = y;
379
}
380
}
381
382
383
/**
384
* A (non-)Context sensitive L-System class.
385
*
386
* This class initializes the rules for Context sensitive L-Systems
387
* (pred, succ, lContext, rContext) from the given java.applet.Applet's attributes.
388
* The generate() method, however, does not (yet) apply the lContext
389
* and rContext parts of the rules.
390
*
391
* @author Jim Graham
392
*/
393
class ContextLSystem {
394
395
String axiom;
396
List<CLSRule> rules = new ArrayList<CLSRule>();
397
int level;
398
399
public ContextLSystem(java.applet.Applet app) {
400
axiom = app.getParameter("axiom");
401
int num = 1;
402
while (true) {
403
String pred = app.getParameter("pred" + num);
404
String succ = app.getParameter("succ" + num);
405
if (pred == null || succ == null) {
406
break;
407
}
408
rules.add(new CLSRule(pred, succ,
409
app.getParameter("lContext" + num),
410
app.getParameter("rContext" + num)));
411
num++;
412
}
413
currentPath = new StringBuffer(axiom);
414
level = 0;
415
}
416
417
public int getLevel() {
418
return level;
419
}
420
StringBuffer currentPath;
421
422
public synchronized String getPath() {
423
return ((currentPath == null) ? null : currentPath.toString());
424
}
425
426
private synchronized void setPath(StringBuffer path) {
427
currentPath = path;
428
level++;
429
}
430
431
public void generate() {
432
StringBuffer newPath = new StringBuffer();
433
int pos = 0;
434
while (pos < currentPath.length()) {
435
CLSRule rule = findRule(pos);
436
if (rule == null) {
437
newPath.append(currentPath.charAt(pos));
438
pos++;
439
} else {
440
newPath.append(rule.succ);
441
pos += rule.pred.length();
442
}
443
}
444
setPath(newPath);
445
}
446
447
public CLSRule findRule(int pos) {
448
for (int i = 0; i < rules.size(); i++) {
449
CLSRule rule = rules.get(i);
450
if (rule.matches(currentPath, pos)) {
451
return rule;
452
}
453
}
454
return null;
455
}
456
}
457
458
459
/**
460
* A Context sensitive L-System production rule.
461
*
462
* This class encapsulates a production rule for a Context sensitive
463
* L-System (pred, succ, lContext, rContext).
464
* The matches() method, however, does not (yet) verify the lContext
465
* and rContext parts of the rule.
466
*
467
* @author Jim Graham
468
*/
469
class CLSRule {
470
471
String pred;
472
String succ;
473
String lContext;
474
String rContext;
475
476
public CLSRule(String p, String d, String l, String r) {
477
pred = p;
478
succ = d;
479
lContext = l;
480
rContext = r;
481
}
482
483
public boolean matches(StringBuffer sb, int pos) {
484
if (pos + pred.length() > sb.length()) {
485
return false;
486
}
487
char cb[] = new char[pred.length()];
488
sb.getChars(pos, pos + pred.length(), cb, 0);
489
return pred.equals(new String(cb));
490
}
491
}
492
493