83 lines
2.2 KiB
Plaintext
83 lines
2.2 KiB
Plaintext
// The Nature of Code
|
|
// Daniel Shiffman
|
|
// http://natureofcode.com
|
|
|
|
// Pathfinding w/ Genetic Algorithms
|
|
|
|
// DNA is an array of vectors
|
|
|
|
class DNA {
|
|
|
|
// The genetic sequence
|
|
PVector[] genes;
|
|
|
|
// Constructor (makes a DNA of random PVectors)
|
|
DNA(int num) {
|
|
genes = new PVector[num];
|
|
for (int i = 0; i < genes.length; i++) {
|
|
genes[i] = PVector.random2D();
|
|
}
|
|
}
|
|
|
|
// Constructor #2, creates the instance based on an existing array
|
|
DNA(PVector[] newgenes) {
|
|
// We could make a copy if necessary
|
|
// genes = (PVector []) newgenes.clone();
|
|
genes = newgenes;
|
|
}
|
|
|
|
// CROSSOVER
|
|
// Creates new DNA sequence from two (this & and a partner)
|
|
DNA crossover(DNA partner) {
|
|
PVector[] child = new PVector[genes.length];
|
|
// Pick a midpoint
|
|
int crossover = int(random(genes.length));
|
|
// Take "half" from one and "half" from the other
|
|
for (int i = 0; i < genes.length; i++) {
|
|
if (i > crossover) child[i] = genes[i];
|
|
else child[i] = partner.genes[i];
|
|
}
|
|
DNA newgenes = new DNA(child);
|
|
return newgenes;
|
|
}
|
|
|
|
// Based on a mutation probability, picks a new random Vector
|
|
void mutate(float m) {
|
|
for (int i = 0; i < genes.length; i++) {
|
|
if (random(1) < m) {
|
|
genes[i] = PVector.random2D();
|
|
}
|
|
}
|
|
}
|
|
|
|
void debugDraw() {
|
|
int cols = width / gridscale;
|
|
int rows = height / gridscale;
|
|
for (int i = 0; i < cols; i++) {
|
|
for (int j = 0; j < rows; j++) {
|
|
drawVector(genes[i+j*cols],i*gridscale,j*gridscale,gridscale-2);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Renders a vector object 'v' as an arrow and a position 'x,y'
|
|
void drawVector(PVector v, float x, float y, float scayl) {
|
|
pushMatrix();
|
|
float arrowsize = 4;
|
|
// Translate to position to render vector
|
|
translate(x+gridscale/2,y);
|
|
stroke(0,100);
|
|
// Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate
|
|
rotate(v.heading());
|
|
// Calculate length of vector & scale it to be bigger or smaller if necessary
|
|
float len = v.mag()*scayl;
|
|
// Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction)
|
|
line(-len/2,0,len/2,0);
|
|
//noFill();
|
|
//ellipse(-len/2,0,2,2);
|
|
popMatrix();
|
|
}
|
|
|
|
}
|
|
|