Initial Commit
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Koch Curve
|
||||
* by Daniel Shiffman.
|
||||
*
|
||||
* Renders a simple fractal, the Koch snowflake.
|
||||
* Each recursive level is drawn in sequence.
|
||||
*/
|
||||
|
||||
|
||||
KochFractal k;
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
frameRate(1); // Animate slowly
|
||||
k = new KochFractal();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
// Draws the snowflake!
|
||||
k.render();
|
||||
// Iterate
|
||||
k.nextLevel();
|
||||
// Let's not do it more than 5 times. . .
|
||||
if (k.getCount() > 5) {
|
||||
k.restart();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// Koch Curve
|
||||
// A class to manage the list of line segments in the snowflake pattern
|
||||
|
||||
class KochFractal {
|
||||
PVector start; // A PVector for the start
|
||||
PVector end; // A PVector for the end
|
||||
ArrayList<KochLine> lines; // A list to keep track of all the lines
|
||||
int count;
|
||||
|
||||
KochFractal() {
|
||||
start = new PVector(0,height-20);
|
||||
end = new PVector(width,height-20);
|
||||
lines = new ArrayList<KochLine>();
|
||||
restart();
|
||||
}
|
||||
|
||||
void nextLevel() {
|
||||
// For every line that is in the arraylist
|
||||
// create 4 more lines in a new arraylist
|
||||
lines = iterate(lines);
|
||||
count++;
|
||||
}
|
||||
|
||||
void restart() {
|
||||
count = 0; // Reset count
|
||||
lines.clear(); // Empty the array list
|
||||
lines.add(new KochLine(start,end)); // Add the initial line (from one end PVector to the other)
|
||||
}
|
||||
|
||||
int getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
// This is easy, just draw all the lines
|
||||
void render() {
|
||||
for(KochLine l : lines) {
|
||||
l.display();
|
||||
}
|
||||
}
|
||||
|
||||
// This is where the **MAGIC** happens
|
||||
// Step 1: Create an empty arraylist
|
||||
// Step 2: For every line currently in the arraylist
|
||||
// - calculate 4 line segments based on Koch algorithm
|
||||
// - add all 4 line segments into the new arraylist
|
||||
// Step 3: Return the new arraylist and it becomes the list of line segments for the structure
|
||||
|
||||
// As we do this over and over again, each line gets broken into 4 lines, which gets broken into 4 lines, and so on. . .
|
||||
ArrayList iterate(ArrayList<KochLine> before) {
|
||||
ArrayList now = new ArrayList<KochLine>(); // Create emtpy list
|
||||
for(KochLine l : before) {
|
||||
// Calculate 5 koch PVectors (done for us by the line object)
|
||||
PVector a = l.start();
|
||||
PVector b = l.kochleft();
|
||||
PVector c = l.kochmiddle();
|
||||
PVector d = l.kochright();
|
||||
PVector e = l.end();
|
||||
// Make line segments between all the PVectors and add them
|
||||
now.add(new KochLine(a,b));
|
||||
now.add(new KochLine(b,c));
|
||||
now.add(new KochLine(c,d));
|
||||
now.add(new KochLine(d,e));
|
||||
}
|
||||
return now;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
// The Nature of Code
|
||||
// Daniel Shiffman
|
||||
// http://natureofcode.com
|
||||
|
||||
// Koch Curve
|
||||
// A class to describe one line segment in the fractal
|
||||
// Includes methods to calculate midPVectors along the line according to the Koch algorithm
|
||||
|
||||
class KochLine {
|
||||
|
||||
// Two PVectors,
|
||||
// a is the "left" PVector and
|
||||
// b is the "right PVector
|
||||
PVector a;
|
||||
PVector b;
|
||||
|
||||
KochLine(PVector start, PVector end) {
|
||||
a = start.copy();
|
||||
b = end.copy();
|
||||
}
|
||||
|
||||
void display() {
|
||||
stroke(255);
|
||||
line(a.x, a.y, b.x, b.y);
|
||||
}
|
||||
|
||||
PVector start() {
|
||||
return a.copy();
|
||||
}
|
||||
|
||||
PVector end() {
|
||||
return b.copy();
|
||||
}
|
||||
|
||||
// This is easy, just 1/3 of the way
|
||||
PVector kochleft() {
|
||||
PVector v = PVector.sub(b, a);
|
||||
v.div(3);
|
||||
v.add(a);
|
||||
return v;
|
||||
}
|
||||
|
||||
// More complicated, have to use a little trig to figure out where this PVector is!
|
||||
PVector kochmiddle() {
|
||||
PVector v = PVector.sub(b, a);
|
||||
v.div(3);
|
||||
|
||||
PVector p = a.copy();
|
||||
p.add(v);
|
||||
|
||||
v.rotate(-radians(60));
|
||||
p.add(v);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
// Easy, just 2/3 of the way
|
||||
PVector kochright() {
|
||||
PVector v = PVector.sub(a, b);
|
||||
v.div(3);
|
||||
v.add(b);
|
||||
return v;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* The Mandelbrot Set
|
||||
* by Daniel Shiffman.
|
||||
*
|
||||
* Simple rendering of the Mandelbrot set.
|
||||
*/
|
||||
|
||||
size(640, 360);
|
||||
noLoop();
|
||||
background(255);
|
||||
|
||||
// Establish a range of values on the complex plane
|
||||
// A different range will allow us to "zoom" in or out on the fractal
|
||||
|
||||
// It all starts with the width, try higher or lower values
|
||||
float w = 4;
|
||||
float h = (w * height) / width;
|
||||
|
||||
// Start at negative half the width and height
|
||||
float xmin = -w/2;
|
||||
float ymin = -h/2;
|
||||
|
||||
// Make sure we can write to the pixels[] array.
|
||||
// Only need to do this once since we don't do any other drawing.
|
||||
loadPixels();
|
||||
|
||||
// Maximum number of iterations for each point on the complex plane
|
||||
int maxiterations = 100;
|
||||
|
||||
// x goes from xmin to xmax
|
||||
float xmax = xmin + w;
|
||||
// y goes from ymin to ymax
|
||||
float ymax = ymin + h;
|
||||
|
||||
// Calculate amount we increment x,y for each pixel
|
||||
float dx = (xmax - xmin) / (width);
|
||||
float dy = (ymax - ymin) / (height);
|
||||
|
||||
// Start y
|
||||
float y = ymin;
|
||||
for (int j = 0; j < height; j++) {
|
||||
// Start x
|
||||
float x = xmin;
|
||||
for (int i = 0; i < width; i++) {
|
||||
|
||||
// Now we test, as we iterate z = z^2 + cm does z tend towards infinity?
|
||||
float a = x;
|
||||
float b = y;
|
||||
int n = 0;
|
||||
while (n < maxiterations) {
|
||||
float aa = a * a;
|
||||
float bb = b * b;
|
||||
float twoab = 2.0 * a * b;
|
||||
a = aa - bb + x;
|
||||
b = twoab + y;
|
||||
// Infinty in our finite world is simple, let's just consider it 16
|
||||
if (dist(aa, bb, 0, 0) > 4.0) {
|
||||
break; // Bail
|
||||
}
|
||||
n++;
|
||||
}
|
||||
|
||||
// We color each pixel based on how long it takes to get to infinity
|
||||
// If we never got there, let's pick the color black
|
||||
if (n == maxiterations) {
|
||||
pixels[i+j*width] = color(0);
|
||||
} else {
|
||||
// Gosh, we could make fancy colors here if we wanted
|
||||
float norm = map(n, 0, maxiterations, 0, 1);
|
||||
pixels[i+j*width] = color(map(sqrt(norm), 0, 1, 0, 255));
|
||||
}
|
||||
x += dx;
|
||||
}
|
||||
y += dy;
|
||||
}
|
||||
updatePixels();
|
||||
@@ -0,0 +1,76 @@
|
||||
class LSystem
|
||||
{
|
||||
int steps = 0;
|
||||
|
||||
String axiom;
|
||||
String rule;
|
||||
String production;
|
||||
|
||||
float startLength;
|
||||
float drawLength;
|
||||
float theta;
|
||||
|
||||
int generations;
|
||||
|
||||
LSystem() {
|
||||
axiom = "F";
|
||||
rule = "F+F-F";
|
||||
startLength = 90.0;
|
||||
theta = radians(120.0);
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
production = axiom;
|
||||
drawLength = startLength;
|
||||
generations = 0;
|
||||
}
|
||||
|
||||
int getAge() {
|
||||
return generations;
|
||||
}
|
||||
|
||||
void render() {
|
||||
translate(width/2, height/2);
|
||||
steps += 5;
|
||||
if (steps > production.length()) {
|
||||
steps = production.length();
|
||||
}
|
||||
for (int i = 0; i < steps; i++) {
|
||||
char step = production.charAt(i);
|
||||
if (step == 'F') {
|
||||
rect(0, 0, -drawLength, -drawLength);
|
||||
noFill();
|
||||
translate(0, -drawLength);
|
||||
}
|
||||
else if (step == '+') {
|
||||
rotate(theta);
|
||||
}
|
||||
else if (step == '-') {
|
||||
rotate(-theta);
|
||||
}
|
||||
else if (step == '[') {
|
||||
pushMatrix();
|
||||
}
|
||||
else if (step == ']') {
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void simulate(int gen) {
|
||||
while (getAge() < gen) {
|
||||
production = iterate(production, rule);
|
||||
}
|
||||
}
|
||||
|
||||
String iterate(String prod_, String rule_) {
|
||||
drawLength = drawLength * 0.6;
|
||||
generations++;
|
||||
String newProduction = prod_;
|
||||
newProduction = newProduction.replaceAll("F", rule_);
|
||||
return newProduction;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Penrose Snowflake L-System
|
||||
* by Geraldine Sarmiento.
|
||||
*
|
||||
* This code was based on Patrick Dwyer's L-System class.
|
||||
*/
|
||||
|
||||
PenroseSnowflakeLSystem ps;
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
stroke(255);
|
||||
noFill();
|
||||
ps = new PenroseSnowflakeLSystem();
|
||||
ps.simulate(4);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
ps.render();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
class PenroseSnowflakeLSystem extends LSystem {
|
||||
|
||||
String ruleF;
|
||||
|
||||
PenroseSnowflakeLSystem() {
|
||||
axiom = "F3-F3-F3-F3-F";
|
||||
ruleF = "F3-F3-F45-F++F3-F";
|
||||
startLength = 450.0;
|
||||
theta = radians(18);
|
||||
reset();
|
||||
}
|
||||
|
||||
void useRule(String r_) {
|
||||
rule = r_;
|
||||
}
|
||||
|
||||
void useAxiom(String a_) {
|
||||
axiom = a_;
|
||||
}
|
||||
|
||||
void useLength(float l_) {
|
||||
startLength = l_;
|
||||
}
|
||||
|
||||
void useTheta(float t_) {
|
||||
theta = radians(t_);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
production = axiom;
|
||||
drawLength = startLength;
|
||||
generations = 0;
|
||||
}
|
||||
|
||||
int getAge() {
|
||||
return generations;
|
||||
}
|
||||
|
||||
void render() {
|
||||
translate(width, height);
|
||||
int repeats = 1;
|
||||
|
||||
steps += 3;
|
||||
if (steps > production.length()) {
|
||||
steps = production.length();
|
||||
}
|
||||
|
||||
for (int i = 0; i < steps; i++) {
|
||||
char step = production.charAt(i);
|
||||
if (step == 'F') {
|
||||
for (int j = 0; j < repeats; j++) {
|
||||
line(0,0,0, -drawLength);
|
||||
translate(0, -drawLength);
|
||||
}
|
||||
repeats = 1;
|
||||
}
|
||||
else if (step == '+') {
|
||||
for (int j = 0; j < repeats; j++) {
|
||||
rotate(theta);
|
||||
}
|
||||
repeats = 1;
|
||||
}
|
||||
else if (step == '-') {
|
||||
for (int j =0; j < repeats; j++) {
|
||||
rotate(-theta);
|
||||
}
|
||||
repeats = 1;
|
||||
}
|
||||
else if (step == '[') {
|
||||
pushMatrix();
|
||||
}
|
||||
else if (step == ']') {
|
||||
popMatrix();
|
||||
}
|
||||
else if ( (step >= 48) && (step <= 57) ) {
|
||||
repeats += step - 48;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String iterate(String prod_, String rule_) {
|
||||
String newProduction = "";
|
||||
for (int i = 0; i < prod_.length(); i++) {
|
||||
char step = production.charAt(i);
|
||||
if (step == 'F') {
|
||||
newProduction = newProduction + ruleF;
|
||||
}
|
||||
else {
|
||||
if (step != 'F') {
|
||||
newProduction = newProduction + step;
|
||||
}
|
||||
}
|
||||
}
|
||||
drawLength = drawLength * 0.4;
|
||||
generations++;
|
||||
return newProduction;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
class LSystem
|
||||
{
|
||||
int steps = 0;
|
||||
|
||||
String axiom;
|
||||
String rule;
|
||||
String production;
|
||||
|
||||
float startLength;
|
||||
float drawLength;
|
||||
float theta;
|
||||
|
||||
int generations;
|
||||
|
||||
LSystem() {
|
||||
axiom = "F";
|
||||
rule = "F+F-F";
|
||||
startLength = 190.0;
|
||||
theta = radians(120.0);
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
production = axiom;
|
||||
drawLength = startLength;
|
||||
generations = 0;
|
||||
}
|
||||
|
||||
int getAge() {
|
||||
return generations;
|
||||
}
|
||||
|
||||
void render() {
|
||||
translate(width/2, height/2);
|
||||
steps += 5;
|
||||
if (steps > production.length()) {
|
||||
steps = production.length();
|
||||
}
|
||||
for (int i = 0; i < steps; i++) {
|
||||
char step = production.charAt(i);
|
||||
if (step == 'F') {
|
||||
rect(0, 0, -drawLength, -drawLength);
|
||||
noFill();
|
||||
translate(0, -drawLength);
|
||||
}
|
||||
else if (step == '+') {
|
||||
rotate(theta);
|
||||
}
|
||||
else if (step == '-') {
|
||||
rotate(-theta);
|
||||
}
|
||||
else if (step == '[') {
|
||||
pushMatrix();
|
||||
}
|
||||
else if (step == ']') {
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void simulate(int gen) {
|
||||
while (getAge() < gen) {
|
||||
production = iterate(production, rule);
|
||||
}
|
||||
}
|
||||
|
||||
String iterate(String prod_, String rule_) {
|
||||
drawLength = drawLength * 0.6;
|
||||
generations++;
|
||||
String newProduction = prod_;
|
||||
newProduction = newProduction.replaceAll("F", rule_);
|
||||
return newProduction;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
class PenroseLSystem extends LSystem {
|
||||
|
||||
int steps = 0;
|
||||
float somestep = 0.1;
|
||||
String ruleW;
|
||||
String ruleX;
|
||||
String ruleY;
|
||||
String ruleZ;
|
||||
|
||||
PenroseLSystem() {
|
||||
axiom = "[X]++[X]++[X]++[X]++[X]";
|
||||
ruleW = "YF++ZF4-XF[-YF4-WF]++";
|
||||
ruleX = "+YF--ZF[3-WF--XF]+";
|
||||
ruleY = "-WF++XF[+++YF++ZF]-";
|
||||
ruleZ = "--YF++++WF[+ZF++++XF]--XF";
|
||||
startLength = 460.0;
|
||||
theta = radians(36);
|
||||
reset();
|
||||
}
|
||||
|
||||
void useRule(String r_) {
|
||||
rule = r_;
|
||||
}
|
||||
|
||||
void useAxiom(String a_) {
|
||||
axiom = a_;
|
||||
}
|
||||
|
||||
void useLength(float l_) {
|
||||
startLength = l_;
|
||||
}
|
||||
|
||||
void useTheta(float t_) {
|
||||
theta = radians(t_);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
production = axiom;
|
||||
drawLength = startLength;
|
||||
generations = 0;
|
||||
}
|
||||
|
||||
int getAge() {
|
||||
return generations;
|
||||
}
|
||||
|
||||
void render() {
|
||||
translate(width/2, height/2);
|
||||
int pushes = 0;
|
||||
int repeats = 1;
|
||||
steps += 12;
|
||||
if (steps > production.length()) {
|
||||
steps = production.length();
|
||||
}
|
||||
|
||||
for (int i = 0; i < steps; i++) {
|
||||
char step = production.charAt(i);
|
||||
if (step == 'F') {
|
||||
stroke(255, 60);
|
||||
for (int j = 0; j < repeats; j++) {
|
||||
line(0, 0, 0, -drawLength);
|
||||
noFill();
|
||||
translate(0, -drawLength);
|
||||
}
|
||||
repeats = 1;
|
||||
}
|
||||
else if (step == '+') {
|
||||
for (int j = 0; j < repeats; j++) {
|
||||
rotate(theta);
|
||||
}
|
||||
repeats = 1;
|
||||
}
|
||||
else if (step == '-') {
|
||||
for (int j =0; j < repeats; j++) {
|
||||
rotate(-theta);
|
||||
}
|
||||
repeats = 1;
|
||||
}
|
||||
else if (step == '[') {
|
||||
pushes++;
|
||||
pushMatrix();
|
||||
}
|
||||
else if (step == ']') {
|
||||
popMatrix();
|
||||
pushes--;
|
||||
}
|
||||
else if ( (step >= 48) && (step <= 57) ) {
|
||||
repeats = (int)step - 48;
|
||||
}
|
||||
}
|
||||
|
||||
// Unpush if we need too
|
||||
while (pushes > 0) {
|
||||
popMatrix();
|
||||
pushes--;
|
||||
}
|
||||
}
|
||||
|
||||
String iterate(String prod_, String rule_) {
|
||||
String newProduction = "";
|
||||
for (int i = 0; i < prod_.length(); i++) {
|
||||
char step = production.charAt(i);
|
||||
if (step == 'W') {
|
||||
newProduction = newProduction + ruleW;
|
||||
}
|
||||
else if (step == 'X') {
|
||||
newProduction = newProduction + ruleX;
|
||||
}
|
||||
else if (step == 'Y') {
|
||||
newProduction = newProduction + ruleY;
|
||||
}
|
||||
else if (step == 'Z') {
|
||||
newProduction = newProduction + ruleZ;
|
||||
}
|
||||
else {
|
||||
if (step != 'F') {
|
||||
newProduction = newProduction + step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drawLength = drawLength * 0.5;
|
||||
generations++;
|
||||
return newProduction;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Penrose Tile L-System
|
||||
* by Geraldine Sarmiento.
|
||||
*
|
||||
* This code was based on Patrick Dwyer's L-System class.
|
||||
*/
|
||||
|
||||
PenroseLSystem ds;
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
ds = new PenroseLSystem();
|
||||
ds.simulate(4);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
ds.render();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
class LSystem {
|
||||
|
||||
int steps = 0;
|
||||
|
||||
String axiom;
|
||||
String rule;
|
||||
String production;
|
||||
|
||||
float startLength;
|
||||
float drawLength;
|
||||
float theta;
|
||||
|
||||
int generations;
|
||||
|
||||
LSystem() {
|
||||
|
||||
axiom = "F";
|
||||
rule = "F+F-F";
|
||||
startLength = 90.0;
|
||||
theta = radians(120.0);
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
production = axiom;
|
||||
drawLength = startLength;
|
||||
generations = 0;
|
||||
}
|
||||
|
||||
int getAge() {
|
||||
return generations;
|
||||
}
|
||||
|
||||
void render() {
|
||||
translate(width/2, height/2);
|
||||
steps += 5;
|
||||
if (steps > production.length()) {
|
||||
steps = production.length();
|
||||
}
|
||||
for (int i = 0; i < steps; i++) {
|
||||
char step = production.charAt(i);
|
||||
if (step == 'F') {
|
||||
rect(0, 0, -drawLength, -drawLength);
|
||||
noFill();
|
||||
translate(0, -drawLength);
|
||||
}
|
||||
else if (step == '+') {
|
||||
rotate(theta);
|
||||
}
|
||||
else if (step == '-') {
|
||||
rotate(-theta);
|
||||
}
|
||||
else if (step == '[') {
|
||||
pushMatrix();
|
||||
}
|
||||
else if (step == ']') {
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void simulate(int gen) {
|
||||
while (getAge() < gen) {
|
||||
production = iterate(production, rule);
|
||||
}
|
||||
}
|
||||
|
||||
String iterate(String prod_, String rule_) {
|
||||
drawLength = drawLength * 0.6;
|
||||
generations++;
|
||||
String newProduction = prod_;
|
||||
newProduction = newProduction.replaceAll("F", rule_);
|
||||
return newProduction;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Pentigree L-System
|
||||
* by Geraldine Sarmiento.
|
||||
*
|
||||
* This code was based on Patrick Dwyer's L-System class.
|
||||
*/
|
||||
|
||||
|
||||
PentigreeLSystem ps;
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
ps = new PentigreeLSystem();
|
||||
ps.simulate(3);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
ps.render();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
class PentigreeLSystem extends LSystem {
|
||||
|
||||
int steps = 0;
|
||||
float somestep = 0.1;
|
||||
float xoff = 0.01;
|
||||
|
||||
PentigreeLSystem() {
|
||||
axiom = "F-F-F-F-F";
|
||||
rule = "F-F++F+F-F-F";
|
||||
startLength = 60.0;
|
||||
theta = radians(72);
|
||||
reset();
|
||||
}
|
||||
|
||||
void useRule(String r_) {
|
||||
rule = r_;
|
||||
}
|
||||
|
||||
void useAxiom(String a_) {
|
||||
axiom = a_;
|
||||
}
|
||||
|
||||
void useLength(float l_) {
|
||||
startLength = l_;
|
||||
}
|
||||
|
||||
void useTheta(float t_) {
|
||||
theta = radians(t_);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
production = axiom;
|
||||
drawLength = startLength;
|
||||
generations = 0;
|
||||
}
|
||||
|
||||
int getAge() {
|
||||
return generations;
|
||||
}
|
||||
|
||||
void render() {
|
||||
translate(width/4, height/2);
|
||||
steps += 3;
|
||||
if (steps > production.length()) {
|
||||
steps = production.length();
|
||||
}
|
||||
|
||||
for (int i = 0; i < steps; i++) {
|
||||
char step = production.charAt(i);
|
||||
if (step == 'F') {
|
||||
noFill();
|
||||
stroke(255);
|
||||
line(0, 0, 0, -drawLength);
|
||||
translate(0, -drawLength);
|
||||
}
|
||||
else if (step == '+') {
|
||||
rotate(theta);
|
||||
}
|
||||
else if (step == '-') {
|
||||
rotate(-theta);
|
||||
}
|
||||
else if (step == '[') {
|
||||
pushMatrix();
|
||||
}
|
||||
else if (step == ']') {
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Recursive Tree
|
||||
* by Daniel Shiffman.
|
||||
*
|
||||
* Renders a simple tree-like structure via recursion.
|
||||
* The branching angle is calculated as a function of
|
||||
* the horizontal mouse location. Move the mouse left
|
||||
* and right to change the angle.
|
||||
*/
|
||||
|
||||
float theta;
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
frameRate(30);
|
||||
stroke(255);
|
||||
// Let's pick an angle 0 to 90 degrees based on the mouse position
|
||||
float a = (mouseX / (float) width) * 90f;
|
||||
// Convert it to radians
|
||||
theta = radians(a);
|
||||
// Start the tree from the bottom of the screen
|
||||
translate(width/2,height);
|
||||
// Draw a line 120 pixels
|
||||
line(0,0,0,-120);
|
||||
// Move to the end of that line
|
||||
translate(0,-120);
|
||||
// Start the recursive branching!
|
||||
branch(120);
|
||||
|
||||
}
|
||||
|
||||
void branch(float h) {
|
||||
// Each branch will be 2/3rds the size of the previous one
|
||||
h *= 0.66;
|
||||
|
||||
// All recursive functions must have an exit condition!!!!
|
||||
// Here, ours is when the length of the branch is 2 pixels or less
|
||||
if (h > 2) {
|
||||
pushMatrix(); // Save the current state of transformation (i.e. where are we now)
|
||||
rotate(theta); // Rotate by theta
|
||||
line(0, 0, 0, -h); // Draw the branch
|
||||
translate(0, -h); // Move to the end of the branch
|
||||
branch(h); // Ok, now call myself to draw two new branches!!
|
||||
popMatrix(); // Whenever we get back here, we "pop" in order to restore the previous matrix state
|
||||
|
||||
// Repeat the same thing, only branch off to the "left" this time!
|
||||
pushMatrix();
|
||||
rotate(-theta);
|
||||
line(0, 0, 0, -h);
|
||||
translate(0, -h);
|
||||
branch(h);
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user