• fullscreen
  • classParicle.pde
  • lookForTarget.pde
  • triangulation_web.pde
  • class Particle 
    {
      float cx, cy;
      float tx, ty;
      float speed = 0;
      boolean targetRechead = false;
    
      Particle (float cx, float cy, float tx, float ty)
      {
        this.cx = cx;
        this.cy = cy;
        this.tx = tx;
        this.ty = ty;
      }
    
      void update (float tx, float ty)
      {
        targetRechead = false;
        speed = 0;
        this.tx = tx;
        this.ty = ty;
      }
    
      void move ()
      {
        if (!targetRechead)
        {
          float amt = sin (speed);
          cx = lerp (cx, tx, amt);
          cy = lerp (cy, ty, amt);
          speed += 0.002;
          if ( (int) cx ==  (int) tx && (int) cy == (int) ty) targetRechead = true;
          if (speed >= 0.13) 
          {
            targetRechead = true;
            cx = tx;
            cy = ty;
          }
        }
      }
    
      void draw ()
      {
        point (cx, cy);
      }
    }
    
    class PointCloud 
    {
      boolean paused = false;
      Particle [] p;
      float [] [] pp;
      float[][] myEdges;
      int length;
      Delaunay dl;
    
      PointCloud (int n)
      {
        this.length = n;
        p = new Particle [0];
        pp = new float [0] [0];
        myEdges = new float [0] [0];
      }
    
    
      void addPatricel (Particle cp)
      {
        if (p.length <= length) {
          p = (Particle[]) append (p, cp);
          pp = (float [] []) append (pp, new float [] {
            p[p.length-1].cx, 
            p[p.length-1].cy
          }
          );
        }
      }
    
      void update (float [] [] target)
      {
        ArrayList <Integer> index = new ArrayList();
        ArrayList <Float> targetX = new ArrayList();
        ArrayList <Float> targetY = new ArrayList();
    
        for (int i = 0; i < target.length; i++) index.add (i);
    
        int closestIndex = 0;
        float closestDist = width*2;
        float dis = 0;
    
        for (int i = 0; i < p.length; i++)
        {
          closestIndex = 0;
          closestDist = width*2;
    
          for (int j = 0; j < index.size(); j++)
          {
            dis = dist (p[i].cx, p[i].cy, target [index.get(j)] [0], target [index.get(j)] [1]);
            {
              if (dis < closestDist) 
              {
                closestDist = dis;
                closestIndex = j;
              }
            }
          }
    
          targetX.add ( target [index.get(closestIndex)] [0]);
          targetY.add ( target [index.get(closestIndex)] [1]);
          try 
          {
            index.remove (closestIndex);
          }
          catch (IndexOutOfBoundsException e)
          {
            println (e);
          }
        }
    
    
        for (int i = 0; i < p.length; i++)
        {
    
          p[i].update (targetX.get (i), targetY.get (i));
        }
    
        paused = false;
      }
    
      void updateSimple (float [] [] target)
      {
        for (int i = 0; i < p.length; i++)
        {
          p[i].update (target [i] [0], target [i] [1]);
        }
    
        paused = false;
      }
    
      void checkFinishing ()
      {
    
        boolean targetRechead = true;
        for (int i = 0; i < p.length; i++)
        {
          if (!p[i].targetRechead)
          {
            targetRechead = false;
            break;
          }
        }
    
        if (targetRechead) paused = true;
      }
    
      void draw ()
      {
        for (int i = 0; i < p.length; i++)
        {
          if (!paused) {
            //if (p.length-1 < length && !p[i].targetRechead) p[i].move();
            //else if (p.length-1 == length) 
            p[i].move();
            pp [i] [0] = p[i].cx;
            pp [i] [1] = p[i].cy;
          }
         // p[i].draw();
        }
    
        dl = new Delaunay (pp);
    
        checkFinishing();
    
        myEdges = dl.getEdges();
    
        for (int i=0; i<myEdges.length; i++)
        {
          line( myEdges[i][0], myEdges[i][1], myEdges[i][2], myEdges[i][3] );
        }
      }
    }
    
    
    float [] [] findTargets (int n, PImage img)
    {
      img.loadPixels();
      float [] [] target = new float [n] [2];
    
      PVector pos;
      for (int i = 0; i < target.length; i++)
      {
        pos = target (img.pixels, (int) random (img.width), (int) random (img.height), img.width, img.height, 0);
    
        target [i] [0] = pos.x;
        target [i] [1] = pos.y;
      }
    
      return target;
    }
    
    PVector target (int [] colors, int x, int y, int W, int H, int depth)
    {
      PVector pos = new PVector (0, 0);
      int index = y*W+x;
      color c = colors [index];
    
      if (depth == 15 || isValidTarget (brightness (c)))
      {
        pos.x = x;
        pos.y = y;
      } 
      else 
      {
        pos = target (colors, (int) random (W), (int) random (H), W, H, depth++);
      }
      
        return pos;
    }
    
    boolean isValidTarget (float fbrightness)
    {
      if (fbrightness > 220) return false;
      float value = map (fbrightness, 0, 255, 1, 100);
    
      float iRandom = random (0, value);
      if (iRandom < 1) return true;
      else return false;
    }
    
    
    import megamu.mesh.*;
    
    PointCloud pc;
    
    PImage testImg;
    PImage [] img;
    boolean showImage = false, transparentBackground = true, moveRandom = false, doPause = false, randomImage = true;
    
    void setup ()
    {
      size (675, 450, P3D);
      smooth();
      frameRate (30);
      img = new PImage [3];
      img [0] = loadImage ("delorien.jpg");
      img [1] = loadImage ("skull.jpg");
      img [2] = loadImage ("butterfly.jpg");
    
      testImg = img[1];
    
      pc = new PointCloud (1800);
      addParticel(true);
      addParticel(true);
      background (230);
      stroke (5);
      strokeWeight (0.5);
    
      frameCount = 0;
    }
    
    void draw ()
    {
    
      if (transparentBackground)
      {
        noStroke();
        fill (230, 90);
        rect (0, 0, width, height);
        stroke (5, 120);
      }
      else background (230);
    
      pc.draw();
      if (pc.paused)
      {
        if (pc.p.length < pc.length) 
        {
          for (int i = 0; i < frameCount / 14; i++) addParticel(true);
        }
        else 
        {
          if (randomImage) testImg = img [(int) random(img.length)];
        }    
        updatePointCloud (testImg, moveRandom ? 1 : 0);
      }
      if (showImage) image (testImg, 10, 10, testImg.width/4, testImg.height/4);
    }
    
    void addParticel (boolean startRandom)
    {
      if (startRandom)
      {
        float [] [] target = (float[] []) findTargets (1, testImg);
    
        int dir = (int) random (4);
        float cx = 0, cy = 0;
        if (dir == 0) {
          cx = 0;
          cy = random (height);
        }
        else if (dir == 1) {
          cx = width-1;
          cy = random (height);
        }
        else if (dir == 2) {
          cx = random (width);
          cy = 0;
        }
        else {
          cx = random (width);
          cy = height-1;
        }
        pc.addPatricel (new Particle (cx, cy, target[0][0], target[0][1]));
      }
      else {
        float [] [] target = (float[] []) findTargets (2, testImg);
        pc.addPatricel (new Particle (target[1][0], target[1][1], target[0][0], target[0][1]));
      }
    }
    
    
    void updatePointCloud (PImage img, int mode)
    {
      float [] [] target = (float[] []) findTargets (pc.p.length, img);
      if (mode == 0) pc.update (target);
      else pc.updateSimple (target);
    }
    
    void keyPressed ()
    {
      if (keyCode == KeyEvent.VK_1) 
      {
        testImg = img[0];
        while (pc.p.length < pc.length) 
        {
          addParticel(false);
        }
    
        updatePointCloud (testImg, moveRandom ? 1 : 0);
      }
    
      if (keyCode == KeyEvent.VK_2) 
      {
        testImg = img[1];
        while (pc.p.length < pc.length) 
        {
          addParticel(false);
        }
    
        updatePointCloud (testImg, moveRandom ? 1 : 0);
      }
    
      if (keyCode == KeyEvent.VK_3) 
      {
        testImg = img[2];
        while (pc.p.length < pc.length) 
        {
          addParticel(false);
        }
    
        updatePointCloud (testImg, moveRandom ? 1 : 0);
      }
      if (keyCode == KeyEvent.VK_P) {
        doPause = !doPause;
        if (doPause) noLoop();
        else loop();
      }
      if (keyCode == KeyEvent.VK_M) moveRandom = !moveRandom;
      if (keyCode == KeyEvent.VK_B) transparentBackground = !transparentBackground;
      if (keyCode == KeyEvent.VK_I) showImage = !showImage;
      if (keyCode == KeyEvent.VK_R) randomImage = !randomImage;
    }
    
    void mousePressed ()
    {
      if (mouseButton == LEFT)
      {
        pc = new PointCloud (2000);
        addParticel(true);
        addParticel(true);
        frameCount = 0;
      }
      else {
        updatePointCloud (testImg, moveRandom ? 1 : 0);
        while (pc.p.length < pc.length) 
        {
          addParticel(false);
        }
      }
    }
    
    

    code

    tweaks (0)

    about this sketch

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

    license

    advertisement


    Diana Lange

    Image based triangulation

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

    Drawing machine based on http://www.openprocessing.org/sketch/81905

    Uses Lee Byron's Mesh Library:
    http://www.leebyron.com/else/mesh/

    Little bit slow because the triangulation has to be calculated every frame.

    Controls:
    Left mouse button = restart
    Right mouse button = restart /w full resolution
    1 / 2 / 3 = choose image
    M = change movement mode
    B = transparent background on / off
    I = show / hide current input image
    R = random image on / off

    (Work in progress) Video:
    https://vimeo.com/54590461

    Novitskiy Sergey
    15 Jan 2013
    very cool!
    Alejandro
    5 Apr 2013
    This is amazing!! what is your thesis about? I'm a fan of your work
    You need to login/register to comment.