• fullscreen
  • Critter.pde
  • Link.pde
  • OrganizingCritters.pde
  • Particle.pde
  • class Critter extends Particle
    {
      float z;
      float dir, dir_head, v_dir_head;
    
      Critter()
      {
      }
    
      void Update()
      {
        super.Update();
        
        v_vx += vx * 0.1;
        v_vy += vy * 0.1;
        dir = atan2(v_vy, v_vx) - PI * 0.5;
        v_vx *= 0.9;
        v_vy *= 0.9;
    
        v_dir_head += (atan2(vy, vx) - PI * 0.5 - dir) * 0.1;
        dir_head += v_dir_head * 0.1;
        dir_head = constrain(dir_head, -PI * 0.2, PI * 0.2);
        v_dir_head *= 0.95;
        dir_head *= 0.9;
      }
      
      void DrawCritter(PGraphics pg)
      {
        float t = age;
        z = r_visual + abs(r_visual * sin(t + phase));
    
        int c_alpha = (int)(p_alpha * 255);
        if(c_alpha > 100) c_alpha = 255;
        pg.fill(cR + cD, cG + cD, cB + cD, c_alpha);
        pg.pushMatrix();
        pg.translate(x, y, z);
        pg.rotateZ(dir);
        pg.box(r_visual);
        pg.popMatrix();
    
        pg.fill(255 + cD, 255 + cD, 255 + cD, c_alpha);
        pg.pushMatrix();
        pg.translate(x, y, z + r_visual * 0.5 + 2 * cos(t + phase));
        pg.rotateZ(dir);
        pg.rotateX(PI * 0.05 * sin(t * 0.9 + phase));
        pg.translate(0, r_visual * 0.5, 0);
        pg.rotateZ(dir_head);
        pg.translate(0, r_visual * 0.5, 0);
        pg.box(r_visual * 0.5);
        pg.popMatrix();
    
        pg.pushMatrix();
        pg.translate(x, y + r_visual * 0.2, z);
        pg.rotateZ(dir);
        pg.rotateX(PI * 0.25 * sin(t + phase));
        pg.translate(0, 0, -r_visual);
        pg.scale(1, 1, 4);
        pg.box(r_visual * 0.2);
        pg.popMatrix();
    
        pg.pushMatrix();
        pg.translate(x, y - r_visual * 0.2, z);
        pg.rotateZ(dir);
        pg.rotateX(PI * 0.25 * sin(t + phase + PI));
        pg.translate(0, 0, -r_visual);
        pg.scale(1, 1, 4);
        pg.box(r_visual * 0.2);
        pg.popMatrix();
      }
    }
    
    
    
    class Link
    {
      Particle p0;
      Particle p1;
      Link(Particle p0, Particle p1)
      {
        this.p0 = p0;
        this.p1 = p1;
      }
    
      void Draw(PGraphics pg)
      {
        float dx = p0.x - p1.x;
        float dy = p0.y - p1.y;
        float d = sqrt(dx*dx+dy*dy);
        if(d < (p0.r_view + p1.r_view) * 0.5)
        {
          pg.line(p0.x, p0.y, p1.x, p1.y);
        }
      }
    }
    
    
    import controlP5.*;
    
    ArrayList ps;
    ArrayList ls;
    PGraphics pg, pgA;
    
    ControlP5 controlP5;
    int ui_pane_width = 200;
    
    public boolean no_bg = true;
    public boolean pause = false;
    public boolean show_trail = false;
    public boolean show_brush = false;
    
    public boolean isBounded = true;
    public boolean isPeriodicBound = false;
    public boolean orthographic = true;
    public boolean repulse_hard = true;
    public boolean repulse_bouncy = true;
    public boolean show_ptcls = true;
    public boolean show_vector = false;
    public boolean show_network = false;
    public boolean show_reff = false;
    public boolean show_rview = false;
    
    public int ptcl_count = 15;
    public int attractable_count = 10;
    public int max_speed = 50;
    public int dimming = 0;
    
    public int min_reff = 10;
    public int max_reff = 30;
    public float view_range = 3;
    public float breathe_scale = 0.05;
    
    public int Red, Green, Blue, Alpha;
    public float cam_A = 0;
    public float cam_Y = 300;
    public float cam_Z = 500;
    float p_cam_A, p_cam_Y, p_cam_Z;
    
    Critter selectedPtcl = null;
    float[] plane;
    
    void setup()
    {
      pg = createGraphics(400, 400, P3D);
      pg.background(255, 255, 255);
    
      pgA = createGraphics(pg.width, pg.height, P2D);
      pgA.background(255, 255, 255);
    
      size(pg.width + ui_pane_width, pg.height, P2D);
      background(255, 255, 255);
    
      Red = 100;
      Green = 100;
      Blue = 100;
      Alpha = 128;
    
      p_cam_A = cam_A;
      p_cam_Y = cam_Y;
      p_cam_Z = cam_Z;
    
      plane = new float[4];
      plane[0] = 0;
      plane[1] = 0;
      plane[2] = 1;
      plane[3] = 0;
    
      InitUI();
      InitParticleSystem();  
    }
    
    void InitUI()
    {
      int ui_x = 10;
      int ui_y = 8;
      int ui_y_step = 10;
      int ui_y_space = 5;
      controlP5 = new ControlP5(this);
    
      controlP5.addToggle("pause",pause,ui_x + 90,ui_y,10,10);
      controlP5.addSlider("dimming",0,50,dimming,ui_x + 90,ui_y + 29,40,10);
      Radio r_bg = controlP5.addRadio("radio_bg",ui_x,ui_y);
      r_bg.add("no bg",0);
      r_bg.add("draw trail",1);
      r_bg.add("paint brush",2);
      r_bg.activate("draw trail");
      ui_y += ui_y_step + ui_y_space + 40;
    
      controlP5.addToggle("show_ptcls",show_ptcls,ui_x,ui_y,10,10);
      controlP5.addToggle("show_vector",show_vector,ui_x + 90,ui_y,10,10);
      ui_y += ui_y_step + ui_y_space + 10;
      controlP5.addSlider("Alpha",0,255,Alpha,ui_x,ui_y,128,10);
      ui_y += ui_y_step + 10;
      controlP5.addToggle("show_reff",show_reff,ui_x,ui_y,10,10);
      controlP5.addToggle("show_rview",show_rview,ui_x + 90,ui_y,10,10);
      ui_y += ui_y_step + ui_y_space + 10;
      controlP5.addSlider("view_range",1,20,view_range,ui_x,ui_y,90,10);
      ui_y += ui_y_step + ui_y_space;
      controlP5.addSlider("breathe_scale",0,2,breathe_scale,ui_x,ui_y,90,10);
      ui_y += ui_y_step + ui_y_space;
      controlP5.addToggle("show_network",show_network,ui_x,ui_y,10,10);
      controlP5.addToggle("orthographic",orthographic,ui_x + 90,ui_y + 8,10,10);
      ui_y += ui_y_step + ui_y_space + 20;
    
      controlP5.addSlider("cam_A",0,360,cam_A,ui_x + 90,ui_y,50,10);
      controlP5.addSlider("cam_Y",0,500,cam_Y,ui_x + 90,ui_y + 14,50,10);
      controlP5.addSlider("cam_Z",10,1000,cam_Z,ui_x + 90,ui_y + 28,50,10);
    
      Radio r_bound = controlP5.addRadio("radio_bound",ui_x,ui_y);
      r_bound.add("no bound",0);
      r_bound.add("bound",1);
      r_bound.add("periodic bound",2);
      r_bound.activate("periodic bound");
      ui_y += ui_y_step + ui_y_space + 30;
    
      controlP5.addSlider("max_speed",10,100,max_speed,ui_x,ui_y,90,10);
      ui_y += ui_y_step + ui_y_space;
      controlP5.addSlider("attractable_count",0,100,attractable_count,ui_x,ui_y,90,10);
      ui_y += ui_y_step + ui_y_space;
      controlP5.addToggle("repulse_hard",repulse_hard,ui_x,ui_y,10,10);
      controlP5.addToggle("repulse_bouncy",repulse_hard,ui_x + 90, ui_y,10,10);
      ui_y += ui_y_step + ui_y_space + 28;
    
      controlP5.addSlider("ptcl_count",0,200,ptcl_count,ui_x,ui_y,100,10);
      ui_y += ui_y_step + ui_y_space;
      controlP5.addSlider("min_reff",3,50,min_reff,ui_x,ui_y,90,10);
      ui_y += ui_y_step + ui_y_space;
      controlP5.addSlider("max_reff",3,50,max_reff,ui_x,ui_y,90,10);
      ui_y += ui_y_step + ui_y_space;
    
      controlP5.addSlider("Red",0,255,Red,ui_x,ui_y,128,10);
      ui_y += ui_y_step + 1;
      controlP5.addSlider("Green",0,255,Green,ui_x,ui_y,128,10);
      ui_y += ui_y_step + 1;
      controlP5.addSlider("Blue",0,255,Blue,ui_x,ui_y,128,10);
      ui_y += ui_y_step + 1;
    }
    
    void InitParticleSystem()
    {
      ps = new ArrayList();
      ls = new ArrayList();
      for(int i = 0; i < ptcl_count; i++)
      {
        Critter c = AddNewPtcl();
        c.cR = random(0, 100);
        c.cG = random(100, 255);
        c.cB = random(200, 255);
      }
    }
    
    Critter AddNewPtcl()
    {
      Critter ptcl = new Critter();
      ptcl.SetPosition(random(width), random(height));
      ptcl.vx = random(-max_speed, max_speed);
      ptcl.vy = random(-max_speed, max_speed);
      ptcl.r_eff = random(min_reff, max_reff);
      ptcl.cR = Red;
      ptcl.cG = Green;
      ptcl.cB = Blue;
      ps.add(ptcl);
      return ptcl;
    }
    
    void draw()
    {
      background(255, 255, 255);
      noStroke();
      fill(64, 64, 64);
      rect(0, 0, ui_pane_width, height);
      stroke(100, 100, 100);
      line(0, 305, ui_pane_width - 1, 305);
    
      p_cam_A += (cam_A - p_cam_A) * 0.1;
      p_cam_Y += (cam_Y - p_cam_Y) * 0.1;
      p_cam_Z += (cam_Z - p_cam_Z) * 0.1;
    
      pgA.beginDraw();
      pgA.smooth();
      if(!pause)
      {
        if(no_bg || frameCount < 10)
        {
          pgA.background(255, 255, 255, 0);
        }
        if(dimming > 0)
        {
          pgA.noStroke();
          pgA.fill(0, 0, 0, dimming);
          pgA.rect(0, 0, pgA.width, pgA.height);
        }
        DrawA(pgA); 
      }
      pgA.endDraw();
    
      pg.beginDraw();
      pg.background(255, 255, 255, 0);
      if(!pause)
      {
        Update();
      }
    
      float r = p_cam_Z;
      float camX = r * cos(radians(p_cam_A));
      float camY = r * sin(radians(p_cam_A));
      if(orthographic)
      {
        pg.ortho(-pg.width * 0.5, pg.width * 0.5, -pg.height * 0.5, pg.height * 0.5, -1000, 1000);
      }
      else
      {
        pg.perspective();
      }
      pg.camera(camX, camY, p_cam_Y, 0, 0, 0, 0, 0, -1);
    
      pg.noStroke();
      pg.beginShape(QUADS);
      pg.textureMode(NORMALIZED);
      pg.texture(pgA);
      pg.vertex(-pg.width * 0.5, -pg.height * 0.5, 0, 0, 0);
      pg.vertex(pg.width * 0.5, -pg.height * 0.5, 0, 1, 0);
      pg.vertex(pg.width * 0.5, pg.height * 0.5, 0, 1, 1);
      pg.vertex(-pg.width * 0.5, pg.height * 0.5, 0, 0, 1);
      pg.endShape();
    
      pg.lights();
      pg.pushMatrix();
      pg.translate(-pg.width * 0.5, -pg.height * 0.5, 0);
      Draw(pg); 
      pg.popMatrix();
      pg.endDraw();
    
      image(pg, ui_pane_width, 0);
    
      if(ps.size() < ptcl_count)
      {
        AddNewPtcl();
      }
      if(ps.size() > ptcl_count)
      {
        ps.remove(0);
      }
    
      stroke(0, 0, 0);
      noFill();
      rect(0, 0, width-1, height-1);
      controlP5.draw();
    }
    
    float jx, jy, jz;
    
    void Update()
    {
      ls.clear();
      pg.noFill();
      pg.stroke(0 ,0, 0);
      for(int i = 0; i < ps.size(); i++)
      {
        Critter critter = (Critter)ps.get(i);
        critter.Update();
      }
      MoveCritter(mouseX - ui_pane_width, mouseY);
    }
    
    void Draw(PGraphics pg)
    {
      pg.noFill();
    
      if(show_reff)
      {
        for(int i = 0; i < ps.size(); i++)
        {
          Particle ptcl = (Particle)ps.get(i);
          ptcl.DrawReff(pg);
        }
      }
    
      if(show_rview)
      {
        for(int i = 0; i < ps.size(); i++)
        {
          Particle ptcl = (Particle)ps.get(i);
          ptcl.DrawRview(pg);
        }
      }
    
      if(show_network)
      {
        pg.stroke(0, 0, 0, 64);
        for(int i = 0; i < ls.size(); i++)
        {
          Link li = (Link)ls.get(i);
          li.Draw(pg);
        }
      }
    
      if(show_ptcls)
      {
        if(selectedPtcl != null)
        {
          pg.stroke(255, 0, 0);
          pg.strokeWeight(2);
          pg.ellipse(selectedPtcl.x, selectedPtcl.y, selectedPtcl.R_eff * 2, selectedPtcl.R_eff * 2);
          pg.strokeWeight(1);
        }
        pg.noStroke();
        for(int i = 0; i < ps.size(); i++)
        {
          Particle ptcl = (Particle)ps.get(i);
          ptcl.Draw(pg);
        }
        for(int i = 0; i < ps.size(); i++)
        {
          Critter critter = (Critter)ps.get(i);
          critter.DrawCritter(pg);
        }
      }
    
      if(show_vector)
      {
        pg.stroke(255, 255, 255);
        for(int i = 0; i < ps.size(); i++)
        {
          Particle ptcl = (Particle)ps.get(i);
          ptcl.DrawV(pg);
        }
      }
    }
    
    void DrawA(PGraphics pg)
    {
      if(show_trail)
      {
        for(int i = 0; i < ps.size(); i++)
        {
          Particle ptcl = (Particle)ps.get(i);
          ptcl.DrawTrail(pg);
        }
      }
    
      if(show_brush)
      {
        pg.noStroke();
        for(int i = 0; i < ps.size(); i++)
        {
          Particle ptcl = (Particle)ps.get(i);
          ptcl.Draw(pg);
        }
      }
    }
    
    void radio_bound(int theID) {
      switch(theID) {
        case(0):
        isBounded = false;   
        break;  
        case(1):
        isBounded = true;
        isPeriodicBound = false;
        break;  
        case(2):
        isBounded = true;
        isPeriodicBound = true;
        break;
      }
    }
    
    void radio_bg(int theID) {
      switch(theID) {
        case(0):
        no_bg = true;
        show_trail = false;
        show_brush = false;   
        break;  
        case(1):
        no_bg = false;
        show_trail = true;
        show_brush = false;
        break;  
        case(2):
        no_bg = false;
        show_trail = false;
        show_brush = true;
        break;
      }
    }
    
    void mousePressed()
    {
      if(mouseX < ui_pane_width) return;
    
      SelectCritter(mouseX - ui_pane_width, mouseY);
    }
    
    void mouseReleased()
    {
      selectedPtcl = null;
    }
    
    void SelectCritter(float x, float y)
    {
      float[] pos = mpoint_on_plane(plane, x, y);
      if(pos != null)
      {
        for(int i = 0; i < ps.size(); i++)
        {
          Critter c = (Critter)ps.get(i);
          float dx = pos[0] + pg.width * 0.5 - c.x;
          float dy = pos[1] + pg.height * 0.5 - c.y;
          float dz = pos[2] - c.z;
          float d = sqrt(dx*dx + dy*dy + dz*dz);
          if(d < c.R_eff * 1.5)
          {
            selectedPtcl = c;
            break;
          }
        }
      }
      if(selectedPtcl != null) return;
      if ( x < 0 || x >= pg.width || y < 0 || y >= pg.height) return;
      PGraphics3D g3d = (PGraphics3D)pg; 
      float z = g3d.zbuffer[(int)y * pg.width + (int)x];
      pos = unproject(x, y, z);
      if(pos != null)
      {
        for(int i = 0; i < ps.size(); i++)
        {
          Critter c = (Critter)ps.get(i);
          float dx = pos[0] + pg.width * 0.5 - c.x;
          float dy = pos[1] + pg.height * 0.5 - c.y;
          float dz = pos[2] - c.z;
          float d = sqrt(dx*dx + dy*dy + dz*dz);
          if(d < c.R_eff * 1.5)
          {
            selectedPtcl = c;
            break;
          }
        }
      }
    }
    
    void MoveCritter(float x, float y)
    {
      if(selectedPtcl != null)
      {
        float[] pos = mpoint_on_plane(plane, x, y);
        if(pos != null)
        {
          selectedPtcl.vx = (pos[0] + pg.width * 0.5 - selectedPtcl.x);
          selectedPtcl.vy = (pos[1] + pg.height * 0.5 - selectedPtcl.y);
        }
        
        selectedPtcl.cR = Red;
        selectedPtcl.cG = Green;
        selectedPtcl.cB = Blue;
        selectedPtcl.r_eff = (min_reff + max_reff) * 0.5;
        selectedPtcl.Update();
      }
    }
    
    float[] unproject(float x, float y, float z)
    {
      float[] in = new float[4];
      float[] out = new float[4];
      in[0] = map(x, 0, pg.width, -1, 1); 
      in[1] = map(y, 0, pg.height, -1, 1); 
      in[2] = map(z, 0, 1, -1, 1);
      in[3] = 1;
    
      PGraphics3D g3d = (PGraphics3D)pg; 
      PMatrix3D mv = g3d.modelview.get(); 
      PMatrix3D pr = g3d.projection.get();
    
      mv.invert();
      pr.invert();
      mv.apply(pr);
      mv.mult(in ,out);
    
      if(out[3] != 0)
      {
        out[0] /= out[3];
        out[1] /= out[3];
        out[2] /= out[3];
        return out;
      } 
      return null;
    }
    
    float[] mpoint_on_plane(float[] plane, float x, float y)
    {
      float[] r0 = unproject(mouseX - ui_pane_width, mouseY, 0);
      float[] r1 = unproject(mouseX - ui_pane_width, mouseY, 1);
      float[] rd = new float[3];
      rd[0] = r1[0] - r0[0];
      rd[1] = r1[1] - r0[1];
      rd[2] = r1[2] - r0[2];
    
      float vd = plane[0] * rd[0] + plane[1] * rd[1] + plane[2] * rd[2];
      if(vd != 0)
      {
        float v0 = -(plane[0] * r0[0] + plane[1] * r0[1] + plane[2] * r0[2] + plane[3]);
        float t = v0 / vd;
        float[] out = new float[3];
        out[0] = r0[0] + rd[0] * t;
        out[1] = r0[1] + rd[1] * t;
        out[2] = r0[2] + rd[2] * t;
        return out;
      }
      return null;
    }
    
    
    
    
    class Particle
    {
      float x, y;
      float old_x, old_y;
      float vx, vy;
      float v_vx, v_vy;
      float u_vx, u_vy;
      float speed;
      float r_eff, R_eff, r_visual, r_view;
      float r_breathe = 0;
      float dt, age;
      float cR, cG, cB, cD;
      float p_alpha, m_alpha;
      int attractedCount = 0;
    
      float phase = random(PI * 2);
      float pace = random(0.01, 0.1);
    
      float repulsive_factor = 10;
    
      Particle()
      {
        dt = 0.05;
        cD = random(-64, 64);
        p_alpha = 0;
        m_alpha = 1;
      }
    
      void SetPosition(float x, float y)
      {
        this.x = x;
        this.y = y;
        old_x = x;
        old_y = y;
      }
    
      void Update()
      {
        if(!pause)
        {
          age += 0.1 + (max_speed / 100) * 0.1;
        }
        p_alpha += (m_alpha - p_alpha) * 0.1;
        r_breathe = (sin(frameCount * pace + phase) + 1) * r_eff * breathe_scale;
        R_eff = r_eff + r_breathe;
        r_view = R_eff * view_range;
        speed = sqrt(vx * vx + vy * vy);
        if(speed > 0)
        {
          u_vx = vx / speed;
          u_vy = vy / speed;
          if(speed > max_speed) speed = max_speed;
          vx = speed * u_vx;
          vy = speed * u_vy;
        }
        old_x = x;
        old_y = y;
        x += vx * dt;
        y += vy * dt;
    
        Interact();
    
        if(isBounded)
        {
          if(isPeriodicBound)
          {
            PeriodicBound();
          }
          else
          {
            Bound();
          }
        }
      }
    
      boolean PointInside(float px, float py)
      {
        float dx = px - x;
        float dy = py - y;
        float d2 = dx*dx + dy*dy;
        if(d2 < r_visual * r_visual)
        {
          return true;
        }
        return false;
      }
    
      void Interact()
      {
        attractedCount = 0;
        for(int i = 0; i < ps.size(); i++)
        {
          Particle other = (Particle)ps.get(i);
          if(this != other)
          {
            float dx = x - other.x;
            float dy = y - other.y;
            float d = sqrt(dx*dx + dy*dy);
            if(d > 0)
            {
              float u_fx = dx / d;
              float u_fy = dy / d;
              if(attractedCount < attractable_count)
              {
                Attract(other, d, u_fx, u_fy);
              }
              Repulse(other, d, u_fx, u_fy);
            }
          }
        }
      }
    
    
    
      void Repulse(Particle other, float d, float u_fx, float u_fy)
      {
        float R = R_eff + other.R_eff;
        if(d < R)
        {
          float power = (R - d) * 0.5;
    
          if(repulse_hard)
          {
            if(this != selectedPtcl)
            {
              x += u_fx * power;
              y += u_fy * power;
            }
            if(other != selectedPtcl)
            {
              other.x += -u_fx * power;
              other.y += -u_fy * power;
            }
          }
          if(repulse_bouncy)
          {
            vx += u_fx * power * repulsive_factor;
            vy += u_fy * power * repulsive_factor;
            other.vx += -u_fx * power * repulsive_factor;
            other.vy += -u_fy * power * repulsive_factor;
          }
        }  
      }
    
      void Attract(Particle other, float d, float u_fx, float u_fy)
      {
        if(d > R_eff && d < r_view)
        {
          float f = (d - R_eff) / (r_view - R_eff);
          float power = cos(f * PI * 0.5) * 2;
          vx += -u_fx * power;
          vy += -u_fy * power;
          if(show_network)
          {
            if(d < r_view)
            {
              int i0 = ps.indexOf(this);
              int i1 = ps.indexOf(other);
              if(i0 < i1)
              {
                Link li = new Link(this, other);
                if(!ls.contains(li)) ls.add(li);
              }
              else
              {
                Link li = new Link(other, this);
                if(!ls.contains(li)) ls.add(li);
              }
            }
          }
          attractedCount++;
        }   
      }
    
      void Bound()
      {
        m_alpha = 1;
        if(x < r_eff || x > pg.width-r_eff) vx += (pg.width * 0.5 - x) * dt;
        if(y < r_eff|| y > pg.height-r_eff) vy += (pg.height * 0.5 - y) * dt;
        x = constrain(x, r_eff, pg.width-r_eff);
        y = constrain(y, r_eff, pg.height-r_eff);
      }
    
      void PeriodicBound()
      {
        boolean inside = true;
        if(x < r_eff || x > pg.width-r_eff) inside = false;
        if(y < r_eff|| y > pg.height-r_eff) inside = false;
        if(inside) m_alpha = 1; else m_alpha = 0;
        
        float r_eff2 = r_eff * 2;
        if(x < -r_eff2) x = pg.width + r_eff;
        else if(x > pg.width + r_eff2) x = -r_eff;
        if(y < -r_eff2) y = pg.height + r_eff;
        else if(y > pg.height + r_eff2) y = -r_eff;
      }
    
      void Draw(PGraphics pg)
      {
        pg.fill(cR + cD, cG + cD, cB + cD, Alpha * p_alpha);
        r_visual = R_eff - 5;
        pg.ellipse(x, y, r_visual * 2, r_visual * 2);
      }
    
      void DrawV(PGraphics pg)
      {
        float r = r_visual - 2;
        pg.line(x, y, x + r* u_vx, y + r * u_vy);
      }
    
      void DrawTrail(PGraphics pg)
      {
        float dx = old_x - x;
        float dy = old_y - y;
        float d = sqrt(dx*dx+dy*dy);
        if(d < max_speed)
        {
          //float gr = (cR + cG + cB) / 3 + cD;
          pg.stroke(cR + cD, cG + cD, cB + cD, Alpha * p_alpha);
          pg.line(old_x, old_y, x, y);
        }
      }
    
      void DrawReff(PGraphics pg)
      {
        pg.stroke(0, 255, 0, 255);
        pg.ellipse(x, y, R_eff * 2, R_eff * 2); 
      }
    
      void DrawRview(PGraphics pg)
      {
        pg.stroke(0, 0, 255, 255);
        pg.ellipse(x, y, r_view * 2, r_view * 2); 
      }
    }
    
    
    
    
    
    

    code

    tweaks (0)

    about this sketch

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

    license

    advertisement

    Report Sketch

    Report for inappropriate content

    Please provide details if possible:

    Your have successfully reported the sketch. Thank you very much for helping to keep OpenProcessing clean and tidy :)

    Make a Copyright Infringement claim

    Seung Joon Choi

    Organizing Critters

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

    An extension for the 'Organizing Particles'.
    http://www.openprocessing.org/visuals/?visualID=6672

    The background texture matches correctly in orthographic mode.
    You can select and drag a critter by the mouse.

    Particles became critters.

    subpixel
    26 Dec 2009
    Excellent! I love your little bounding critters! :o)
    bitcraft
    27 Dec 2009
    Wow! Electric sheep :-)
    shaocong zhou
    27 Dec 2009
    I like this farm!
    kisoon Eom
    28 Dec 2009
    Wow~
    Xiaohan Zhang
    1 Jan 2010
    fantastic! i love it.
    haptiK
    4 Jan 2010
    This is fantastic!
    haptiK
    4 Jan 2010
    This is fantastic!
    Ahram Choi
    13 Jan 2010
    fantastic!
    I lo ve it
    Ivanka Horoshko
    17 Jan 2010
    this is amazing!!!!
    Deepak Dhawan
    17 Feb 2010
    simply outstanding... wish 1 day i could also make something like this.
    johan wastring
    17 Jun 2010
    Excellent!
    Cory Hughart
    18 May 2011
    This makes me want to play Minecraft! :D Excellent work!
    noir
    26 Jun 2011
    so~~ cute~~~
    xichen
    9 Oct 2012
    SO CUTE!!!!!
    oat cracker
    12 Nov 2012
    interesting work!

    I got the following error message:"the type PGraphics3D is ambiguous" when trying to run the code..

    Any suggestion?
    Paul Hoover
    20 Nov 2012
    I got the same message. Tried downloading a couple plugins, but no help. I would love to tinker with this amazing work.
    Paul Hoover
    20 Nov 2012
    Looks like the error might be because of an upgrade to mountain lion. I might try an older version of processing to fix it.
    Michael S
    12 Sep 2013
    Beautiful. Wonderful outcome.
    You need to login/register to comment.