kopia lustrzana https://github.com/villares/sketch-a-day
108 wiersze
3.0 KiB
Plaintext
108 wiersze
3.0 KiB
Plaintext
// The Nature of Code
|
|
// Daniel Shiffman
|
|
// http://natureofcode.com
|
|
// Interactive Selection
|
|
// http://www.genarts.com/karl/papers/siggraph91.html
|
|
|
|
// The class for our "organism", contains DNA sequence, fitness value, position on screen
|
|
// Fitness Function f(t) = t (where t is "time" mouse rolls over organism)
|
|
|
|
class Organism {
|
|
|
|
DNA dna; // organism's DNA
|
|
float fitness; // How good is this organism?
|
|
float x, y; // Position on screen
|
|
int wh = 110; // Size of square enclosing organism
|
|
boolean mouseIsOver; // Are we rolling over this organism?
|
|
float a, ra, rl;
|
|
|
|
// Create a new organism
|
|
Organism(DNA dna_, float x_, float y_) {
|
|
dna = dna_;
|
|
x = x_;
|
|
y = y_;
|
|
fitness = 1;
|
|
}
|
|
|
|
// Display the organism
|
|
void display() {
|
|
// We are using the organism's DNA to pick properties for this organism
|
|
// such as: head size, color, eye position, etc.
|
|
// Now, since every gene is a floating point between 0 and 1, we map the values
|
|
int d = int(map(dna.genes[0], 0, 1, 3, 9)); // degree, number of gens
|
|
a = map(dna.genes[1], 0, 1, 0, HALF_PI); // angle
|
|
ra = map(dna.genes[2], 0, 1, -2, 2); // angle randomizer
|
|
|
|
// Once we calculate all the above properties, we use those variables to draw rects, ellipses, etc.
|
|
pushMatrix();
|
|
translate(x, y);
|
|
randomSeed(int(x + y));
|
|
branch(d, a, wh/9);
|
|
// Draw the bounding box
|
|
pushStyle();
|
|
if (mouseIsOver) fill(0, 0.25);
|
|
else noFill();
|
|
rectMode(CENTER);
|
|
stroke(1);
|
|
rect(0, 0, wh, wh);
|
|
popStyle();
|
|
popMatrix();
|
|
|
|
// Display fitness value
|
|
textAlign(CENTER);
|
|
fill(1);
|
|
text(fitness, x, y+70);
|
|
}
|
|
|
|
float getFitness() {
|
|
return fitness;
|
|
}
|
|
|
|
DNA getDNA() {
|
|
return dna;
|
|
}
|
|
|
|
// Increment fitness if mouse is rolling over organism
|
|
void checkMouseOver(int mx, int my) {
|
|
int cx = int(x-wh/2);
|
|
int cy = int(y-wh/2);
|
|
if (mx > cx && mx < cx + wh && my > cy && my < cy + wh) {
|
|
mouseIsOver = true;
|
|
if (mousePressed) fitness += 0.25;
|
|
} else {
|
|
mouseIsOver = false;
|
|
}
|
|
}
|
|
|
|
|
|
void branch(int gen, float theta, float branch_size) {
|
|
pushStyle();
|
|
//strokeWeight(gen);
|
|
// All recursive functions must have an exit condition!!!!
|
|
if (gen > 0) { // and branch_size > 1:
|
|
pushMatrix();
|
|
stroke(map(gen,0,9,0,1), 1, 1);
|
|
rl = map(dna.genes[3+gen], 0, 1, 0, 10);
|
|
float h = branch_size * (1 - random(rl/2, rl) / 15);
|
|
rotate(theta + ra * random(1)); // Rotate by theta
|
|
line(0, 0, 0, -h); // Draw the branch
|
|
translate(0, -h); // Move to the end of the branch
|
|
// Ok, now call myself to draw two branches!!
|
|
pushStyle();
|
|
branch(gen - 1, theta, h);
|
|
popStyle();
|
|
popMatrix();
|
|
pushMatrix();
|
|
h = branch_size * (1 - random(rl/3, rl) / 15);
|
|
rotate(-theta + ra * random(1));
|
|
line(0, 0, 0, -h);
|
|
translate(0, -h);
|
|
pushStyle();
|
|
branch(gen - 1, theta, h);
|
|
popStyle();
|
|
popMatrix();
|
|
}
|
|
popStyle();
|
|
}
|
|
}
|