Art›Dot Bands
Dot.pde
class Dot {
PVector center;
PVector location;
PVector velocity;
PVector acceleration;
float max_speed = 8;
float max_force = 0.1;
PVector target;
ArrayList<Trailer> trailers;
PVector hole;
float radius = 12;
float box_size = 50;
int trailer_every_num_frames = 1;
color col_blue = color(21, 107, 193);
color col_green = color(6, 229, 78);
Dot(float x_, float y_, PVector hole_, float box_size_) {
center = new PVector(x_, y_);
location = new PVector(x_, y_);
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
newTarget();
trailers = new ArrayList<Trailer>();
hole = hole_.copy();
box_size = box_size_;
}
void newTarget() {
PVector new_target_offset = PVector.random2D();
new_target_offset.mult((box_size * 0.5));
target = center.copy();
target.add(new_target_offset);
}
boolean atTarget() {
return (PVector.dist(location, target) <= radius);
}
void applyForce(PVector force) {
acceleration.add(force);
}
void seek() {
PVector desired = PVector.sub(target, location);
desired.normalize();
desired.mult(max_speed);
PVector steer = PVector.sub(desired, velocity);
steer.limit(max_force);
applyForce(steer);
}
void update() {
seek();
velocity.add(acceleration);
velocity.limit(max_speed);
location.add(velocity);
acceleration.mult(0);
// track movement on trail
if((frameCount % trailer_every_num_frames) == 0) {
trailers.add(new Trailer(location.x, location.y, hole));
}
if(atTarget()) {
// met its goal, set a new target
newTarget();
}
}
void draw() {
/*// draw container box
pushMatrix();
pushStyle();
stroke(color(255, 0, 0));
noFill();
rect(
(center.x - (box_size * 0.5)),
(center.y - (box_size * 0.5)),
box_size,
box_size
);
popStyle();
popMatrix();*/
// trailers
for(Trailer trailer : trailers) {
trailer.update();
trailer.draw();
}
// clean out any trailers that finished finding their hole
for(int i = (trailers.size() - 1); i >= 0; i--) {
Trailer trailer = trailers.get(i);
if(trailer.finished()) {
trailers.remove(i);
}
}
// draw dot
pushMatrix();
pushStyle();
noStroke();
fill(col_green);
ellipseMode(CENTER);
ellipse(location.x, location.y, radius+abs(velocity.x), radius+abs(velocity.y));
popStyle();
popMatrix();
/*// draw target
pushMatrix();
pushStyle();
noStroke();
fill(color(100));
ellipseMode(CENTER);
ellipse(target.x, target.y, radius, radius);
popStyle();
popMatrix();*/
}
}
Trailer.pde
class Trailer {
PVector init;
PVector location;
PVector velocity;
PVector acceleration;
float max_speed = 2;
float max_force = 0.1;
PVector target;
float max_goal_dist = 5;
float radius = 2;
float max_rel_dist = 70;
float max_rel_radius = 10;
color fill_color;
color col_blue = color(21, 107, 193);
color col_green = color(6, 229, 78);
Trailer(float x_, float y_, PVector hole_) {
init = new PVector(x_, y_);
location = new PVector(x_, y_);
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
target = hole_.copy();
//fill_color = color(red(col_blue), green(col_blue), blue(col_blue), (100 * 0.4));
fill_color = col_blue;
}
boolean finished() {
return (PVector.dist(location, target) <= max_goal_dist);
}
void applyForce(PVector force) {
acceleration.add(force);
}
void seek() {
PVector desired = PVector.sub(target, location);
desired.normalize();
desired.mult(max_speed);
PVector steer = PVector.sub(desired, velocity);
steer.limit(max_force);
applyForce(steer);
}
void update() {
seek();
velocity.add(acceleration);
velocity.limit(max_speed);
location.add(velocity);
acceleration.mult(0);
}
void draw() {
pushMatrix();
pushStyle();
noStroke();
float rel_dist = PVector.dist(init, location);
float rel_radius = radius;
color rel_color = fill_color;
if(rel_dist <= max_rel_dist) {
float relative_size = norm(rel_dist, 0, max_rel_dist);
rel_radius = map(relative_size, 0, 1, max_rel_radius, radius);
rel_color = lerpColor(color(21, 193, 147), fill_color, relative_size);
//rel_color = color(red(rel_color), green(rel_color), blue(rel_color), (100 * map(relative_size, 0, 1, 0.5, 1)));
}
float targ_dist = PVector.dist(location, target);
float max_targ_dist = 50;
if(targ_dist <= max_targ_dist) {
rel_radius = map(targ_dist, max_targ_dist, 0, rel_radius, 1);
rel_color = lerpColor(rel_color, color(30), (1 - (targ_dist / max_targ_dist)));
}
fill(rel_color);
ellipseMode(CENTER);
ellipse(location.x, location.y, rel_radius, rel_radius);
popStyle();
popMatrix();
}
}
dot_bands.pde
ArrayList<Dot> dots;
PVector blackhole;
int num_dots = 24;
float box_size = 50;
void setup() {
size(640, 640);
dots = new ArrayList<Dot>();
blackhole = new PVector(320, 620);
for(int i = 0; i < num_dots; i++) {
float rand_x = random(50, 590);
float rand_y = random(50, 270);
dots.add(new Dot(rand_x, rand_y, blackhole, box_size));
}
}
void draw() {
background(30);
for(Dot dot : dots) {
dot.update();
dot.draw();
}
// draw blackhole
pushMatrix();
pushStyle();
color col_blue = color(21, 107, 193);
color col_green = color(6, 229, 78);
//fill(color(0));
fill(color(30));
noStroke();
//stroke(col_green);
//strokeWeight(2);
ellipseMode(CENTER);
ellipse(blackhole.x, blackhole.y, 12, 12);
popStyle();
popMatrix();
if(frameCount == 250) { save("preview.png"); }
}