Python Tutorials | (back to the list of tutorials) |
Multi-Agent 2D Example 4![]()
![]()
![]()
![]()
add_library('igeo')
def setup() :
size(480,360,IG.GL)
IRand.init(3)
IG.duration(700)
LineAgent(IG.v(-0.1,0,0), IG.v(1,0,0)).clr(0)
LineAgent(IG.v(500,-0.1,0), IG.v(0,1,0)).clr(0)
LineAgent(IG.v(500+0.1,500,0), IG.v(-1,0,0)).clr(0)
LineAgent(IG.v(0,500+0.1,0), IG.v(0,-1,0)).clr(0)
for i in range(10) :
LineAgent(IRand.pt(100,100,0,400,400,0), IRand.pt(-10,-10,0,10,10,0)).clr(IRand.clr(0.4,0.4,0.4))
class LineAgent(IAgent) :
# static variable constants
length = 2
clearance = 1.99 #less than length
angleThreshold = PI/20
threshold = 10
def __init__(self, pt, dir) :
self.pt1 = pt
self.pt2 = pt.cp(dir.cp().len(LineAgent.length))
self.isColliding = False
self.angle = 0
self.minDist = 0
self.frontAngle = 0
def interact(self, agents) :
if self.time() == 0 : #only in the first time
self.minDist = -1 #reset
for agent in agents :
if self.isColliding :
return
if isinstance(agent, LineAgent) and agent is not self :
# checking clearance of end point
dist = agent.pt2.dist(self.pt2)
if dist < LineAgent.clearance :
self.isColliding=True
elif dist < LineAgent.threshold : #not colliding but close
#check if not the parent and in front and closest one
if not self.pt1.eq(agent.pt2) and \
self.pt2.dif(self.pt1).angle(agent.pt2.dif(self.pt1)) < LineAgent.angleThreshold and \
(self.minDist < 0 or dist < self.minDist) :
self.minDist = dist
self.frontAngle = self.pt2.dif(self.pt1).angle(agent.pt2.dif(agent.pt1),IG.zaxis)
def update(self) :
if self.time() == 0 :
if self.isColliding :
self.del()
else : #if not colliding
ICurve(self.pt1,self.pt2).clr(self.clr())
dir = self.pt2.dif(self.pt1)
if IRand.pct(1) : #branching
r = self.red()+IRand.get(-0.1,0.1)
g = self.green()+IRand.get(-0.1,0.1)
b = self.blue()+IRand.get(-0.1,0.1)
LineAgent(self.pt2, dir.cp().rot(IRand.get(PI/3,2*PI/3))).clr(r,g,b)
if self.frontAngle < 0 :
self.frontAngle+=PI #going in only one direction
r = self.red()+IRand.get(-0.03,0.03)
g = self.green()+IRand.get(-0.03,0.03)
b = self.blue()+IRand.get(-0.03,0.03)
LineAgent(self.pt2, dir.rot(self.frontAngle)).clr(r,g,b)
The next code change the previous code to round the turning corner by bending the lines with a few segments. To enable bending through multiple generation of agents, the instance field of bendAngle and bendCount are added to LineAgent class.
![]()
![]()
![]()
![]()
add_library('igeo')
def setup() :
size(480,360,IG.GL)
IRand.init(2)
IG.duration(700)
LineAgent(IG.v(-0.1,0,0),IG.v(1,0,0),0,0).clr(0)
LineAgent(IG.v(500,-0.1,0),IG.v(0,1,0),0,0).clr(0)
LineAgent(IG.v(500+0.1,500,0),IG.v(-1,0,0),0,0).clr(0)
LineAgent(IG.v(0,500+0.1,0),IG.v(0,-1,0),0,0).clr(0)
LineAgent(IG.v(500/2,0,0),IG.v(1,0,0),0,0).clr(0)
LineAgent(IG.v(500,500/2,0),IG.v(0,1,0),0,0).clr(0)
LineAgent(IG.v(500/2,500,0),IG.v(-1,0,0),0,0).clr(0)
LineAgent(IG.v(0,500/2,0),IG.v(0,-1,0),0,0).clr(0)
for i in range(30) :
LineAgent(IRand.pt(100,100,0,400,400,0),IRand.pt(-10,-10,0,10,10,0),0,0).clr(IRand.clr(0.4,0.4,0.4))
class LineAgent(IAgent) :
# static variable constants
length = 2
clearance = 1.99 #less than length
angleThreshold = PI/20
threshold = 10
bendSize = 2
def __init__(self, pt, dir, bend, bcount) :
self.pt1 = pt
self.pt2 = pt.cp(dir.cp().len(LineAgent.length))
self.isColliding = False
self.minDist = 0
self.frontAngle = 0
self.bendAngle = bend
self.bendCount = bcount
def interact(self, agents) :
if self.time() == 0 : #only in the first time
self.minDist = -1 #reset
for agent in agents :
if self.isColliding :
return
if isinstance(agent, LineAgent) and agent is not self :
# checking clearance of end point
dist = agent.pt2.dist(self.pt2)
if dist < LineAgent.clearance :
self.isColliding=True
elif dist < LineAgent.threshold : #not colliding but close
#check if not the parent and in front and closest one
if not self.pt1.eq(agent.pt2) and \
self.pt2.dif(self.pt1).angle(agent.pt2.dif(self.pt1)) < LineAgent.angleThreshold and \
(self.minDist < 0 or dist < self.minDist) :
self.minDist = dist
self.frontAngle = self.pt2.dif(self.pt1).angle(agent.pt2.dif(agent.pt1),IG.zaxis)
def update(self) :
if self.time() == 0 :
if self.isColliding :
self.del()
else : #if not colliding
ICurve(self.pt1,self.pt2).clr(self.clr())
dir = self.pt2.dif(self.pt1)
if IRand.pct(1) : #branching
r = self.red()+IRand.get(-0.1,0.1)
g = self.green()+IRand.get(-0.1,0.1)
b = self.blue()+IRand.get(-0.1,0.1)
LineAgent(self.pt2,dir.cp().rot(IRand.get(PI/3,2*PI/3)),0,0).clr(r,g,b)
r = self.red()+IRand.get(-0.03,0.03)
g = self.green()+IRand.get(-0.03,0.03)
b = self.blue()+IRand.get(-0.03,0.03)
#checking bend
if self.bendCount == 0 and self.minDist >=0 and self.frontAngle!=0 :
if self.frontAngle < 0 :
self.frontAngle+=PI #going in only one direction
self.bendCount = LineAgent.bendSize
self.bendAngle = self.frontAngle/self.bendCount
if self.bendCount > 0 : #bending
dir.rot(self.bendAngle)
LineAgent(self.pt2, dir, self.bendAngle, self.bendCount-1).clr(r,g,b)
else : #go straight
LineAgent(self.pt2, dir, 0, 0).clr(r,g,b)
HOME
FOR PROCESSING
DOWNLOAD
DOCUMENTS
TUTORIALS (Java /
Python)
GALLERY
SOURCE CODE(GitHub)
PRIVACY POLICY
ABOUT/CONTACT