home processing download documents tutorial python tutorial gallery source about
 Tutorials (back to the list of tutorials)

Physics Simulation and Swarm Example

     Physics Simulation Example 1 (requires iGeo version 7.5.2 or higher)

The particle example below defines the attractor class and shows the behavior of the particles under the attractors.

import processing.opengl.*;
import igeo.*;

void setup(){
  size(480,360,IG.GL);
  IG.duration(360);
  int num=200;
  for(int i=0; i < num; i++){
    IVec pos = IG.v(100,0,0).rot(2*PI*i/num);
    IVec vel = IG.v(-40,0,0).rot(2*PI*i/num);
    new MyParticle(pos, vel).fric(0.012).hsb(1.0/num*i,1,1);
  }
  for(int i=0; i < 8; i++){
    new Attractor(IRand.pt(-120,-120,0,80,80,0)).clr(1.0,0,0);
  }
}

class Attractor extends IPointAgent{
  final double threshold = 100;
  final double gravity = 300.0;
  final double minDist = 1.0;

  Attractor(IVec v){ super(v); }
  
  void interact(ArrayList agents){
    for(int i=0; i < agents.size(); i++){
      if(agents.get(i) instanceof MyParticle){
        MyParticle agent = (MyParticle)agents.get(i);
        IVec dif = pos().dif(agent.pos());
        double dist = dif.len();
        if(dist < threshold){
          if(dist < minDist){ dist = minDist; }
          double strength = gravity/dist; //the closer the larger
          IVec force = dif.len(strength);
          agent.push(force);
        }
      }
    }
  }
}

class MyParticle extends IParticle{
  IVec prevPos;
  
  MyParticle(IVec p, IVec v){ super(p,v); }

  void update(){
    IVec curPos = pos().cp();
    if(prevPos!=null){
      new ICurve(prevPos, curPos).clr(clr());
    }
    prevPos = curPos;
  }
}

The next code below adds interaction method in MyParticle to introduce gravity between particles themselves. The particles are taking forces not only towards the attractor agents but also other particle agents.

import processing.opengl.*;
import igeo.*;

void setup(){
  size(480,360,IG.GL);
  IG.duration(450);
  int num=100;
  for(int i=0; i < num; i++){
    if(IRand.pct(97)){
      IVec pos = IG.v(100,0,0).rot(2*PI*i/num);
      IVec vel = IG.v(-20,0,0).rot(2*PI*i/num);
      new MyParticle(pos, vel).fric(0.001).hsb(1.0/num*i,1,1);
    }
  }
  for(int i=0; i < 3; i++){
    new Attractor(IRand.pt(-120,-120,0,80,80,0)).clr(1.0,0,0);
  }
}

class Attractor extends IPointAgent{
  final double threshold = 100;
  final double gravity = 300.0;
  final double minDist = 1.0;

  Attractor(IVec v){ super(v); }
  
  void interact(ArrayList agents){
    for(int i=0; i < agents.size(); i++){
      if(agents.get(i) instanceof MyParticle){
        MyParticle agent = (MyParticle)agents.get(i);
        IVec dif = pos().dif(agent.pos());
        double dist = dif.len();
        if(dist < threshold){
          if(dist < minDist){ dist = minDist; }
          double strength = gravity/dist; //the closer the larger
          IVec force = dif.len(strength);
          agent.push(force);
        }
      }
    }
  }
}

class MyParticle extends IParticle{
  final double threshold = 30;
  final double gravity = 2.0;
  IVec prevPos;
  
  MyParticle(IVec p, IVec v){ super(p,v); }
  
  void interact(ArrayList < IDynamics > agents){
    IVec center=null;
    int num=0;
    for(int i=0; i < agents.size(); i++){
      if(agents.get(i) instanceof MyParticle){
        MyParticle a = (MyParticle)agents.get(i);
        if(a != this){
          if(a.pos().dist(pos()) < threshold){
            if(center==null) center = a.pos().dup();
            else{ center.add(a.pos()); }
            num++;
          }
        }
      }
    }
    if(num > 0){
      center.div(num);
      IVec force = center.dif(pos()).mul(gravity);
      push(force);
    }
  }

  void update(){
    IVec curPos = pos().cp();
    if(prevPos!=null){
      new ICurve(prevPos, curPos).clr(clr());
    }
    prevPos = curPos;
  }
}

The code below shows behavior of the particle agents with self gravity among the particles without any external attractors. It also changes the initial configuration of particle agents putting them on two lines.

import processing.opengl.*;
import igeo.*;

void setup(){
  size(480,360,IG.GL);
  IG.duration(250);
  int num=100;
  for(int i=0; i < num; i++){
    for(int j=0; j < 2; j++){
      if(IRand.pct(70)){
        IVec pos = IG.v(i, j*100, 0);
        IVec vel = IG.v(0, (30-j*55), 0);
        new MyParticle(pos, vel).fric(0.008).clr(IRand.clr());
      }
    }
  }
}

class MyParticle extends IParticle{
  final double threshold = 15;
  final double gravity = 25.0;
  IVec prevPos;
  
  MyParticle(IVec p, IVec v){ super(p,v); }
  
  void interact(ArrayList < IDynamics > agents){
    IVec center=null;
    int num=0;
    for(int i=0; i < agents.size(); i++){
      if(agents.get(i) instanceof MyParticle){
        MyParticle a = (MyParticle)agents.get(i);
        if(a != this){
          if(a.pos().dist(pos()) < threshold){
            if(center==null) center = a.pos().dup();
            else{ center.add(a.pos()); }
            num++;
          }
        }
      }
    }
    if(num > 0){
      center.div(num);
      IVec force = center.dif(pos()).mul(gravity);
      push(force);
    }
  }

  void update(){
    IVec curPos = pos().cp();
    if(prevPos!=null){
      new ICurve(prevPos, curPos).clr(clr());
    }
    prevPos = curPos;
  }
}


(back to the list of tutorials)

HOME
FOR PROCESSING
DOWNLOAD
DOCUMENTS
TUTORIALS (Java / Python)
GALLERY
SOURCE CODE(GitHub)
ABOUT