• fullscreen
  • Boid.pde
  • imageBoids.pde
  • class Boid
    {
      //fields
      PVector pos, vel, acc; //pos, velocity, and acceleration in a vector datatype
      PVector initPos;
      float maxSpeed; //maximum magnitude ofr the velocity vector
      float maxSteerForce; //maximum magnitude of the steering vector
      color c; //color
    
      //constructors
      Boid(PVector inPos, color ic)
      {
        pos = new PVector();
        pos.set(inPos);
        initPos = new PVector();
        initPos.set(inPos);
        vel = new PVector(random(-10,10),random(-10,10));
        acc = new PVector(0, 0);
        c = ic;
        maxSpeed = red(c)*6.0/255 + 2;
        float sat = saturation(c)/255.0;
        float br = (brightness(c)/255.0);
        maxSteerForce = .1 + (sat*br)*.1;
      }
    
      void mDown()
      {
        acc.add(steer(new PVector(mouseX+random(-50, 50), mouseY+random(-50, 50)), false));
        move();
        //checkBounds();
        render();
      }
    
      void mDownR()
      {
        acc.add(avoid(new PVector(mouseX+random(-50, 50), mouseY+random(-50, 50)), true));
        move();
        //checkBounds();
        render();
      }
    
      void mUp()
      {
        if (pos.x!=initPos.x&&pos.y!=initPos.y)
          acc.add(steer(new PVector(initPos.x, initPos.y), true));
        //println(initPos);
        move();
        //checkBounds();
        render();
      }
    
      void move()
      {
        vel.add(acc); //add acceleration to velocity
        vel.limit(maxSpeed); //make sure the velocity vector magnitude does not exceed maxSpeed
        pos.add(vel); //add velocity to position
        acc.mult(0); //reset acceleration
      }
    
      void checkBounds()
      {
        if (pos.x>width) pos.x=0;
        if (pos.x<0) pos.x=width;
        if (pos.y>height) pos.y=0;
        if (pos.y<0) pos.y=height;
      }
    
      void render()
      {    
        /*pushMatrix();
         translate(pos.x,pos.y);
         stroke(c);
         point(0,0);
         popMatrix();*/
        int x2 = (int)pos.x;
        int y2 = (int)pos.y;
        if (x2 >= 0 && x2 < width && y2 >= 0 && y2 <height)
          pixels[width*y2+x2]=c;
      }
    
      //steering. If arrival==true, the boid slows to meet the target. Credit to Craig Reynolds
      PVector steer(PVector target, boolean arrival)
      {
        PVector steer = new PVector(); //creates vector for steering
        if (!arrival)
        {
          steer.set(PVector.sub(target, pos)); //steering vector points towards target (switch target and pos for avoiding)
          steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
        }
        else
        {
          PVector targetOffset = PVector.sub(target, pos);
          float distance=targetOffset.mag();
          float rampedSpeed = maxSpeed*(distance/100);
          float clippedSpeed = min(rampedSpeed, maxSpeed);
          PVector desiredVelocity = PVector.mult(targetOffset, (clippedSpeed/distance));
          steer.set(PVector.sub(desiredVelocity, vel));
          steer.limit(maxSteerForce);
        }
        return steer;
      }
    
      //avoid. If weight == true avoidance vector is larger the closer the boid is to the target
      PVector avoid(PVector target, boolean weight)
      {
        PVector steer = new PVector(); //creates vector for steering
        steer.set(PVector.sub(pos, target)); //steering vector points away from target
        if (weight)
          steer.mult(10/sq(steer.mag()));
        steer.limit(maxSteerForce); //limits the steering force to maxSteerForce
        return steer;
      }
    }
    
    
    /* OpenProcessing Tweak of *@*http://www.openprocessing.org/sketch/6658*@* */
    /* !do not delete the line above, required for linking your tweak if you re-upload */
    ArrayList boids = new ArrayList();
    PImage pic1, pic2, pic3;
    boolean mouseDownL= false;
    boolean mouseDownR = false;
    PGraphics pg;
    float minBrightness = 80;
    void setup()
    {
      size(400, 400);
      background(0);
      pic1 = loadImage("girl_with_pearl_earbuds.jpg");
      pic2 = loadImage("ge_wang.jpg");
      pic3 = loadImage("ciclop_thumbnail.jpg");
      createBoids(pic1);
    }
    
    void draw()
    {
      loadPixels();
      for (int i=0;i<boids.size();i++)
      {
        Boid b=(Boid)boids.get(i);
        if (mouseDownR)
          b.mDownR();
        if (mouseDownL)
          b.mDown();
        if (mouseDownR==false&&mouseDownL==false)
          b.mUp();
      }
      fastBlur(g, 1);
      updatePixels();
    }
    
    void mousePressed()
    {
      if (mouseButton==LEFT)
        mouseDownL = true;
      if (mouseButton==RIGHT)
        mouseDownR = true;
    }
    
    void mouseReleased()
    {
      if (mouseButton==LEFT)
        mouseDownL = false;
      if (mouseButton==RIGHT)
        mouseDownR = false;
    }
    
    // Super Fast Blur v1.1 by Mario Klingemann
    void fastBlur(PImage img, int radius) {
    
      if (radius<1) {
        return;
      }
      int w=width;
      int h=height;
      int wm=w-1;
      int hm=h-1;
      int wh=w*h;
      int div=radius+radius+1;
      int r[]=new int[wh];
      int g[]=new int[wh];
      int b[]=new int[wh];
      int rsum, gsum, bsum, fx, fy, i, p, p1, p2, yp, yi, yw;
      int vmin[] = new int[max(w, h)];
      int vmax[] = new int[max(w, h)];
      int[] pix = img.pixels;
      int dv[]=new int[256*div];
      for (i=0;i<256*div;i++) {
        dv[i]=(i/div);
      }
    
      yw=yi=0;
    
      for (fy=0;fy<h;fy++) {
        rsum=gsum=bsum=0;
        for (i=-radius;i<=radius;i++) {
          p=pix[yi+min(wm, max(i, 0))];
          rsum+=(p & 0xff0000)>>16;
          gsum+=(p & 0x00ff00)>>8;
          bsum+= p & 0x0000ff;
        }
        for (fx=0;fx<w;fx++) {
    
          r[yi]=dv[rsum];
          g[yi]=dv[gsum];
          b[yi]=dv[bsum];
    
          if (fy==0) {
            vmin[fx]=min(fx+radius+1, wm);
            vmax[fx]=max(fx-radius, 0);
          }
          p1=pix[yw+vmin[fx]];
          p2=pix[yw+vmax[fx]];
    
          rsum+=((p1 & 0xff0000)-(p2 & 0xff0000))>>16;
          gsum+=((p1 & 0x00ff00)-(p2 & 0x00ff00))>>8;
          bsum+= (p1 & 0x0000ff)-(p2 & 0x0000ff);
          yi++;
        }
        yw+=w;
      }
    
      for (fx=0;fx<w;fx++) {
        rsum=gsum=bsum=0;
        yp=-radius*w;
        for (i=-radius;i<=radius;i++) {
          yi=max(0, yp)+fx;
          rsum+=r[yi];
    
          gsum+=g[yi];
          bsum+=b[yi];
          yp+=w;
        }
        yi=fx;
        for (fy=0;fy<h;fy++) {
          pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];
          if (fx==0) {
            vmin[fy]=min(fy+radius+1, hm)*w;
            vmax[fy]=max(fy-radius, 0)*w;
          }
          p1=fx+vmin[fy];
          p2=fx+vmax[fy];
    
          rsum+=r[p1]-r[p2];
          gsum+=g[p1]-g[p2];
          bsum+=b[p1]-b[p2];
    
          yi+=w;
        }
      }
    }
    
    void keyPressed()
    {
      if (key==' ')
      {
        for (int i=0; i<boids.size(); i++)
        {
          Boid b=(Boid)boids.get(i);
          b.vel = new PVector(random(-100, 100), random(-100, 100));
        }
      }
    
      else if (key-48 > 0 && key-48 < 4)
      {
        switch (key)
        {
        case '1':
          minBrightness = 50;
          createBoids(pic1);
          break;
        case '2':
          minBrightness = 0;
          createBoids(pic2);
          break;
        default:
          minBrightness = 200;
          createBoids(pic3);
        }
      }
    }
    
    void createBoids(PImage img)
    {
      boids = new ArrayList(); 
      for (int i=0;i<img.width;i++)
      {
        for (int j=0;j<img.height;j++)
        {
          color c = img.get(i, j);
          if (brightness(c)>minBrightness)
            boids.add(new Boid(new PVector(width*i*1.0/img.width, height*j*1.0/img.height), c));
        }
      }
    }
    
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Joel Matthys

    Photo Particles

    Add to Faves Me Likey@! 8
    You must login/register to add this sketch to your favorites.

    Tweak of *@*http://www.openprocessing.org/sketch/6658

    Particles' behavior is affected by hue, brightness, saturation.

    Choose a photo with 1,2. Press space to explode.

    Uses dotlassie's amazing FastBlur.

    You need to login/register to comment.