Monday, July 06, 2009
Forest I
spArrayList trees;
int NUMGENERATIONS = 5;
void setup() {
size(800, 400);
trees = new spArrayList(20);
}
void draw() {
Tree t;
if(trees.size() == 0) {
trees.add(new Tree(new Coordinate(width/2, height - 10)));
}
background(133,221,254);
strokeWeight(10);
stroke(187,209,66);
line(0, height - 5, width, height - 5);
for(int i=0; i < trees.size(); i++) {
t = (Tree)trees.get(i);
t.draw();
if(t.dead && t.colorOffset > 200) {
trees.remove(i);
}
}
}
void mousePressed() {
trees.clear();
}
class spArrayList {
Object[] contents;
boolean[] inUse;
int count;
spArrayList(int s) {
contents = new Object[s];
inUse = new boolean[s];
count = 0;
}
void add(Object o) {
for(int i=0; i < inUse.length; i++) {
if(inUse[i] == false) {
contents[i] = o;
inUse[i] = true;
count++;
break;
}
}
}
void remove(int l) {
int i = 0, j = 0;
while(i < l) {
if(inUse[j]) {
i++;
}
j++;
}
inUse[j] = false;
count--;
}
Object get(int l) {
int i = 0, j = 0;
while(i < l) {
if(inUse[j]) {
i++;
}
j++;
}
return contents[j];
}
int size() {
return count;
}
void clear() {
for(int i=0; i < inUse.length; i++) {
inUse[i] = false;
}
count = 0;
}
}
class Tree {
spArrayList branches = new spArrayList(50);
spArrayList fruits = new spArrayList(50);
float x, y;
boolean dead = false;
int colorOffset = 0;
Tree(Coordinate c) {
this.x = x;
this.y = y;
branches.add(new Branch(this, c, -1, 0, 1));
}
void draw() {
Branch b;
Fruit f;
for(int i = 0; i < branches.size(); i++) {
b = (Branch)branches.get(i);
b.grow();
b.draw();
}
for(int i = 0; i < fruits.size(); i++) {
f = (Fruit)fruits.get(i);
f.grow();
f.draw();
if(f.dead) {
fruits.remove(i);
}
}
if(dead == false && random(1000) > 998) {
colorOffset = 10;
dead = true;
}
if(dead) {
colorOffset += 3;
}
}
}
class Branch {
Coordinate s, e;
float dy, dx;
int l = 0, g, fruitSize = 1;
boolean growing = true, madeFruit = false;
Tree p;
Branch(Tree parent, Coordinate start, float dy, float dx, int generation) {
p = parent;
s = start;
e = new Coordinate(s.x, s.y);
this.dy = dy;
this.dx = dx;
g = generation;
}
void grow() {
if(growing) {
float pDiv;
e.x += dx;
e.y += dy;
l++;
pDiv = (float)g * sq((float)l/100);
if(random(1) < pDiv) {
if(g < NUMGENERATIONS) {
p.branches.add(new Branch(p, e, random(-3, -1), random(-3, 0), g+1));
p.branches.add(new Branch(p, e, random(-3, -1), random(0, 3), g+1));
}
growing = false;
}
}
}
void draw() {
strokeWeight(NUMGENERATIONS-g);
stroke(143 - p.colorOffset, 119 - p.colorOffset, 91 - p.colorOffset, 255 - p.colorOffset);
line(s.x, s.y, e.x, e.y);
if(growing == false && g == NUMGENERATIONS && madeFruit == false) {
p.fruits.add(new Fruit(e));
madeFruit = true;
} else if(growing == false && g > 2) {
noStroke();
fill(42 - p.colorOffset, 191 - p.colorOffset, 26 - p.colorOffset, 255 - p.colorOffset);
ellipse(e.x, e.y, 5, 10);
}
}
}
class Fruit {
float dy = 0;
Coordinate l;
int fruitSize = 1;
boolean dead = false;
Fruit(Coordinate location) {
l = new Coordinate(location.x, location.y);
}
void grow() {
if(fruitSize < 7) {
fruitSize++;
} else {
if(random(1) > 0.9) {
dy = 10;
}
}
if(l.y < height - 10) {
l.y += dy;
} else if(l.y >= height - 10) {
if(random(1) > 0.1) {
dead = true;
} else {
trees.add(new Tree(l));
}
}
}
void draw() {
noStroke();
fill(184,22,40);
ellipse(l.x, l.y, fruitSize, fruitSize);
}
}
class Coordinate {
float x, y;
Coordinate(float x, float y) {
this.x = x;
this.y = y;
}
}
int NUMGENERATIONS = 5;
void setup() {
size(800, 400);
trees = new spArrayList(20);
}
void draw() {
Tree t;
if(trees.size() == 0) {
trees.add(new Tree(new Coordinate(width/2, height - 10)));
}
background(133,221,254);
strokeWeight(10);
stroke(187,209,66);
line(0, height - 5, width, height - 5);
for(int i=0; i < trees.size(); i++) {
t = (Tree)trees.get(i);
t.draw();
if(t.dead && t.colorOffset > 200) {
trees.remove(i);
}
}
}
void mousePressed() {
trees.clear();
}
class spArrayList {
Object[] contents;
boolean[] inUse;
int count;
spArrayList(int s) {
contents = new Object[s];
inUse = new boolean[s];
count = 0;
}
void add(Object o) {
for(int i=0; i < inUse.length; i++) {
if(inUse[i] == false) {
contents[i] = o;
inUse[i] = true;
count++;
break;
}
}
}
void remove(int l) {
int i = 0, j = 0;
while(i < l) {
if(inUse[j]) {
i++;
}
j++;
}
inUse[j] = false;
count--;
}
Object get(int l) {
int i = 0, j = 0;
while(i < l) {
if(inUse[j]) {
i++;
}
j++;
}
return contents[j];
}
int size() {
return count;
}
void clear() {
for(int i=0; i < inUse.length; i++) {
inUse[i] = false;
}
count = 0;
}
}
class Tree {
spArrayList branches = new spArrayList(50);
spArrayList fruits = new spArrayList(50);
float x, y;
boolean dead = false;
int colorOffset = 0;
Tree(Coordinate c) {
this.x = x;
this.y = y;
branches.add(new Branch(this, c, -1, 0, 1));
}
void draw() {
Branch b;
Fruit f;
for(int i = 0; i < branches.size(); i++) {
b = (Branch)branches.get(i);
b.grow();
b.draw();
}
for(int i = 0; i < fruits.size(); i++) {
f = (Fruit)fruits.get(i);
f.grow();
f.draw();
if(f.dead) {
fruits.remove(i);
}
}
if(dead == false && random(1000) > 998) {
colorOffset = 10;
dead = true;
}
if(dead) {
colorOffset += 3;
}
}
}
class Branch {
Coordinate s, e;
float dy, dx;
int l = 0, g, fruitSize = 1;
boolean growing = true, madeFruit = false;
Tree p;
Branch(Tree parent, Coordinate start, float dy, float dx, int generation) {
p = parent;
s = start;
e = new Coordinate(s.x, s.y);
this.dy = dy;
this.dx = dx;
g = generation;
}
void grow() {
if(growing) {
float pDiv;
e.x += dx;
e.y += dy;
l++;
pDiv = (float)g * sq((float)l/100);
if(random(1) < pDiv) {
if(g < NUMGENERATIONS) {
p.branches.add(new Branch(p, e, random(-3, -1), random(-3, 0), g+1));
p.branches.add(new Branch(p, e, random(-3, -1), random(0, 3), g+1));
}
growing = false;
}
}
}
void draw() {
strokeWeight(NUMGENERATIONS-g);
stroke(143 - p.colorOffset, 119 - p.colorOffset, 91 - p.colorOffset, 255 - p.colorOffset);
line(s.x, s.y, e.x, e.y);
if(growing == false && g == NUMGENERATIONS && madeFruit == false) {
p.fruits.add(new Fruit(e));
madeFruit = true;
} else if(growing == false && g > 2) {
noStroke();
fill(42 - p.colorOffset, 191 - p.colorOffset, 26 - p.colorOffset, 255 - p.colorOffset);
ellipse(e.x, e.y, 5, 10);
}
}
}
class Fruit {
float dy = 0;
Coordinate l;
int fruitSize = 1;
boolean dead = false;
Fruit(Coordinate location) {
l = new Coordinate(location.x, location.y);
}
void grow() {
if(fruitSize < 7) {
fruitSize++;
} else {
if(random(1) > 0.9) {
dy = 10;
}
}
if(l.y < height - 10) {
l.y += dy;
} else if(l.y >= height - 10) {
if(random(1) > 0.1) {
dead = true;
} else {
trees.add(new Tree(l));
}
}
}
void draw() {
noStroke();
fill(184,22,40);
ellipse(l.x, l.y, fruitSize, fruitSize);
}
}
class Coordinate {
float x, y;
Coordinate(float x, float y) {
this.x = x;
this.y = y;
}
}
info
submitted by: jon_stuttersviews: 1903
First (fairly crude) attempt at a generative forest. So much more that I want to do with this - animals, nutrients, weather, more realistic fruiting - but I thought at this point it was interesting enough to share.
comments
loading...
Add a comment: