// pinetree forest
import processing.opengl.*;
float rotationX, rotationY, velocityX, velocityY = 0;
ArrayList trees = new ArrayList();
void setup() {
size(800, 600, OPENGL);
for (int i = 0; i < 120; i++)
{
trees.add( new Tree( random(50, 160), new PVector(random(-400, 400), 0, random(-400, 400)) ) );
}
}
void draw()
{
background(242);
rotationX += velocityX;
rotationY += velocityY;
velocityX *= 0.95;
velocityY *= 0.95;
pushMatrix();
translate(width/2, height/2, 0);
rotateX(radians(-TWO_PI-rotationX));
rotateY(radians(-rotationY));
for (int i = 0; i < trees.size(); i++) {
Tree tree = (Tree) trees.get(i);
tree.render();
}
popMatrix();
if(mousePressed){
velocityX += (mouseY-pmouseY) * 0.05;
velocityY -= (mouseX-pmouseX) * 0.05;
}
}
class Tree
{
float treeHeight;
float baseRadius;
float x;
float z;
float theta = 0.0f;
ArrayList coords = new ArrayList();
PVector initPos;
Tree(float _treeHeight, PVector _initPos)
{
treeHeight = _treeHeight;
baseRadius = _treeHeight/4;
initPos = _initPos;
}
void render()
{
//trunk
stroke(#342F02);
for (int t=0; t<treeHeight; t++){
float trunkWidth = map(t, 0, treeHeight, treeHeight/16, 0.1);
strokeWeight(trunkWidth);
line(initPos.x,initPos.y,initPos.z,initPos.x,-t,initPos.z);
}
for(float i = 0; i < baseRadius; i++){
baseRadius -= 1;
drawBranch(baseRadius);
}
for(int i = 0; i < coords.size(); i+=2) {
x = (Float) coords.get(i);
z = (Float) coords.get(i+1);
float branchW = map(i, 0, coords.size(), 3, 0.1);
strokeWeight(branchW);
stroke(#054D0B, 150);
pushMatrix();
translate(0, (treeHeight/2)-6, 0);
line(initPos.x,(-i/3)-(treeHeight/2)-2,initPos.z, x,(-i/3)-treeHeight/2,z);
popMatrix();
}
}
//branches
void drawBranch (float radius)
{
for (int i = 0; i < TWO_PI; i++){
x = initPos.x + radius * cos(theta);
z = initPos.z + radius * sin(theta);
coords.add(x);
coords.add(z);
theta += 1;
}
}
}