Skip to content

Instantly share code, notes, and snippets.

@Craigson
Last active August 29, 2015 14:16
Show Gist options
  • Select an option

  • Save Craigson/678d87d31abc8602ddea to your computer and use it in GitHub Desktop.

Select an option

Save Craigson/678d87d31abc8602ddea to your computer and use it in GitHub Desktop.
Generative portraits inspired by Golan Levin's Floccular portraits
Cluster cluster1, cluster2, cluster3,cluster4;
PImage img; //create the image object for trapping snow
boolean showImage = false;
ArrayList<Cluster>clusters;
void setup() {
size(700,950, P2D);
img = loadImage("data/bruce.png"); //load the image into the system
image(img, 0, 0);
clusters = new ArrayList<Cluster>();
for (int i = 0; i < 50; i++){
clusters.add(new Cluster(3, img));
}
background(220);
smooth();
}
void draw() {
//background(20);
//image(img,0,0);
//blendMode(ADD);
for (Cluster c : clusters){
c.run();
}
println(frameRate);
}
void keyPressed(){
if (key == 's'){
println("file saved");
save();
}
}
void save(){
float a = random(0,1000);
int b = int(a);
save("images/generative_" + str(b) + ".jpg");
}
class Cluster {
ArrayList<Vehicle> vehicles;
Grazer grazer;
Cluster(int nums, PImage img) {
grazer = new Grazer();
vehicles = new ArrayList<Vehicle>();
for (int i = 0; i < nums; i ++) {
vehicles.add(new Vehicle(grazer.loc));
}
}
void run(){
update();
render();
grazer.run(img);
}
void render(){
for (Vehicle v : vehicles){
v.display();
}
}
void update() {
for (Vehicle a : vehicles) {
for (Vehicle b : vehicles) {
a.applyForce(a.attract(b));
a.applyForce(a.spin(b));
}
a.update();
a.seek(grazer.loc);
// a.drawTail();
//a.applyForce(grazer.spin(a));
}
}
}
class Grazer {
PVector loc;
PVector noff;
boolean overImage;
float strength, mass;
Grazer() {
loc = new PVector(random(width), random(height));
noff = new PVector(random(1000),random(1000));
mass = 100;
}
void run(PImage img) {
isOverImage(img);
walk();
//render();
}
void render() {
stroke(0);
fill(255,0,0);
ellipse(loc.x, loc.y, 5, 5);
}
// Randomly move up, down, left, right, or stay in one place
void walk() {
if (overImage == true) {
} else if (overImage == false) {
}
loc.x = map(noise(noff.x),0,1,-150,width+150);
loc.y = map(noise(noff.y),0,1,-150,height+150);
if (overImage == true) {
noff.add(0.0005,0.0005,0);
} else {
noff.add(0.003,0.003,0);
}
// Stay on the screen
}
void isOverImage (PImage img1) {
color pixelColour = img1.get(int(loc.x), int(loc.y));
//println(pixelColour); // <- this was used to determine the value
if (pixelColour != -1) {
overImage = true;
} else {
overImage = false;
}
}
PVector spin(Vehicle v){
PVector force = PVector.sub(loc, v.loc); // Calculate direction of force
float distance = force.mag(); // Distance between objects
// distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
//force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction
//multiply mass to speed up rotation
strength = (mass) / (distance * distance * distance + 100.0); // Calculate gravitional force magnitude
force.mult(strength); // Get force vector --> magnitude * direction
// return force;
//flip vector around to add rotation (cross producT)
return new PVector(-force.y, force.x);
}
}
class Vehicle {
PVector loc, vel, acc, initForce, prevLoc;
float mass, strength;
float rad;
float maxSpeed, maxForce, arrivalR;
color k;
float g;
ArrayList<PVector> history;
Vehicle(PVector _loc) {
history = new ArrayList<PVector>();
loc = _loc.get();
prevLoc = new PVector();
vel = new PVector(0, 0);
mass = random (0.1,0.5);
acc = new PVector(0,0);
arrivalR = 10;
rad = mass*20;
k = color (0);
initForce = new PVector(random(-0.002,0.002),random(-0.002,0.002)); //give the mover an initial velocity
maxSpeed = 3; //speed to which to limit the mover's velocity
maxForce = 0.2; //maximum force steering force to be applied
}
void update() {
vel.add(acc);
vel.limit(maxSpeed); //limit the velocity of the mover
loc.add(vel);
acc.mult(0); //reset the acceleration at the end of every frame
history.add(loc.get());
}
void applyForce(PVector force) {
PVector f = PVector.div(force, mass); //creace a copy of the original force
acc.add(f);
}
void display() {
fill(0,4);
noStroke();
ellipse(loc.x,loc.y,1.5,1.5);
}
void drawTail(){
stroke(200,1);
beginShape();
noFill();
for (PVector v : history) {
curveVertex(v.x, v.y);
}
endShape();
}
void seek(PVector target){
PVector desired = PVector.sub(target, loc);
float d = desired.mag();
desired.normalize();
if ( d < arrivalR ){
float m = map(d,0,arrivalR,0,maxSpeed);
desired.mult(m);
} else {
desired.mult(maxSpeed);
}
PVector steer = PVector.sub(desired, vel);
steer.limit(maxForce);
applyForce(steer);
}
//the repel method causes the mover to apply a repulsion force to every mover in
//the environment
PVector spin(Vehicle v){
PVector force = PVector.sub(loc, v.loc); // Calculate direction of force
float distance = force.mag(); // Distance between objects
// distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
//force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction
//multiply mass to speed up rotation
strength = (mass) / (distance * distance * distance + 100.0); // Calculate gravitional force magnitude
force.mult(strength); // Get force vector --> magnitude * direction
// return force;
//flip vector around to add rotation (cross producT)
return new PVector(-force.y, force.x);
}
PVector attract(Vehicle v) {
PVector force = PVector.sub(loc, v.loc); // Calculate direction of force
float distance = force.mag(); // Distance between objects
// distance = constrain(distance, 5.0, 25.0); // Limiting the distance to eliminate "extreme" results for very close or very far objects
//force.normalize(); // Normalize vector (distance doesn't matter here, we just want this vector for direction
//adding the extra 100.0 to the denominator prevents the value going to infinity
//when removing the conditional statment in draw where the particle checks
//itself
//remove g and apply it in the main update
strength = (mass*30) / (distance * distance * distance + 100.0); // Calculate gravitional force magnitude
force.mult(strength); // Get force vector --> magnitude * direction
return force;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment