sim.app.lsystem.LSystemDrawer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mason Show documentation
Show all versions of mason Show documentation
MASON is a fast discrete-event multiagent simulation library core in Java, designed to be the foundation for large custom-purpose Java simulations, and also to provide more than enough functionality for many lightweight simulation needs. MASON contains both a model library and an optional suite of visualization tools in 2D and 3D.
The newest version!
/*
Copyright 2006 by Daniel Kuebrich
Licensed under the Academic Free License version 3.0
See the file "LICENSE" for more information
*/
package sim.app.lsystem;
import sim.util.*;
import sim.engine.*;
// This is the steppable that interprets the fully expanded l-system
public class LSystemDrawer implements Steppable
{
private static final long serialVersionUID = 1;
// copy the code over so that you can draw while calculating
ByteList code;
// draw settings remain local so that no changes are made mid-draw
int draw_time;
double x,y,theta, angle;
double segsize;
// used to keep track of popping and pushing positions
// Bags have pop() and push() functions in addition to normal list functions
// Meaning that they can be used either way, or as both... freaky.
public Bag stack;
// draw segment name
Segment s;
// we can stop when done drawing
public Stoppable stopper;
LSystemDrawer( LSystemData l )
{
// copy copy copy
this.code = new ByteList(l.code);
this.x = l.x;
this.y = l.y;
this.angle = l.angle;
this.theta = l.theta;
this.segsize = l.segsize;
// -1 is an odd number to initialize to, but seems the best choice for the step loop
draw_time = -1;
stack = new Bag();
}
public void step( final SimState state )
{
// draw stuff
LSystem ls = (LSystem)state;
while(true)
{
draw_time++;
// If done, then stop the sim
if(draw_time >= code.length)
{
if(stopper!=null) stopper.stop();
return;
}
// stack functionality
if(code.b[draw_time] == ((byte)'[')) // push
{
// using a double3d.. except the z is actually the angle
stack.push(new Double3D(x,y,theta));
}
else if(code.b[draw_time] == ((byte)']')) // pop
{
Double3D d = (Double3D)stack.pop();
x = d.x;
y = d.y;
theta = d.z;
}
// else normal stuff
// rotate
else if(code.b[draw_time] == ((byte)'-'))
theta += angle;
// rotate
else if(code.b[draw_time] == ((byte)'+'))
theta -= angle;
// if it's a capital letter, draw forward
else if(code.b[draw_time] >= ((byte)'A') && code.b[draw_time] <= ((byte)'Z'))
{
// draw a segment there
s = new Segment(x,y,segsize,theta);
ls.drawEnvironment.setObjectLocation(s, new Double2D(s.x, s.y));
x += (segsize * /*Strict*/Math.cos(theta));
y += (segsize * /*Strict*/Math.sin(theta));
break;
}
// if it's a lowercase letter, skip forward but don't draw
else if(code.b[draw_time] >= ((byte)'a') && code.b[draw_time] <= ((byte)'z'))
{
// don't draw, just skip the space
x += (segsize * /*Strict*/Math.cos(theta));
y += (segsize * /*Strict*/Math.sin(theta));
}
else
{
// this should never happen except on bad user input
System.err.println("Error--bad code: " + (char)code.b[draw_time] );
break;
}
}
// end while
}
// end step
}
// end class
© 2015 - 2025 Weber Informatics LLC | Privacy Policy