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