Python Tutorials | (back to the list of tutorials) |
Multi-Agent 3D Example 2 (requires iGeo version 7.6.0 or higher)![]()
![]()
![]()
![]()
add_library('igeo')
def setup() :
size(480, 360, IG.GL)
IG.duration(300)
# left 100%, right 4.5%
LineAgent(IG.v(0,0,0), IG.v(2,0,0), 100.0, 4.5).clr(0)
class LineAgent(IAgent) :
def __init__(self, pt, dir, pctL, pctR) :
self.pos = pt
self.dir = dir
self.pctL = pctL
self.pctR = pctR
self.isColliding=False
self.itxn = None
def interact(self, agents) :
if self.time()==0 :
for agent in agents :
if self.isColliding :
return
if isinstance(agent, LineAgent) and agent is not self :
pos2 = self.pos.cp(self.dir)
apos2 = agent.pos.cp(agent.dir)
if not apos2.eq(self.pos) and not agent.pos.eq(self.pos) : #not sharing root
self.itxn = IVec.intersectLine(agent.pos,apos2,self.pos,pos2) #keep intersection to draw line later
if self.itxn is not None : #intersecting
self.isColliding=True
def update(self) :
if self.time()==0 :
pos2 = self.pos.dup().add(self.dir)
thickness = 0.3
widthDir = self.dir.dup().rot(PI/2).len(thickness/2)
z1 = sin(IG.time()*0.05)*10+15
z2 = sin((IG.time()+1)*0.05)*10+15
meshPt1 = self.pos
meshPt2 = pos2
if self.isColliding :
meshPt2 = self.itxn
IG.meshBox(meshPt1.cp().sub(widthDir),\
meshPt2.cp().sub(widthDir),\
meshPt2.cp().add(widthDir),\
meshPt1.cp().add(widthDir),\
meshPt1.cp().sub(widthDir).add(0,0,z1),\
meshPt2.cp().sub(widthDir).add(0,0,z2),\
meshPt2.cp().add(widthDir).add(0,0,z2),\
meshPt1.cp().add(widthDir).add(0,0,z1)).clr(self.clr())
if self.isColliding :
self.del()
return
r = self.red() + IRand.get(-0.05, 0.05)
g = self.green() + IRand.get(-0.05, 0.05)
b = self.blue() + IRand.get(-0.05, 0.05)
branchL = IRand.pct(self.pctL)
branchR = IRand.pct(self.pctR)
lenL = self.dir.len()
lenR = self.dir.len()
lenL*=0.995 #shrinking length
lenR*=0.995 #shrinking length
if branchL and branchR : #only when branching both
if IRand.pct(50.0) :
if self.pctL < self.pctR :
lenL *= 0.9
else :
lenR *= 0.9
elif IRand.pct(6.0) :
if self.pctL < self.pctR :
lenL *= 0.4
else :
lenR *= 0.4
elif IRand.pct(5.0) :
if self.pctL < self.pctR :
lenL *= 4
else :
lenR *= 4
if branchL : #bend left
dir2 = self.dir.dup()
dir2.len(lenL) #update length
dir2.rot(PI/30)
if branchR and self.pctR > self.pctL : #swap L/R% when branching both
LineAgent(pos2, dir2, self.pctR, self.pctL).clr(r,g,b)
else :
LineAgent(pos2, dir2, self.pctL, self.pctR).clr(r,g,b)
if branchR : #bend right
dir2 = self.dir.dup()
dir2.len(lenR) #update length
dir2.rot(-PI/30)
if branchL and self.pctR < self.pctL : #swap L/R% when branching both
LineAgent(pos2, dir2, self.pctR, self.pctL).clr(r,g,b)
else :
LineAgent(pos2, dir2, self.pctL, self.pctR).clr(r,g,b)
The example code below takes the previous tutorial code at "Multi-Agent 2D Example 3" and layering multiple agents in different z levels and interconnect them. All the branches and interconnection lines are made out of polygon mesh sticks.
![]()
![]()
![]()
![]()
add_library('igeo')
def setup() :
size(480, 360, IG.GL)
IG.duration(80)
z = 0
for i in range(20) :
#IRand.dir() is giving a random direction with given length perpendicular to given axis
LineAgent(IRand.pt(-30,-30,z,30,30,z), IRand.dir(IG.zaxis,2),100.0,4.5).clr(0)
z += IRand.get(1,5)
class LineAgent(IAgent) :
def __init__(self, pt, dir, pctL, pctR) :
self.pos = pt
self.dir = dir
self.pctL = pctL
self.pctR = pctR
self.isColliding = False
self.itxn = None
def interact(self, agents) :
if self.time()==0 :
for agent in agents :
if self.isColliding :
return
if isinstance(agent, LineAgent) and agent is not self :
#draw interconnection in z
if not self.pos.eqZ(agent.pos) : #z is not equal
minLen = self.dir.len()
if agent.dir.len() < minLen :
minLen = agent.dir.len()
threshold = minLen * 2.5
if self.pos.eqX(agent.pos, threshold) and\
self.pos.eqY(agent.pos, threshold) : #x and y is equal with in given tolerance
if IRand.pct(60) :
#ICurve(self.pos,agent.pos).clr(self.clr())
IG.meshSquareStick(self.pos,agent.pos,0.3).clr(self.clr())
else :
pos2 = self.pos.cp(self.dir)
apos2 = agent.pos.cp(agent.dir)
if not apos2.eq(self.pos) and not agent.pos.eq(self.pos) : #not sharing root
self.itxn = IVec.intersectLine(agent.pos,apos2,self.pos,pos2) #keep intersection to draw line later
if self.itxn is not None : #intersecting
self.isColliding=True
def update(self) :
if self.time()==0 :
if self.isColliding :
#ICurve(self.pos, self.itxn).clr(self.clr())
IG.meshSquareStick(self.pos, self.itxn, 0.5).clr(self.clr()) #keep line to intersection
self.del()
return
pos2 = self.pos.dup().add(self.dir)
#ICurve(self.pos, self.pos2).clr(self.clr())
IG.meshSquareStick(self.pos, pos2, 0.5).clr(self.clr())
r = self.red() + IRand.get(-0.05, 0.05)
g = self.green() + IRand.get(-0.05, 0.05)
b = self.blue() + IRand.get(-0.05, 0.05)
branchL = IRand.pct(self.pctL)
branchR = IRand.pct(self.pctR)
lenL = self.dir.len()
lenR = self.dir.len()
lenL*=0.995 #shrinking length
lenR*=0.995 #shrinking length
if branchL and branchR : #only when branching both
if IRand.pct(50.0) :
if self.pctL < self.pctR :
lenL *= 0.9
else :
lenR *= 0.9
elif IRand.pct(6.0) :
if self.pctL < self.pctR :
lenL *= 0.4
else :
lenR *= 0.4
elif IRand.pct(5.0) :
if self.pctL < self.pctR :
lenL *= 1.4
else :
lenR *= 1.4
if branchL : #bend left
dir2 = self.dir.dup()
dir2.len(lenL) #update length
dir2.rot(PI/30)
if branchR and self.pctR > self.pctL : #swap L/R% when branching both
LineAgent(pos2, dir2, self.pctR, self.pctL).clr(r,g,b)
else :
LineAgent(pos2, dir2, self.pctL, self.pctR).clr(r,g,b)
if branchR : #bend right
dir2 = self.dir.dup()
dir2.len(lenR) #update length
dir2.rot(-PI/30)
if branchL and self.pctR < self.pctL : #swap L/R% when branching both
LineAgent(pos2, dir2, self.pctR, self.pctL).clr(r,g,b)
else :
LineAgent(pos2, dir2, self.pctL, self.pctR).clr(r,g,b)
HOME
FOR PROCESSING
DOWNLOAD
DOCUMENTS
TUTORIALS (Java /
Python)
GALLERY
SOURCE CODE(GitHub)
PRIVACY POLICY
ABOUT/CONTACT