import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.border.*; import java.util.*; public class AsynchBoids extends JPanel { int numSteps = 100; // Number of time-steps in simulation. int numBoids = 10; // Boid data. Point[] boids = null; int numNeighbors = 3; // Each boid observes some of its neighbors. int leader = 0; // The current leader. double leaderTheta = Math.PI/4.0; // Current direction for leader. double leaderChangeProb = 0.05; // The probability that we'll change the leader. double randomMoveProb = 0.1; // Sometimes, a boid moves in a random direction. int numMoveAttempts = 5; // Move attempts before giving up. int maxStepSize = 20; // Distance moved each step. int minDistSquare = 200; int radius = 10; // Drawing parameters. // For asychronous simulation, our usual next-event variables: PriorityQueue eventList; double clock = 0; void init () { clock = 0; eventList = new PriorityQueue (); // As usual, we need to have at least one event in the queue at the start. for (int i=0; i D.width-5) || (leaderY < 5) || (leaderY > D.height-5)) { // Change direction: either opposite, or random. if (RandTool.uniform() < 0.5) { leaderTheta = RandTool.uniform (0.0, Math.PI); } else { // Opposite. leaderTheta = 2*Math.PI - leaderTheta; } leaderX = boids[leader].x; leaderY = boids[leader].y; } return new Point (leaderX, leaderY); } Point moveOther (int i) { // Identify nearest neighbors. int[] neighbors = findNearestNeighbors (i); // Compute centroid. Point centroid = computeCentroid (neighbors); if (RandTool.uniform() < randomMoveProb) { // Random move: pick a random direction. return randomMove (i); } else { // Apply rules. return applyRules (i, neighbors, centroid); } } Point computeCentroid (int[] neighbors) { int sumX = 0, sumY = 0; for (int k=0; k minDistSquare) { // Valid. x = tempX; y = tempY; succ = true; break; } // Otherwise, try a smaller move. alpha = alpha / 2.0; } // If not successful, try moving away from centroid. alpha = maxAlpha; if (!succ) { x = (int) (boids[i].x - alpha * (centroid.x - boids[i].x)); y = (int) (boids[i].y - alpha * (centroid.y - boids[i].y)); } return new Point (x,y); } int[] findNearestNeighbors (int i) { int[] neighbors = new int [numNeighbors]; int current = i; for (int k=0; k e.eventTime) { return 1; } else { return 0; } } public boolean equals (Object obj) { return (compareTo(obj) == 0); } }