|
|
dd8bf2 |
|
|
|
dd8bf2 |
#include <math.h></math.h>
|
|
|
dab153 |
#include <stdlib.h></stdlib.h>
|
|
|
dab153 |
#include <string.h></string.h>
|
|
|
dd8bf2 |
|
|
|
dab153 |
#include <helianthus.h></helianthus.h>
|
|
|
dd8bf2 |
|
|
|
dab153 |
#include "tree.h"
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
|
|
|
dab153 |
static const double segmentLength = 0.2;
|
|
|
dab153 |
static const double segmentWidth = 0.004;
|
|
|
dab153 |
static const double minWidth = 0.02;
|
|
|
dab153 |
static const double rootWidth = 0.8;
|
|
|
815578 |
static const double branchesPerSegment = 0.2;
|
|
|
dab153 |
static const double leafSize = 8;
|
|
|
dab153 |
static const double leafPerBranch = 1;
|
|
|
dab153 |
static const double leafThreshold = 0.02 + 8/4/0.2*0.004; // minWidth + leafSize/4/segmentLength*segmentWidth
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
|
|
|
dab153 |
static double randomRange(double min, double max)
|
|
|
dd8bf2 |
{ return randomFloat()*(max - min) + min; }
|
|
|
dd8bf2 |
|
|
|
dab153 |
static double randomIncrement(double deviation)
|
|
|
dd8bf2 |
{ return randomRange(-deviation, deviation); }
|
|
|
dd8bf2 |
|
|
|
dab153 |
static double randomAmplifier(double deviation)
|
|
|
dd8bf2 |
{ return randomRange(1 - deviation, 1 + deviation); }
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
|
|
|
dab153 |
static void leaf(double x, double y, double size) {
|
|
|
dd8bf2 |
double r = 0.5*size;//*randomAmplifier(0.5);
|
|
|
dd8bf2 |
saveState();
|
|
|
dd8bf2 |
noStroke();
|
|
|
dd8bf2 |
circle(x, y, r);
|
|
|
dd8bf2 |
restoreState();
|
|
|
dd8bf2 |
}
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
|
|
|
815578 |
static void branch(double x, double y, double angle, double width, double time, int flags) {
|
|
|
dab153 |
double da = sin(time*randomRange(0.5, 1) + randomIncrement(PI));
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
saveState();
|
|
|
dd8bf2 |
while(TRUE) {
|
|
|
dd8bf2 |
double length = segmentLength * randomAmplifier(0.1);
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
double s = sin(angle/180*PI);
|
|
|
dd8bf2 |
double c = cos(angle/180*PI);
|
|
|
dd8bf2 |
double nx = x + c*length;
|
|
|
dd8bf2 |
double ny = y + s*length;
|
|
|
dd8bf2 |
double nw = width - segmentWidth;
|
|
|
dd8bf2 |
strokeWidth(width);
|
|
|
dd8bf2 |
line(x, y, nx, ny);
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
if (width > leafThreshold && nw <= leafThreshold && randomFloat() < leafPerBranch && y > leafSize/2) {
|
|
|
dd8bf2 |
double dl = randomRange(0, length);
|
|
|
dd8bf2 |
leaf(x + c*dl, y + s*dl, leafSize);
|
|
|
dd8bf2 |
}
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
if (width < minWidth || ny < 0)
|
|
|
dd8bf2 |
break;
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
x = nx;
|
|
|
dd8bf2 |
y = ny;
|
|
|
dd8bf2 |
s += randomRange(0, 0.2);
|
|
|
dd8bf2 |
c += randomIncrement(0.15);
|
|
|
dd8bf2 |
angle = atan2(s, c)/PI*180;
|
|
|
dd8bf2 |
width -= segmentWidth;
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
translate(x, y);
|
|
|
dd8bf2 |
rotate(da*pow(minWidth/width, 2));
|
|
|
dd8bf2 |
translate(-x, -y);
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
if (randomFloat() < branchesPerSegment) {
|
|
|
815578 |
double k = randomRange(0, 0.3);
|
|
|
dd8bf2 |
double w = sqrt(width*width*k);
|
|
|
dd8bf2 |
if (w > minWidth) {
|
|
|
dd8bf2 |
width = sqrt(width*width*(1-k));
|
|
|
dd8bf2 |
double a = randomNumber(0, 1) ? angle - 90 + randomRange(0, 45)
|
|
|
dd8bf2 |
: angle + 90 - randomRange(0, 45);
|
|
|
815578 |
branch(x, y, a, w, time, flags);
|
|
|
dd8bf2 |
}
|
|
|
dd8bf2 |
}
|
|
|
dd8bf2 |
}
|
|
|
dd8bf2 |
restoreState();
|
|
|
dd8bf2 |
}
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
|
|
|
3395b9 |
void treeGenerate(Tree *t, double x, double y) {
|
|
|
dab153 |
memset(t, 0, sizeof(*t));
|
|
|
dab153 |
t->seed = rand();
|
|
|
3395b9 |
t->x = x;
|
|
|
3395b9 |
t->y = y;
|
|
|
dab153 |
t->angle = 90 + randomIncrement(30);
|
|
|
dab153 |
t->width = rootWidth*randomAmplifier(0.5);
|
|
|
dd8bf2 |
}
|
|
|
dd8bf2 |
|
|
|
dd8bf2 |
|
|
|
3395b9 |
void treeDraw(const Tree *t, double time, int flags) {
|
|
|
dd8bf2 |
saveState();
|
|
|
dab153 |
translate(t->x, t->y);
|
|
|
815578 |
|
|
|
de7236 |
fill(colorByRGBA(0, 0.5, 0, 0.5));
|
|
|
de7236 |
stroke(COLOR_BLACK);
|
|
|
815578 |
srand(t->seed);
|
|
|
de7236 |
branch(0, 0, t->angle, t->width, time, flags);
|
|
|
815578 |
|
|
|
815578 |
restoreState();
|
|
|
815578 |
}
|
|
|
dd8bf2 |
|
|
|
dab153 |
|
|
|
815578 |
void treePrerender(Tree *t, Framebuffer fb) {
|
|
|
815578 |
srand(t->seed);
|
|
|
815578 |
branch(0, 0, t->angle, t->width, 0, FLAG_BOUNDS);
|
|
|
dd8bf2 |
}
|
|
|
dd8bf2 |
|
|
|
815578 |
|
|
|
815578 |
void treeDrawPrerendered(Tree *t);
|