Python Tutorials | (back to the list of tutorials) |
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)