Last active
August 29, 2015 14:16
-
-
Save Craigson/678d87d31abc8602ddea to your computer and use it in GitHub Desktop.
Generative portraits inspired by Golan Levin's Floccular portraits
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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