• fullscreen
  • Swarm.pde
  • particle.pde
  • // Gravity Swarm
    // Claudio Gonzales, June 2009
    // Albuquerque, New Mexico
    
    particle[] Z = new particle[6000];
    float colour = random(1);
    
    void setup() {
      smooth();
      size(500,500,P2D);  
      background(255);
      
      for(int i = 0; i < Z.length; i++) {
        Z[i] = new particle( random(width), random(height), 0, 0, 1 );
      }
      
      frameRate(60);
      colorMode(RGB,255);
    
    }
    
    void draw() {
      
      filter(INVERT);
    
      float r;
    
      stroke(0);
      fill(255);
      rect(0,0,width,height);
      
      colorMode(HSB,1);
      for(int i = 0; i < Z.length; i++) {
        if( mousePressed && mouseButton == LEFT ) {
          Z[i].gravitate( new particle( mouseX, mouseY, 0, 0, 1 ) );
        }
        else if( mousePressed && mouseButton == RIGHT ) {
          Z[i].repel( new particle( mouseX, mouseY, 0, 0, 1 ) );
        }
        else {
          Z[i].deteriorate();
        }
        Z[i].update();
        r = float(i)/Z.length;
        stroke( colour, pow(r,0.1), 1-r, 0.15 );
        Z[i].display();
      }
      colorMode(RGB,255);
      
      colour+=random(0.01);
      if( colour > 1 ) { 
        colour = colour%1;
      }
    
      filter(INVERT);
      
    }
    
    
    
    class particle {
      
      float x;
      float y;
      float px;
      float py;
      float magnitude;
      float angle;
      float mass;
      
      particle( float dx, float dy, float V, float A, float M ) {
        x = dx;
        y = dy;
        px = dx;
        py = dy;
        magnitude = V;
        angle = A;
        mass = M;
      }
      
      void reset( float dx, float dy, float V, float A, float M ) {
        x = dx;
        y = dy;
        px = dx;
        py = dy;
        magnitude = V;
        angle = A;
        mass = M;
      }
      
      void gravitate( particle Z ) {
        float F, mX, mY, A;
        if( sq( x - Z.x ) + sq( y - Z.y ) != 0 ) {
          F = mass * Z.mass;
          mX = ( mass * x + Z.mass * Z.x ) / ( mass + Z.mass );
          mY = ( mass * y + Z.mass * Z.y ) / ( mass + Z.mass );
          A = findAngle( mX - x, mY - y );
          
          mX = F * cos(A);
          mY = F * sin(A);
          
          mX += magnitude * cos(angle);
          mY += magnitude * sin(angle);
          
          magnitude = sqrt( sq(mX) + sq(mY) );
          angle = findAngle( mX, mY );
        }
      }
    
      void repel( particle Z ) {
        float F, mX, mY, A;
        if( sq( x - Z.x ) + sq( y - Z.y ) != 0 ) {
          F = mass * Z.mass;
          mX = ( mass * x + Z.mass * Z.x ) / ( mass + Z.mass );
          mY = ( mass * y + Z.mass * Z.y ) / ( mass + Z.mass );
          A = findAngle( x - mX, y - mY );
          
          mX = F * cos(A);
          mY = F * sin(A);
          
          mX += magnitude * cos(angle);
          mY += magnitude * sin(angle);
          
          magnitude = sqrt( sq(mX) + sq(mY) );
          angle = findAngle( mX, mY );
        }
      }
      
      void deteriorate() {
        magnitude *= 0.925;
      }
      
      void update() {
        
        x += magnitude * cos(angle);
        y += magnitude * sin(angle);
        
      }
      
      void display() {
        line(px,py,x,y);
        px = x;
        py = y;
      }
      
      
    }
    
    float findAngle( float x, float y ) {
      float theta;
      if(x == 0) {
        if(y > 0) {
          theta = HALF_PI;
        }
        else if(y < 0) {
          theta = 3*HALF_PI;
        }
        else {
          theta = 0;
        }
      }
      else {
        theta = atan( y / x );
        if(( x < 0 ) && ( y >= 0 )) { theta += PI; }
        if(( x < 0 ) && ( y < 0 )) { theta -= PI; }
      }
      return theta;
    }
     
    

    code

    tweaks (0)

    about this sketch

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

    license

    advertisement

    Claudio Gonzales

    Gravity Swarm

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

    A similar sketch to my gravity well, but the particles' gravity attraction are no longer affected by the distance between them and the gravity well's center. Additionally, the well is now activated/deactivated and placed by the user's mouse click.

    Petr Vacek
    14 Jun 2009
    Spectacular view. Works much faster with P2D surface for me, especially with enormous particle counts.
    Claudio Gonzales
    14 Jun 2009
    Noted, and thank you! Code updated in P2D.
    Nice eyecandy. Very fun to get the particles all bunched up and then trying to spray them apart again, or catapulting them away and sucking them back.
    Yser C.
    15 Jun 2009
    Delightful!
    Claudio Gonzales
    16 Jun 2009
    Updated with a repelling function, activated by a right mouse click. Left clicking still causes attraction.
    cristian
    13 Jul 2009
    sos un zarpado, la concha de la lora!!! q bueno q esta!!!1
    saludos desde buenos aires!!
    Floris Ver.
    13 Oct 2009
    holy shi* this is one of the most awesomest i've seen
    shaocong zhou
    15 Oct 2009
    This is so beautiful!
    Ivan Burghart
    19 Oct 2009
    I could play with this for hours. Very nice.
    haptiK
    9 Dec 2009
    Exceptional code. As a beginner I am struck with awe. If I could add this to my favorites twice, I would.
    Hello, my name is Elliot Blanchard - I'm a director and motion designer. I love your work - would you be interested in collaborating on an interactive piece?

    You can see my recent projects at http://www.royalcolornetwork.com.
    gendou
    25 Dec 2009
    Beautiful and entertaining!
    Fake Name
    28 Feb 2010
    Entertaining, memorizing, beautiful, awesome, amazing, unique, and tons more descriptions all fall into this game. That really says something!
    Torgeir Sollid
    3 Mar 2010
    Holy cow!!! That is very nice!
    Aaron Bustillo
    4 Jun 2010
    thats a rasengan....
    nahh seriously awesome, i just started programing and this made a few tears drop
    Nathan Nifong
    3 Aug 2010
    This is the most hypnotic thing on the Internet
    Thomas
    21 Jan 2011
    So simple, so amazing
    Charter Jacobson
    23 Jan 2011
    Dude, you should make this an iTunes visualizer, so spikes in volume level would be clicks, pitch would be x position, and loudness would be y position. Btw, What programming language is it in?
    Claudio Gonzales
    24 Jan 2011
    That is a brilliant idea, my friend. I'll have to look into Processing's audio capabilities, that's something I've never explored... (which, naturally, is the language I coded this in)
    Yago de Quay
    12 Feb 2011
    o_O
    Gerard Geer
    18 Jun 2011
    By adding these two lines to "update()" this gets pretty crazy. I'm curious as to why you didn't do this in the first place:

    if(x&lt;0||x&gt;width){magnitude*=-1;}
    if(y&lt;0||y&gt;width){magnitude*=-1;}
    Gerard Geer
    18 Jun 2011
    Of course, that second "width" should be height...
    Claudio Gonzales
    23 Jun 2011
    Simply because I prefer the natural motion of movement uninhibited by walls or boundaries. Also, an experienced user can manage some impressive tricks and create interesting constructs (even a simple string or band-like formation of particles) by slinging them off-window.
    Sixing Huang
    5 Aug 2011
    Impressive visual effect!!
    one of the coolest things i've ever seen. it's so -- fluid.
    You need to login/register to comment.