// FITNESS = Proximity to tx and ty. class Particle { int w; // The particle's index in the array of particles float x, y; // Current position float vx, vy; // Current velocity float xx, yy; // Old position float fitness; float maxVelocity = random(nmaxVelocity, nmaxVelocity2); int age = 0; // The particle's current age int bfage; // The age at which the particle achieved its best fitness int probation = 0; float alpha1 = random(nalpha1, nalpha12); // How much to move towards global best float alpha2 = random(nalpha2, nalpha22); // How much to move towards local best float bf; float bx, by; // Best position boolean isBest; // Is the current particle the best? Particle(int index, float ix, float iy) { // Create a new particle w = index; vx = 0.0; vy = 0.0; if (ix < 0) { x = random(dimX); } else { x = ix; // Kick it vx = random(-maxVelocity, maxVelocity); } if (iy < 0) { y = random(dimY); } else { y = iy; // Kick it vy = random(-maxVelocity, maxVelocity); } bx = x; by = y; bf = fitness(); } float fitness() { float a = (tx - x); float b = (ty - y); return sqrt(a * a + b * b); } void move() { xx = x; yy = y; for (int j = 0; j < nBest; j++) { if (bestIndices.items[j] != w) { float a = particles[bestIndices.items[j]].x - x; float b = particles[bestIndices.items[j]].y - y; a = max(min(a, 1), -1); b = max(min(b, 1), -1); if (isBest) { a *= bestWeighting; b *= bestWeighting; } vx += alpha1 * random(1) * a; vy += alpha1 * random(1) * b; } } // Learn from local best float a = (bx - x); float b = (by - y); a = max(min(a, 1), -1); b = max(min(b, 1), -1); if (isBest) { a *= (1 / bestWeighting); b *= (1 / bestWeighting); } vx += alpha2 * random(1) * a; vy += alpha2 * random(1) * b; vx = max(min(vx, maxVelocity), -maxVelocity); vy = max(min(vy, maxVelocity), -maxVelocity); // Move x += vx; y += vy; // Update local fitness if (fitness() < bf) { bfage = age; bf = fitness(); bx = x; by = y; } age++; probation = max(0, probation - 1); // Draw our movement if (isBest) { } else { noStroke(); if (probation > 0) { fill(255, 102, 0, 192); } else { if (age < 20) { //fill(0, 204, 255, 192); fill(255, 192); } else { fill(255, 204, 0, 192); } } int pSize = 2; ellipse(x, y, pSize, pSize); } } } class MyButton { float x, y; float w, h; color baseColour, highlightColour, currentColour; boolean over = false; boolean pressed = false; String label; MyButton(int ix, int iy, int iw, int ih, color iColour, color iHighlight, String value) { x = ix; y = iy; w = iw; h = ih; baseColour = iColour; highlightColour = iHighlight; currentColour = baseColour; label = value; } void update() { if (over()) { currentColour = highlightColour; } else { currentColour = baseColour; } display(); } boolean pressed() { if (over) { locked = true; return true; } else { locked = false; return false; } } boolean over() { if (overRect(x, y, w, h)) { over = true; return true; } else { over = false; return false; } } boolean overRect(float xx, float yy, float width, float height) { return (mouseX >= xx && mouseX <= xx + width && mouseY >= yy && mouseY <= yy + height); } void display() { stroke(255); strokeWeight(1); fill(currentColour); rect(x, y, w, h); fill(255); text(label, x + 2, y + 2, w - 2, h -2); } }