home processing download documents tutorial python tutorial gallery source about
 Python 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.

add_library('igeo')

def setup() :
    size(480,360,IG.GL)
    IG.duration(360)
    num=200
    for i in range(num): 
        pos = IG.v(100,0,0).rot(2*PI*i/num)
        vel = IG.v(-40,0,0).rot(2*PI*i/num)
        MyParticle(pos, vel).fric(0.012).hsb(1.0/num*i,1,1)
    
    for i in range(8) : 
        Attractor(IRand.pt(-120,-120,0,80,80,0)).clr(1.0,0,0)

class Attractor(IPointAgent) : 
    threshold = 100
    gravity = 300.0
    minDist = 1.0
    
    def __init__(self, v) : 
        IPointAgent.__init__(self, v)
    
    def interact(self, agents) :
        for agent in agents : 
            if isinstance(agent, MyParticle) : 
                dif = self.pos().dif(agent.pos())
                dist = dif.len()
                if dist < Attractor.threshold :
                    if dist < Attractor.minDist : 
                        dist = Attractor.minDist
                    strength = Attractor.gravity/dist #the closer the larger
                    force = dif.len(strength)
                    agent.push(force)

class MyParticle(IParticle) : 
    def __init__(self, p, v) : 
        IParticle.__init__(self,p,v)
        self.prevPos = None
    
    def update(self) :
        curPos = self.pos().cp()
        if self.prevPos is not None : 
            ICurve(self.prevPos, curPos).clr(self.clr())
        self.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.

add_library('igeo')

def setup() : 
    size(480,360,IG.GL)
    IG.duration(450)
    num=100
    for i in range(num) : 
        if IRand.pct(97) :
            pos = IG.v(100,0,0).rot(2*PI*i/num)
            vel = IG.v(-20,0,0).rot(2*PI*i/num)
            MyParticle(pos, vel).fric(0.001).hsb(1.0/num*i,1,1)
    
    for i in range(3) : 
        Attractor(IRand.pt(-120,-120,0,80,80,0)).clr(1.0,0,0)

class Attractor(IPointAgent) : 
    threshold = 100
    gravity = 300.0
    minDist = 1.0
    
    def __init__(self, v) : 
        IPointAgent.__init__(self, v)
    
    def interact(self, agents) :
        for agent in agents : 
            if isinstance(agent, MyParticle) : 
                dif = self.pos().dif(agent.pos())
                dist = dif.len()
                if dist < Attractor.threshold :
                    if dist < Attractor.minDist : 
                        dist = Attractor.minDist
                    strength = Attractor.gravity/dist #the closer the larger
                    force = dif.len(strength)
                    agent.push(force)

class MyParticle(IParticle) : 
    threshold = 30
    gravity = 2.0
    
    def __init__(self, p, v) : 
        IParticle.__init__(self,p,v)
        self.prevPos = None
    
    def interact(self, agents) :
        center = None
        num = 0
        for agent in agents :
            if isinstance(agent, MyParticle) : 
                if agent is not self :
                    if agent.pos().dist(self.pos()) < MyParticle.threshold :
                        if center is None :
                            center = agent.pos().dup()
                        else :
                            center.add(agent.pos())
                        num += 1
        if num > 0 :
            center.div(num)
            force = center.dif(self.pos()).mul(MyParticle.gravity)
            self.push(force)
    
    def update(self) :
        curPos = self.pos().cp()
        if self.prevPos is not None : 
            ICurve(self.prevPos, curPos).clr(self.clr())
        self.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.

add_library('igeo')

def setup() : 
    size(480,360,IG.GL)
    IG.duration(250)
    num=100
    for i in range(num) : 
        for j in range(2) : 
            if IRand.pct(70) : 
                pos = IG.v(i, j*100, 0)
                vel = IG.v(0, (30-j*55), 0)
                MyParticle(pos,vel).fric(0.008).clr(IRand.clr())

class MyParticle(IParticle) : 
    threshold = 15
    gravity = 25.0
    
    def __init__(self, p, v) : 
        IParticle.__init__(self,p,v)
        self.prevPos = None
    
    def interact(self, agents) :
        center = None
        num = 0
        for agent in agents :
            if isinstance(agent, MyParticle) : 
                if agent is not self :
                    if agent.pos().dist(self.pos()) < MyParticle.threshold :
                        if center is None :
                            center = agent.pos().dup()
                        else :
                            center.add(agent.pos())
                        num += 1
        if num > 0 :
            center.div(num)
            force = center.dif(self.pos()).mul(MyParticle.gravity)
            self.push(force)
    
    def update(self) :
        curPos = self.pos().cp()
        if self.prevPos is not None : 
            ICurve(self.prevPos, curPos).clr(self.clr())
        self.prevPos = curPos


(back to the list of tutorials)

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