Laser Cut – Fallen Leaves
./wp-content/uploads/sites/2/2013/10/screen_output.pdf
This is my first attempt at data visualization. Each leaf represents the amount of deaths per 100,000 people caused by a category of cancer in 2009. The size of each leaf is proportional to square root of 5 to those numbers.
The tree is also generated by Processing by consecutively drawing smaller rectangles. The leaves are made from Bezier curves.
I was inspired by “Epilogue” by The Antlers in regards to cancer.
Thanks to CDC for their data.
http://apps.nccd.cdc.gov/uscs/cancersbyraceandethnicity.aspx
int square_width = 15;
import processing.pdf.*;
PVector[] leaves;
// these represent cancer death rate per 100,000 people in 2009 US
// data from CDC http://apps.nccd.cdc.gov/uscs/cancersbyraceandethnicity.aspx
float[] rates = {3.7, 54.6, 64.3, 1.5, 5.7, 0.3, 22.4, 13.7,
0.1, 5.3, 0.8, 8.6, 4.2, 9.5, 1.5, 14.9};
void setup() {
randomSeed(15251);
smooth();
noLoop();
size(640, 640 , PDF, "output.pdf");
//size(640, 640);
}
void draw() {
background(255);
fill(0);
pushMatrix();
translate(width/2-50, 0);
scale(0.75, -0.75);
draw_trunk(0, 0, 30.0, 200, 30);
popMatrix();
noFill();
leaves = new PVector[rates.length];
for(int i = 0; i < rates.length; i++)
{
pushMatrix();
float r = rates[i];
float x = random(30, width - 30);
float y = 250+4*r+random(-30, 200);
// loop through old leaves
for(int j = 0; j < i; j++)
{
float old_x = leaves[j].x;
float old_y = leaves[j].y;
// if similar position, set new
if((old_x + 50.0 > x && old_x - 50.0 < x) ||
(old_y + 50.0 > y && old_y - 50.0 < y))
{
x = random(30, width - 30);
y = 250+4*r+random(-30, 200);
}
}
leaves[i] = new PVector(x, y);
translate(x, y);
rotate(radians(random(-170, -10)));
scale(pow(r, 0.2), pow(r, 0.2));
draw_leaf(0.0,0.0);
popMatrix();
}
exit();
}
void draw_leaf(float x, float y)
{
bezier(x+10, y-3,
x+5, y-8,
x-5, y-8,
x-10, y);
bezier(x+10, y+3,
x+5, y+8,
x-5, y+8,
x-10, y);
strokeWeight(0.7);
bezier(x+15, y,
x+12, y-2,
x-2, y+2,
x-5, y);
strokeWeight(0.3);
line(x+7, y, x+5, y-3);
line(x+7, y, x+5, y+4);
line(x+3, y+0.2, x+1, y-3);
line(x+3, y+0.2, x+1, y+4);
line(x-1, y+0.2, x-3, y-3);
line(x-1, y+0.2, x-3, y+3.5);
strokeWeight(1);
}
void draw_trunk(int x, int y, float tree_thickness, int tree_height, int segments)
{
pushMatrix();
float current_tree_thickness = tree_thickness;
float segment_height = tree_height/segments;
translate(x,y);
for(int i = 0; i < segments; i++)
{
translate(0, -segment_height);
rect(0, 0, current_tree_thickness, segment_height*2.0);
rotate(random(-0.1,0.1));
current_tree_thickness *= 0.97;
}
for(int i = 0; i < 10; i++)
{
float random_scale = random(0.3, 3.0);
draw_branch(0,0,radians(random(-30,40)),random_scale, random_direction());
}
popMatrix();
}
void draw_branch(int x, int y, float theta, float curve_scale, int direction)
{
float len = 20.0;
float branch_width = 5.0;
pushMatrix();
translate(x,y);
rotate(theta*-1*direction);
scale(direction, 1);
if(direction < 0.0)
translate(-25,0);
else
translate(-20,0);
int branch_blocks = (int)random(2, 6);
for(int i = 0; i < 80; i++)
{
translate(len, 0);
rotate(random(-0.15, 0.05));
rect(0,0,len,branch_width);
branch_width *= 0.9;
len = len*0.9;
}
popMatrix();
}
int random_direction()
{
if(random(-1,1) > 0)
return 1;
else
return -1;
}