• 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@! 26
    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
    Hi Diana,

    It looks very cool. The only issue is that processing can't find the images:

    The file "butterfly.jpg" is missing or inaccessible, make sure the URL is valid or that the file has been added to your sketch and is readable.

    I never had this issue with other sketches where is use :

    img [0] = loadImage ("image.jpg");

    do you have any clue what it could be? (im on OSX 10.8.5 , processing 2.1.1)
    Marie
    10 Feb 2014
    Hello Diana,

    This sketch looks wonderful but I am also having the same trouble as Ruben, it tells me that the jpgs are missing or inaccessible, but I have checked and all jpgs are in the associated Data folder and are spelled the same, etc. Do you have any idea why it might be saying this? Any thoughts would be appreciated, thank you!
    Marie
    10 Feb 2014
    *Update: I looked elsewhere in the forum and saw that Diana had helpfully suggested to run this sketch in version 1.5 and it's working beautifully. Thank you for your patience with all of us, Diana! Your sketches are genius!!
    You need to login/register to comment.