Skip to content

Instantly share code, notes, and snippets.

@benjaminleonard
Last active August 29, 2015 14:02
Show Gist options
  • Save benjaminleonard/edb4ee88cbff97e3fd67 to your computer and use it in GitHub Desktop.
Save benjaminleonard/edb4ee88cbff97e3fd67 to your computer and use it in GitHub Desktop.
Simple class based Processing sketch where little balls move around consuming each other.
public class Ball implements Comparable<Ball> {
PVector position;
PVector velocity;
float speed;
int fillValue;
float targetSize;
float r, m;
Ball(float x, float y, float r_) {
position = new PVector(x, y);
velocity = PVector.random2D();
r = r_;
speed = (r*r)/150;
velocity.mult(speed);
m = r*.1;
}
void grow() {
if (r < targetSize) {
r = r + ((targetSize - r)/10);
}
}
void update() {
position.add(velocity);
grow();
}
void checkBoundaryCollision() {
if (position.x > width-r) {
position.x = width-r;
velocity.x *= -1;
}
else if (position.x < r) {
position.x = r;
velocity.x *= -1;
}
else if (position.y > height-r) {
position.y = height-r;
velocity.y *= -1;
}
else if (position.y < r) {
position.y = r;
velocity.y *= -1;
}
}
void display() {
strokeWeight(0);
fill(204);
ellipse(position.x, position.y, r*2, r*2);
}
void gravitate(float targetx, float targety, float ownRadius, float targetRadius) {
float dx = targetx - position.x;
float dy = targety - position.y;
float angle1 = atan2(dy, dx);
velocity = PVector.fromAngle(angle1);
velocity.mult(speed);
}
public int compareTo(Ball other) {
if ( this.position.x < other.position.x ) return -1;
if ( this.position.x > other.position.x ) return +1;
return 0;
}
}
import java.util.*;
int ballCounter = 0;
int maxBalls = 200;
ArrayList<Ball> balls;
void setup() {
frameRate(30);
size(displayWidth, displayHeight);
balls = new ArrayList<Ball>();
for (int i=0; i < maxBalls; i++) {
balls.add(new Ball(random(width), random(height), random(1, 12)) );
}
}
void draw() {
background(51);
for (int i=0; i < balls.size(); i++) {
Ball b = balls.get(i);
b.update();
b.display();
b.checkBoundaryCollision();
}
connectToNearestNeighbors();
}
float getArea(float radius) {
float area = PI * radius * radius;
return area;
}
float getRadius(float area) {
float radius = sqrt(area/PI);
return radius;
}
void mousePressed() {
balls.add(new Ball(random(width), random(height), random(5, 20)) );
}
void drawLine(Ball A, Ball B) {
strokeWeight(2);
stroke(204);
line(A.position.x, A.position.y, B.position.x, B.position.y);
}
void connectToNearestNeighbors() {
int num_balls = balls.size();
Collections.sort(balls);
_FIND_NEIGHBORS_:
for (int i = 0; i < num_balls; i++) {
Ball bi = balls.get(i);
for (int j = i+1; j < num_balls; j++) {
Ball bj = balls.get(j);
float max_dist = (bi.r+bj.r)*2;
float max_dist_sq = max_dist*max_dist;
float dx = bj.position.x-bi.position.x;
// println(dx);
if (dx > max_dist) {
continue _FIND_NEIGHBORS_;
}
float dy = Math.abs(bj.position.y-bi.position.y);
// println(dy);
if (dy > max_dist) {
continue;
}
if ((dx*dx+dy*dy) < max_dist_sq) {
drawLine(bi, bj);
bi.gravitate(bj.position.x, bj.position.y, bi.r, bj.r);
bj.gravitate(bi.position.x, bi.position.y, bj.r, bi.r);
}
if ((dx*dx+dy*dy) < bi.r) {
if (bi.r > bj.r) {
float combinedSize = getArea(bj.r) + getArea(bi.r);
bi.targetSize = getRadius(combinedSize);
balls.remove(bj);
num_balls = num_balls - 1;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment