Python Tutorials | (back to the list of tutorials) |
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.duration(100) LineAgent(IVec(0,0,0), IVec(1,0,0)) class LineAgent(IAgent) : length = 2 clearance = 1.99 #less than length def __init__(self, pt, dir) : self.pt1 = pt self.pt2 = pt.dup().add(dir.dup().len(LineAgent.length)) self.isColliding = False def interact(self, agents) : if self.time() == 0 : #only in the first time for agent in agents : if isinstance(agent, LineAgent) : if agent is not self : # checking clearance of end point if agent.pt2.dist(self.pt2) < LineAgent.clearance : self.isColliding=True def update(self) : if self.isColliding : self.del() elif self.time() == 0 : #if not colliding IG.squarePipe(self.pt1,self.pt2,.2).clr(IRand.gray()) dir = self.pt2.dif(self.pt1) #rotation axis with random direction axis = IRand.pt(-1,1).len(1) if IRand.pct(50) : #bend LineAgent(self.pt2, dir.dup().rot(axis,IRand.get(PI/3,PI/3*2))) if IRand.pct(50) : #bend the other way LineAgent(self.pt2, dir.dup().rot(axis,-IRand.get(PI/3,PI/3*2))) if IRand.pct(80) : #straight LineAgent(self.pt2, dir.dup())
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.duration(100) LineAgent(IVec(0,0,0), IVec(1,0,0)).clr(0) class LineAgent(IAgent) : length = 2 clearance = 1.99 #less than length def __init__(self, pt, dir) : self.pt1 = pt self.pt2 = pt.dup().add(dir.dup().len(LineAgent.length)) self.isColliding = False def interact(self, agents) : if self.time() == 0 : #only in the first time for agent in agents : if isinstance(agent, LineAgent) : if agent is not self : # checking clearance of end point if agent.pt2.dist(self.pt2) < LineAgent.clearance : self.isColliding=True def update(self) : if self.isColliding : self.del() elif self.time() == 0 : #if not colliding dir = self.pt2.dif(self.pt1) axis = IRand.pt(-1,1).len(1) if IRand.pct(100) : #bend nextDir1 = dir.dup().rot(axis,IRand.get(PI/3,PI/3*2)) #degree 2 curve at midpoint of pt1&pt2, pt2, and midpoint of pt2 and next agent's point ICurve([ self.pt1.mid(self.pt2),self.pt2, \ self.pt2.mid(self.pt2.cp(nextDir1)) ], 2).clr(self.clr()) LineAgent(self.pt2, nextDir1).clr(self.clr()) if IRand.pct(50) : #bend the other way #degree 2 curve at midpoint of pt1&pt2, pt2, and midpoint of pt2 and next agent's point nextDir2 = dir.dup().rot(axis,-IRand.get(PI/3,PI/3*2)) ICurve([ self.pt1.mid(self.pt2),self.pt2, \ self.pt2.mid(self.pt2.cp(nextDir2)) ],2).clr(self.clr()) LineAgent(self.pt2, nextDir2).clr(self.clr())
add_library('igeo') def setup() : size(480, 360, IG.GL) IRand.init(8) IG.duration(120) LineAgent(IVec(0,0,0), IVec(1,0,0)).clr(0) IG.fill() class LineAgent(IAgent) : length = 2 clearance = 1.99 #less than length def __init__(self, pt, dir) : self.pt1 = pt self.pt2 = pt.dup().add(dir.dup().len(LineAgent.length)) self.isColliding = False def interact(self, agents) : if self.time() == 0 : #only in the first time for agent in agents : if isinstance(agent, LineAgent) : if agent is not self : #checking clearance of end point if agent.pt2.dist(self.pt2) < LineAgent.clearance : self.isColliding = True def update(self) : if self.isColliding : self.del() elif self.time() == 0 : #if not colliding dir = self.pt2.dif(self.pt1) axis = IRand.pt(-1,1).len(1) nextDir1 = dir.dup().rot(axis,PI/3) nextDir2 = dir.dup().rot(axis,-PI/3) #degree 2 surface with 3x3 control points cpts = [] cpts.append([]) cpts.append([]) cpts.append([]) cpts[0].append(self.pt1.mid(self.pt2)) cpts[0].append(self.pt1.mid(self.pt2)) cpts[0].append(self.pt1.mid(self.pt2)) cpts[1].append(self.pt2) cpts[1].append(self.pt2) cpts[1].append(self.pt2) cpts[2].append(self.pt2.mid(self.pt2.cp(nextDir1))) cpts[2].append(self.pt2) cpts[2].append(self.pt2.mid(self.pt2.cp(nextDir2))) ISurface(cpts, 2, 2).clr(self.clr()) r = self.clr().getRed() + IRand.getInt(-10, 10) g = self.clr().getGreen() + IRand.getInt(-10, 10) b = self.clr().getBlue() + IRand.getInt(-10, 10) if IRand.pct(80) : #bend LineAgent(self.pt2, nextDir1).clr(r,g,b) if IRand.pct(50) : #bend the other way LineAgent(self.pt2, nextDir2).clr(r,g,b)
add_library('igeo') def setup() : size(480, 360, IG.GL) IRand.init(3) IG.duration(30) LineAgent(IVec(0,0,0), IVec(1,0,0)).clr(0) IG.fill() class LineAgent(IAgent) : length = 2 clearance = 1.99 #less than length def __init__(self, pt, dir) : self.pt1 = pt self.pt2 = pt.dup().add(dir.dup().len(LineAgent.length)) self.isColliding = False def interact(self, agents) : if self.time() == 0 : #only in the first time for agent in agents : if isinstance(agent, LineAgent) : if agent is not self : #checking clearance of end point if agent.pt2.dist(self.pt2) < LineAgent.clearance : self.isColliding = True def update(self) : if self.isColliding : self.del() elif self.time() == 0 : #if not colliding ICurve(self.pt1,self.pt2) # center line dir = self.pt2.dif(self.pt1) #making axis perpendicular to dir axis = IRand.pt(-1,1).cross(dir) # child dir & points nextDir1 = dir.dup().rot(axis,PI/3) nextDir2 = dir.dup().rot(axis,-PI/3) nextPt1 = self.pt2.cp(nextDir1) nextPt2 = self.pt2.cp(nextDir2) #midpoints mid1 = self.pt1.mid(self.pt2) mid2 = self.pt2.mid(nextPt1) mid3 = self.pt2.mid(nextPt2) #mid of midpoints quarter1 = self.pt2.mid(mid1) quarter2 = self.pt2.mid(mid2) quarter3 = self.pt2.mid(mid3) offsetWidth = -0.5 offset1 = dir.cross(axis).len(offsetWidth) offset2 = nextDir1.cross(axis).len(offsetWidth) offset3 = nextDir2.cross(axis).len(offsetWidth) #offset edge points 1 edgePt11 = mid1.cp(offset1) edgePt12 = quarter1.cp(offset1) edgePt13 = quarter2.cp(offset2) edgePt14 = mid2.cp(offset2) #offset edge points 2 offset2.flip() #offset to opposite edgePt21 = mid2.cp(offset2) edgePt22 = quarter2.cp(offset2) edgePt23 = quarter3.cp(offset3) edgePt24 = mid3.cp(offset3) #offset edge points 3 offset1.flip() #offset to opposite offset3.flip() #offset to opposite edgePt31 = mid3.cp(offset3) edgePt32 = quarter3.cp(offset3) edgePt33 = quarter1.cp(offset1) edgePt34 = mid1.cp(offset1) #degree 3 curves ICurve([ edgePt11,edgePt12,edgePt13,edgePt14 ], 3).clr(0) ICurve([ edgePt21,edgePt22,edgePt23,edgePt24 ], 3).clr(0) ICurve([ edgePt31,edgePt32,edgePt33,edgePt34 ], 3).clr(0) if IRand.pct(80) : #bend LineAgent(self.pt2, nextDir1) if IRand.pct(50) : #bend the other way LineAgent(self.pt2, nextDir2)
Then next, a surface on the offset curve is calculated by shifting the control points on both direction of the axis with the depthVec vector.
add_library('igeo') def setup() : size(480, 360, IG.GL) IRand.init(3) IG.duration(30) LineAgent(IVec(0,0,0), IVec(1,0,0)).clr(0) IG.fill() class LineAgent(IAgent) : length = 2 clearance = 1.99 #less than length def __init__(self, pt, dir) : self.pt1 = pt self.pt2 = pt.dup().add(dir.dup().len(LineAgent.length)) self.isColliding = False def interact(self, agents) : if self.time() == 0 : #only in the first time for agent in agents : if isinstance(agent, LineAgent) : if agent is not self : #checking clearance of end point if agent.pt2.dist(self.pt2) < LineAgent.clearance : self.isColliding = True def update(self) : if self.isColliding : self.del() elif self.time() == 0 : #if not colliding ICurve(self.pt1,self.pt2) # center line dir = self.pt2.dif(self.pt1) #making axis perpendicular to dir axis = IRand.pt(-1,1).cross(dir) # child dir & points nextDir1 = dir.dup().rot(axis,PI/3) nextDir2 = dir.dup().rot(axis,-PI/3) nextPt1 = self.pt2.cp(nextDir1) nextPt2 = self.pt2.cp(nextDir2) #midpoints mid1 = self.pt1.mid(self.pt2) mid2 = self.pt2.mid(nextPt1) mid3 = self.pt2.mid(nextPt2) #mid of midpoints quarter1 = self.pt2.mid(mid1) quarter2 = self.pt2.mid(mid2) quarter3 = self.pt2.mid(mid3) offsetWidth = -0.5 offset1 = dir.cross(axis).len(offsetWidth) offset2 = nextDir1.cross(axis).len(offsetWidth) offset3 = nextDir2.cross(axis).len(offsetWidth) #offset edge points 1 edgePt11 = mid1.cp(offset1) edgePt12 = quarter1.cp(offset1) edgePt13 = quarter2.cp(offset2) edgePt14 = mid2.cp(offset2) #offset edge points 2 offset2.flip() #offset to opposite edgePt21 = mid2.cp(offset2) edgePt22 = quarter2.cp(offset2) edgePt23 = quarter3.cp(offset3) edgePt24 = mid3.cp(offset3) #offset edge points 3 offset1.flip() #offset to opposite offset3.flip() #offset to opposite edgePt31 = mid3.cp(offset3) edgePt32 = quarter3.cp(offset3) edgePt33 = quarter1.cp(offset1) edgePt34 = mid1.cp(offset1) depth = 0.5 depthVec = axis.dup().len(depth) cpts1 = [] cpts1.append([]) cpts1.append([]) cpts1.append([]) cpts1.append([]) cpts1[0].append(edgePt11.dup().add(depthVec)) cpts1[0].append(edgePt11.dup().sub(depthVec)) cpts1[1].append(edgePt12.dup().add(depthVec)) cpts1[1].append(edgePt12.dup().sub(depthVec)) cpts1[2].append(edgePt13.dup().add(depthVec)) cpts1[2].append(edgePt13.dup().sub(depthVec)) cpts1[3].append(edgePt14.dup().add(depthVec)) cpts1[3].append(edgePt14.dup().sub(depthVec)) cpts2 = [] cpts2.append([]) cpts2.append([]) cpts2.append([]) cpts2.append([]) cpts2[0].append(edgePt21.dup().add(depthVec)) cpts2[0].append(edgePt21.dup().sub(depthVec)) cpts2[1].append(edgePt22.dup().add(depthVec)) cpts2[1].append(edgePt22.dup().sub(depthVec)) cpts2[2].append(edgePt23.dup().add(depthVec)) cpts2[2].append(edgePt23.dup().sub(depthVec)) cpts2[3].append(edgePt24.dup().add(depthVec)) cpts2[3].append(edgePt24.dup().sub(depthVec)) cpts3 = [] cpts3.append([]) cpts3.append([]) cpts3.append([]) cpts3.append([]) cpts3[0].append(edgePt31.dup().add(depthVec)) cpts3[0].append(edgePt31.dup().sub(depthVec)) cpts3[1].append(edgePt32.dup().add(depthVec)) cpts3[1].append(edgePt32.dup().sub(depthVec)) cpts3[2].append(edgePt33.dup().add(depthVec)) cpts3[2].append(edgePt33.dup().sub(depthVec)) cpts3[3].append(edgePt34.dup().add(depthVec)) cpts3[3].append(edgePt34.dup().sub(depthVec)) ISurface(cpts1, 3, 1) ISurface(cpts2, 3, 1) ISurface(cpts3, 3, 1) if IRand.pct(80) : #bend LineAgent(self.pt2, nextDir1) if IRand.pct(50) : #bend the other way LineAgent(self.pt2, nextDir2)
In this example, the surface edges between an agent and the next child are not matching. A technique to make it connected and tangent is shown in the next example.
add_library('igeo') def setup() : size(480, 360, IG.GL) IRand.init(3) IG.duration(30) #second and third vector needs to be perpendicular LineAgent(IVec(0,0,0),IVec(1,0,0),IVec(0,0,1)).clr(0) IG.fill() class LineAgent(IAgent) : length = 2 clearance = 1.99 #less than length def __init__(self, pt, dir, ax) : self.pt1 = pt self.pt2 = pt.dup().add(dir.dup().len(LineAgent.length)) self.axis = ax self.isColliding = False def interact(self, agents) : if self.time() == 0 : #only in the first time for agent in agents : if isinstance(agent, LineAgent) : if agent is not self : #checking clearance of end point if agent.pt2.dist(self.pt2) < LineAgent.clearance : self.isColliding = True def update(self) : if self.isColliding : self.del() elif self.time() == 0 : #if not colliding ICurve(self.pt1,self.pt2) # center line dir = self.pt2.dif(self.pt1) # child dir & points nextDir1 = dir.dup().rot(self.axis, IRand.get(PI/4,PI/3)) nextDir2 = dir.dup().rot(self.axis,-IRand.get(PI/4,PI/3)) nextPt1 = self.pt2.cp(nextDir1) nextPt2 = self.pt2.cp(nextDir2) #midpoints mid1 = self.pt1.mid(self.pt2) mid2 = self.pt2.mid(nextPt1) mid3 = self.pt2.mid(nextPt2) #mid of midpoints quarter1 = self.pt2.mid(mid1) quarter2 = self.pt2.mid(mid2) quarter3 = self.pt2.mid(mid3) #axis of child agents nextAxis1 = self.axis.dup().rot(nextDir1, IRand.get(-PI/3,PI/3)) nextAxis2 = self.axis.dup().rot(nextDir2, IRand.get(-PI/3,PI/3)) offsetWidth = -0.5 offset1 = dir.cross(self.axis).len(offsetWidth) offset2 = nextDir1.cross(nextAxis1).len(offsetWidth) offset3 = nextDir2.cross(nextAxis2).len(offsetWidth) #offset edge points 1 edgePt11 = mid1.cp(offset1) edgePt12 = quarter1.cp(offset1) edgePt13 = quarter2.cp(offset2) edgePt14 = mid2.cp(offset2) #offset edge points 2 offset2.flip() #offset to opposite edgePt21 = mid2.cp(offset2) edgePt22 = quarter2.cp(offset2) edgePt23 = quarter3.cp(offset3) edgePt24 = mid3.cp(offset3) #offset edge points 3 offset1.flip() #offset to opposite offset3.flip() #offset to opposite edgePt31 = mid3.cp(offset3) edgePt32 = quarter3.cp(offset3) edgePt33 = quarter1.cp(offset1) edgePt34 = mid1.cp(offset1) #degree 3 curves ICurve([ edgePt11,edgePt12,edgePt13,edgePt14 ], 3).clr(0) ICurve([ edgePt21,edgePt22,edgePt23,edgePt24 ], 3).clr(0) ICurve([ edgePt31,edgePt32,edgePt33,edgePt34 ], 3).clr(0) if IRand.pct(80) : #bend LineAgent(self.pt2, nextDir1, nextAxis1) if IRand.pct(50) : #bend the other way LineAgent(self.pt2, nextDir2, nextAxis2)
The surfaces are created on the offset curves. The code to create a surface out of 4 control points and two different ex is separated in a method of createEdgeSurface.
add_library('igeo') def setup() : size(480, 360, IG.GL) IRand.init(3) IG.duration(30) #second and third vector needs to be perpendicular LineAgent(IVec(0,0,0),IVec(1,0,0),IVec(0,0,1)).clr(0) IG.fill() class LineAgent(IAgent) : length = 2 clearance = 1.99 #less than length def __init__(self, pt, dir, ax) : self.pt1 = pt self.pt2 = pt.dup().add(dir.dup().len(LineAgent.length)) self.axis = ax self.isColliding = False def interact(self, agents) : if self.time() == 0 : #only in the first time for agent in agents : if isinstance(agent, LineAgent) : if agent is not self : #checking clearance of end point if agent.pt2.dist(self.pt2) < LineAgent.clearance : self.isColliding = True def update(self) : if self.isColliding : self.del() elif self.time() == 0 : #if not colliding ICurve(self.pt1,self.pt2) # center line dir = self.pt2.dif(self.pt1) # child dir & points nextDir1 = dir.dup().rot(self.axis, IRand.get(PI/4,PI/3)) nextDir2 = dir.dup().rot(self.axis,-IRand.get(PI/4,PI/3)) nextPt1 = self.pt2.cp(nextDir1) nextPt2 = self.pt2.cp(nextDir2) #midpoints mid1 = self.pt1.mid(self.pt2) mid2 = self.pt2.mid(nextPt1) mid3 = self.pt2.mid(nextPt2) #mid of midpoints quarter1 = self.pt2.mid(mid1) quarter2 = self.pt2.mid(mid2) quarter3 = self.pt2.mid(mid3) #axis of child agents nextAxis1 = self.axis.dup().rot(nextDir1, IRand.get(-PI/4,PI/4)) nextAxis2 = self.axis.dup().rot(nextDir2, IRand.get(-PI/4,PI/4)) offsetWidth = -0.5 offset1 = dir.cross(self.axis).len(offsetWidth) offset2 = nextDir1.cross(nextAxis1).len(offsetWidth) offset3 = nextDir2.cross(nextAxis2).len(offsetWidth) #offset edge points 1 edgePt11 = mid1.cp(offset1) edgePt12 = quarter1.cp(offset1) edgePt13 = quarter2.cp(offset2) edgePt14 = mid2.cp(offset2) #offset edge points 2 offset2.flip() #offset to opposite edgePt21 = mid2.cp(offset2) edgePt22 = quarter2.cp(offset2) edgePt23 = quarter3.cp(offset3) edgePt24 = mid3.cp(offset3) #offset edge points 3 offset1.flip() #offset to opposite offset3.flip() #offset to opposite edgePt31 = mid3.cp(offset3) edgePt32 = quarter3.cp(offset3) edgePt33 = quarter1.cp(offset1) edgePt34 = mid1.cp(offset1) depth = 0.5 depthVec1 = self.axis.dup().len(depth) depthVec2 = nextAxis1.dup().len(depth) depthVec3 = nextAxis2.dup().len(depth) self.createEdgeSurface(edgePt11,edgePt12,edgePt13,edgePt14,depthVec1,depthVec2) self.createEdgeSurface(edgePt21,edgePt22,edgePt23,edgePt24,depthVec2,depthVec3) self.createEdgeSurface(edgePt31,edgePt32,edgePt33,edgePt34,depthVec3,depthVec1) if IRand.pct(80) : #bend LineAgent(self.pt2, nextDir1, nextAxis1) if IRand.pct(50) : #bend the other way LineAgent(self.pt2, nextDir2, nextAxis2) def createEdgeSurface(self,pt1,pt2,pt3,pt4,extrudeDir1,extrudeDir2) : cpts = [] cpts.append([]) cpts.append([]) cpts.append([]) cpts.append([]) cpts[0].append(pt1.dup().add(extrudeDir1)) cpts[0].append(pt1.dup().sub(extrudeDir1)) cpts[1].append(pt2.dup().add(extrudeDir1)) cpts[1].append(pt2.dup().sub(extrudeDir1)) cpts[2].append(pt3.dup().add(extrudeDir2)) cpts[2].append(pt3.dup().sub(extrudeDir2)) cpts[3].append(pt4.dup().add(extrudeDir2)) cpts[3].append(pt4.dup().sub(extrudeDir2)) return ISurface(cpts, 3, 1)
add_library('igeo') def setup() : size(480, 360, IG.GL) IRand.init(3) IG.duration(30) #second and third vector needs to be perpendicular LineAgent(IVec(0,0,0),IVec(1,0,0),IVec(0,0,1)).clr(0) IG.fill() class LineAgent(IAgent) : length = 2 clearance = 1.99 #less than length def __init__(self, pt, dir, ax) : self.pt1 = pt self.pt2 = pt.dup().add(dir.dup().len(LineAgent.length)) self.axis = ax self.isColliding = False def interact(self, agents) : if self.time() == 0 : #only in the first time for agent in agents : if isinstance(agent, LineAgent) : if agent is not self : #checking clearance of end point if agent.pt2.dist(self.pt2) < LineAgent.clearance : self.isColliding = True def update(self) : if self.isColliding : self.del() elif self.time() == 0 : #if not colliding ICurve(self.pt1,self.pt2) # center line dir = self.pt2.dif(self.pt1) # child dir & points nextDir1 = dir.dup().rot(self.axis, IRand.get(PI/4,PI/3)) nextDir2 = dir.dup().rot(self.axis,-IRand.get(PI/4,PI/3)) nextPt1 = self.pt2.cp(nextDir1) nextPt2 = self.pt2.cp(nextDir2) #midpoints mid1 = self.pt1.mid(self.pt2) mid2 = self.pt2.mid(nextPt1) mid3 = self.pt2.mid(nextPt2) #mid of midpoints quarter1 = self.pt2.mid(mid1) quarter2 = self.pt2.mid(mid2) quarter3 = self.pt2.mid(mid3) #axis of child agents nextAxis1 = self.axis.dup().rot(nextDir1, IRand.get(-PI/4,PI/4)) nextAxis2 = self.axis.dup().rot(nextDir2, IRand.get(-PI/4,PI/4)) offsetWidth = -0.5 offset1 = dir.cross(self.axis).len(offsetWidth) offset2 = nextDir1.cross(nextAxis1).len(offsetWidth) offset3 = nextDir2.cross(nextAxis2).len(offsetWidth) depth = 0.5 depthVec1 = self.axis.dup().len(depth) depthVec2 = nextAxis1.dup().len(depth) depthVec3 = nextAxis2.dup().len(depth) self.createEdgeSurface(mid1,quarter1,quarter2,mid2, \ offset1, offset2, depthVec1, depthVec2) self.createEdgeSurface(mid2,quarter2,quarter3,mid3, \ offset2.dup().flip(), offset3, depthVec2, depthVec3) self.createEdgeSurface(mid3,quarter3,quarter1,mid1, \ offset3.dup().flip(), offset1.dup().flip(), depthVec3, depthVec1) if IRand.percent(80) : #bend LineAgent(self.pt2, nextDir1, nextAxis1) if IRand.percent(50) : #bend the other way LineAgent(self.pt2, nextDir2, nextAxis2) def createEdgeSurface(self,pt1,pt2,pt3,pt4,offsetDir1,\ offsetDir2,extrudeDir1,extrudeDir2) : cpts = [] cpts.append([]) cpts.append([]) cpts.append([]) cpts.append([]) cpts[0].append(pt1.dup().add(extrudeDir1)) cpts[0].append(pt1.dup().add(offsetDir1)) cpts[0].append(pt1.dup().sub(extrudeDir1)) cpts[1].append(pt2.dup().add(extrudeDir1)) cpts[1].append(pt2.dup().add(offsetDir1)) cpts[1].append(pt2.dup().sub(extrudeDir1)) cpts[2].append(pt3.dup().add(extrudeDir2)) cpts[2].append(pt3.dup().add(offsetDir2)) cpts[2].append(pt3.dup().sub(extrudeDir2)) cpts[3].append(pt4.dup().add(extrudeDir2)) cpts[3].append(pt4.dup().add(offsetDir2)) cpts[3].append(pt4.dup().sub(extrudeDir2)) return ISurface(cpts, 3, 1)
add_library('igeo') def setup() : size(480, 360, IG.GL) IRand.init(3) IG.duration(30) #second and third vector needs to be perpendicular LineAgent(IVec(0,0,0),IVec(1,0,0),IVec(0,0,1)).clr(0) IG.fill() class LineAgent(IAgent) : length = 2 clearance = 1.99 #less than length def __init__(self, pt, dir, ax) : self.pt1 = pt self.pt2 = pt.dup().add(dir.dup().len(LineAgent.length)) self.axis = ax self.isColliding = False def interact(self, agents) : if self.time() == 0 : #only in the first time for agent in agents : if isinstance(agent, LineAgent) : if agent is not self : #checking clearance of end point if agent.pt2.dist(self.pt2) < LineAgent.clearance : self.isColliding = True def update(self) : if self.isColliding : self.del() elif self.time() == 0 : #if not colliding ICurve(self.pt1,self.pt2) # center line dir = self.pt2.dif(self.pt1) # child dir & points nextDir1 = dir.dup().rot(self.axis, IRand.get(PI/4,PI/3)) nextDir2 = dir.dup().rot(self.axis,-IRand.get(PI/4,PI/3)) nextPt1 = self.pt2.cp(nextDir1) nextPt2 = self.pt2.cp(nextDir2) #midpoints mid1 = self.pt1.mid(self.pt2) mid2 = self.pt2.mid(nextPt1) mid3 = self.pt2.mid(nextPt2) #mid of midpoints quarter1 = self.pt2.mid(mid1) quarter2 = self.pt2.mid(mid2) quarter3 = self.pt2.mid(mid3) #axis of child agents nextAxis1 = self.axis.dup().rot(nextDir1, IRand.get(-PI/4,PI/4)) nextAxis2 = self.axis.dup().rot(nextDir2, IRand.get(-PI/4,PI/4)) offsetWidth = -0.5 offset1 = dir.cross(self.axis).len(offsetWidth) offset2 = nextDir1.cross(nextAxis1).len(offsetWidth) offset3 = nextDir2.cross(nextAxis2).len(offsetWidth) depth = 0.5 depthVec1 = self.axis.dup().len(depth) depthVec2 = nextAxis1.dup().len(depth) depthVec3 = nextAxis2.dup().len(depth) self.createEdgeSurface(mid1,quarter1,quarter2,mid2, \ offset1,offset2,depthVec1,depthVec2) self.createEdgeSurface(mid2,quarter2,quarter3,mid3, \ offset2.dup().flip(),offset3,depthVec2,depthVec3) self.createEdgeSurface(mid3,quarter3,quarter1,mid1, \ offset3.dup().flip(),offset1.dup().flip(),depthVec3,depthVec1) self.createCapSurface(mid1,quarter1,mid2,quarter2,mid3,quarter3, \ depthVec1,depthVec2,depthVec3) self.createCapSurface(mid1,quarter1,mid3,quarter3,mid2,quarter2, \ depthVec1.flip(),depthVec3.flip(),depthVec2.flip()) if IRand.pct(80) : #bend LineAgent(self.pt2, nextDir1, nextAxis1) if IRand.pct(50) : #bend the other way LineAgent(self.pt2, nextDir2, nextAxis2) def createEdgeSurface(self,pt1,pt2,pt3,pt4,offsetDir1,\ offsetDir2,extrudeDir1,extrudeDir2) : cpts = [] cpts.append([]) cpts.append([]) cpts.append([]) cpts.append([]) cpts[0].append(pt1.dup().add(extrudeDir1)) cpts[0].append(pt1.dup().add(offsetDir1).add(extrudeDir1)) cpts[0].append(pt1.dup().add(offsetDir1).sub(extrudeDir1)) cpts[0].append(pt1.dup().sub(extrudeDir1)) cpts[1].append(pt2.dup().add(extrudeDir1)) cpts[1].append(pt2.dup().add(offsetDir1).add(extrudeDir1)) cpts[1].append(pt2.dup().add(offsetDir1).sub(extrudeDir1)) cpts[1].append(pt2.dup().sub(extrudeDir1)) cpts[2].append(pt3.dup().add(extrudeDir2)) cpts[2].append(pt3.dup().add(offsetDir2).add(extrudeDir2)) cpts[2].append(pt3.dup().add(offsetDir2).sub(extrudeDir2)) cpts[2].append(pt3.dup().sub(extrudeDir2)) cpts[3].append(pt4.dup().add(extrudeDir2)) cpts[3].append(pt4.dup().add(offsetDir2).add(extrudeDir2)) cpts[3].append(pt4.dup().add(offsetDir2).sub(extrudeDir2)) cpts[3].append(pt4.dup().sub(extrudeDir2)) return ISurface(cpts, 3, 1) def createCapSurface(self,pt1,pt2,pt3,pt4,pt5,pt6,\ shiftDir1,shiftDir2,shiftDir3) : cpts = [] cpts.append([]) cpts.append([]) cpts.append([]) cpts.append([]) cpts[0].append(pt1.dup().add(shiftDir1)) cpts[0].append(pt2.dup().add(shiftDir1)) cpts[0].append(pt4.dup().add(shiftDir2)) cpts[0].append(pt3.dup().add(shiftDir2)) cpts[1].append(pt1.dup().add(shiftDir1)) cpts[1].append(pt2.dup().add(shiftDir1)) cpts[1].append(pt4.mid(pt6).add(shiftDir2.mid(shiftDir3))) cpts[1].append(pt4.dup().add(shiftDir2)) cpts[2].append(pt1.dup().add(shiftDir1)) cpts[2].append(pt2.dup().add(shiftDir1)) cpts[2].append(pt4.mid(pt6).add(shiftDir2.mid(shiftDir3))) cpts[2].append(pt6.dup().add(shiftDir3)) cpts[3].append(pt1.dup().add(shiftDir1)) cpts[3].append(pt2.dup().add(shiftDir1)) cpts[3].append(pt6.dup().add(shiftDir3)) cpts[3].append(pt5.dup().add(shiftDir3)) return ISurface(cpts, 3, 3)
The code below creates surfaces with curved section having v-degree 3 NURBS surfaces.
add_library('igeo') def setup() : size(480, 360, IG.GL) IRand.init(3) IG.duration(30) #second and third vector needs to be perpendicular LineAgent(IVec(0,0,0),IVec(1,0,0),IVec(0,0,1)).clr(0) IG.fill() class LineAgent(IAgent) : length = 2 clearance = 1.99 #less than length def __init__(self, pt, dir, ax) : self.pt1 = pt self.pt2 = pt.dup().add(dir.dup().len(LineAgent.length)) self.axis = ax self.isColliding = False def interact(self, agents) : if self.time() == 0 : #only in the first time for agent in agents : if isinstance(agent, LineAgent) : if agent is not self : #checking clearance of end point if agent.pt2.dist(self.pt2) < LineAgent.clearance : self.isColliding = True def update(self) : if self.isColliding : self.del() elif self.time() == 0 : #if not colliding ICurve(self.pt1,self.pt2) # center line dir = self.pt2.dif(self.pt1) # child dir & points nextDir1 = dir.dup().rot(self.axis, IRand.get(PI/4,PI/3)) nextDir2 = dir.dup().rot(self.axis,-IRand.get(PI/4,PI/3)) nextPt1 = self.pt2.cp(nextDir1) nextPt2 = self.pt2.cp(nextDir2) #midpoints mid1 = self.pt1.mid(self.pt2) mid2 = self.pt2.mid(nextPt1) mid3 = self.pt2.mid(nextPt2) #mid of midpoints quarter1 = self.pt2.mid(mid1) quarter2 = self.pt2.mid(mid2) quarter3 = self.pt2.mid(mid3) #axis of child agents nextAxis1 = self.axis.dup().rot(nextDir1, IRand.get(-PI/4,PI/4)) nextAxis2 = self.axis.dup().rot(nextDir2, IRand.get(-PI/4,PI/4)) offsetWidth = -0.75 offset1 = dir.cross(self.axis).len(offsetWidth) offset2 = nextDir1.cross(nextAxis1).len(offsetWidth) offset3 = nextDir2.cross(nextAxis2).len(offsetWidth) depth = 0.75 depthVec1 = self.axis.dup().len(depth) depthVec2 = nextAxis1.dup().len(depth) depthVec3 = nextAxis2.dup().len(depth) self.createEdgeSurface(mid1,quarter1,quarter2,mid2,\ offset1, offset2,depthVec1, depthVec2) self.createEdgeSurface(mid2,quarter2,quarter3,mid3,\ offset2.dup().flip(),offset3,depthVec2,depthVec3) self.createEdgeSurface(mid3,quarter3,quarter1,mid1,\ offset3.dup().flip(),offset1.dup().flip(),depthVec3,depthVec1) self.createCapSurface(mid1,quarter1,mid2,quarter2,mid3,quarter3,\ depthVec1,depthVec2,depthVec3) self.createCapSurface(mid1,quarter1,mid3,quarter3,mid2,quarter2,\ depthVec1.flip(),depthVec3.flip(),depthVec2.flip()) if IRand.pct(80) : #bend LineAgent(self.pt2, nextDir1, nextAxis1) if IRand.pct(50) : #bend the other way LineAgent(self.pt2, nextDir2, nextAxis2) def createEdgeSurface(self,pt1,pt2,pt3,pt4,offsetDir1, offsetDir2,extrudeDir1, extrudeDir2) : cpts = [] cpts.append([]) cpts.append([]) cpts.append([]) cpts.append([]) cpts[0].append(pt1.dup().add(extrudeDir1)) cpts[0].append(pt1.dup().add(offsetDir1).add(extrudeDir1)) cpts[0].append(pt1.dup().add(offsetDir1).sub(extrudeDir1)) cpts[0].append(pt1.dup().sub(extrudeDir1)) cpts[1].append(pt2.dup().add(extrudeDir1)) cpts[1].append(pt2.dup().add(offsetDir1).add(extrudeDir1)) cpts[1].append(pt2.dup().add(offsetDir1).sub(extrudeDir1)) cpts[1].append(pt2.dup().sub(extrudeDir1)) cpts[2].append(pt3.dup().add(extrudeDir2)) cpts[2].append(pt3.dup().add(offsetDir2).add(extrudeDir2)) cpts[2].append(pt3.dup().add(offsetDir2).sub(extrudeDir2)) cpts[2].append(pt3.dup().sub(extrudeDir2)) cpts[3].append(pt4.dup().add(extrudeDir2)) cpts[3].append(pt4.dup().add(offsetDir2).add(extrudeDir2)) cpts[3].append(pt4.dup().add(offsetDir2).sub(extrudeDir2)) cpts[3].append(pt4.dup().sub(extrudeDir2)) return ISurface(cpts, 3, 3) def createCapSurface(self,pt1,pt2,pt3,pt4,pt5,pt6,\ shiftDir1,shiftDir2,shiftDir3) : cpts = [] cpts.append([]) cpts.append([]) cpts.append([]) cpts.append([]) cpts[0].append(pt1.dup().add(shiftDir1)) cpts[0].append(pt2.dup().add(shiftDir1)) cpts[0].append(pt4.dup().add(shiftDir2)) cpts[0].append(pt3.dup().add(shiftDir2)) cpts[1].append(pt1.dup().add(shiftDir1)) cpts[1].append(pt2.dup().add(shiftDir1)) cpts[1].append(pt4.mid(pt6).add(shiftDir2.mid(shiftDir3))) cpts[1].append(pt4.dup().add(shiftDir2)) cpts[2].append(pt1.dup().add(shiftDir1)) cpts[2].append(pt2.dup().add(shiftDir1)) cpts[2].append(pt4.mid(pt6).add(shiftDir2.mid(shiftDir3))) cpts[2].append(pt6.dup().add(shiftDir3)) cpts[3].append(pt1.dup().add(shiftDir1)) cpts[3].append(pt2.dup().add(shiftDir1)) cpts[3].append(pt6.dup().add(shiftDir3)) cpts[3].append(pt5.dup().add(shiftDir3)) return ISurface(cpts, 3, 3)
add_library('igeo') def setup() : size(480, 360, IG.GL) IRand.init(4) IG.duration(30) #second and third vector needs to be perpendicular LineAgent(IVec(0,0,0),IVec(1,0,0),IVec(0,0,1),True,True).clr(0.4,0,0) IG.fill() class LineAgent(IAgent) : length = 2 clearance = 1.99 #less than length def __init__(self, pt, dir, ax, createLeft, createRight) : self.pt1 = pt self.pt2 = pt.dup().add(dir.dup().len(LineAgent.length)) self.axis = ax self.isColliding = False self.createLeftSrf = createLeft self.createRightSrf = createRight def interact(self, agents) : if self.time() == 0 : #only in the first time for agent in agents : if isinstance(agent, LineAgent) : if agent is not self : #checking clearance of end point if agent.pt2.dist(self.pt2) < LineAgent.clearance : self.isColliding = True def update(self) : if self.isColliding : self.del() elif self.time() == 0 : #if not colliding ICurve(self.pt1,self.pt2) # center line dir = self.pt2.dif(self.pt1) # child dir & points nextDir1 = dir.dup().rot(self.axis, IRand.get(PI/4,PI/3)) nextDir2 = dir.dup().rot(self.axis,-IRand.get(PI/4,PI/3)) nextPt1 = self.pt2.cp(nextDir1) nextPt2 = self.pt2.cp(nextDir2) #midpoints mid1 = self.pt1.mid(self.pt2) mid2 = self.pt2.mid(nextPt1) mid3 = self.pt2.mid(nextPt2) #mid of midpoints quarter1 = self.pt2.mid(mid1) quarter2 = self.pt2.mid(mid2) quarter3 = self.pt2.mid(mid3) #axis of child agents nextAxis1 = self.axis.dup().rot(nextDir1, IRand.get(-PI/4,PI/4)) nextAxis2 = self.axis.dup().rot(nextDir2, IRand.get(-PI/4,PI/4)) offsetWidth = -1.0 offset1 = dir.cross(self.axis).len(offsetWidth) offset2 = nextDir1.cross(nextAxis1).len(offsetWidth) offset3 = nextDir2.cross(nextAxis2).len(offsetWidth) depth = 1.0 depthVec1 = self.axis.dup().len(depth) depthVec2 = nextAxis1.dup().len(depth) depthVec3 = nextAxis2.dup().len(depth) if self.createLeftSrf : self.createEdgeSurface(mid1,quarter1,quarter2,mid2,\ offset1,offset2,depthVec1,depthVec2).clr(self.clr()) if not self.createLeftSrf or not self.createRightSrf : self.createEdgeSurface(mid2,quarter2,quarter3,mid3,\ offset2.dup().flip(),offset3,depthVec2, depthVec3).clr(self.clr()) if self.createRightSrf : self.createEdgeSurface(mid3,quarter3,quarter1,mid1,\ offset3.dup().flip(), offset1.dup().flip(),depthVec3, depthVec1).clr(self.clr()) self.createCapSurface(mid1,quarter1,mid2,quarter2,mid3,quarter3,\ depthVec1,depthVec2,depthVec3).clr(self.clr()) self.createCapSurface(mid1,quarter1,mid3,quarter3,mid2,quarter2,\ depthVec1.flip(),depthVec3.flip(),depthVec2.flip()).clr(self.clr()) #child agents color r = self.clr().getRed() + IRand.getInt(-10,10) g = self.clr().getGreen() b = self.clr().getBlue() + IRand.getInt(-10,10) if IRand.pct(80) : #bend LineAgent(self.pt2, nextDir1, nextAxis1, self.createLeftSrf, not self.createLeftSrf or not self.createRightSrf).clr(r,g,b) if IRand.pct(50) : #bend the other way LineAgent(self.pt2, nextDir2, nextAxis2, not self.createLeftSrf or not self.createRightSrf, self.createRightSrf).clr(r,g,b) def createEdgeSurface(self,pt1,pt2,pt3,pt4,\ offsetDir1,offsetDir2,extrudeDir1,extrudeDir2) : cpts = [] cpts.append([]) cpts.append([]) cpts.append([]) cpts.append([]) cpts[0].append(pt1.dup().add(extrudeDir1)) cpts[0].append(pt1.dup().add(offsetDir1).add(extrudeDir1)) cpts[0].append(pt1.dup().add(offsetDir1).sub(extrudeDir1)) cpts[0].append(pt1.dup().sub(extrudeDir1)) cpts[1].append(pt2.dup().add(extrudeDir1)) cpts[1].append(pt2.dup().add(offsetDir1).add(extrudeDir1)) cpts[1].append(pt2.dup().add(offsetDir1).sub(extrudeDir1)) cpts[1].append(pt2.dup().sub(extrudeDir1)) cpts[2].append(pt3.dup().add(extrudeDir2)) cpts[2].append(pt3.dup().add(offsetDir2).add(extrudeDir2)) cpts[2].append(pt3.dup().add(offsetDir2).sub(extrudeDir2)) cpts[2].append(pt3.dup().sub(extrudeDir2)) cpts[3].append(pt4.dup().add(extrudeDir2)) cpts[3].append(pt4.dup().add(offsetDir2).add(extrudeDir2)) cpts[3].append(pt4.dup().add(offsetDir2).sub(extrudeDir2)) cpts[3].append(pt4.dup().sub(extrudeDir2)) return ISurface(cpts, 3, 3) def createCapSurface(self,pt1,pt2,pt3,pt4,pt5,pt6,\ shiftDir1,shiftDir2,shiftDir3) : cpts = [] cpts.append([]) cpts.append([]) cpts.append([]) cpts.append([]) cpts[0].append(pt1.dup().add(shiftDir1)) cpts[0].append(pt2.dup().add(shiftDir1)) cpts[0].append(pt4.dup().add(shiftDir2)) cpts[0].append(pt3.dup().add(shiftDir2)) cpts[1].append(pt1.dup().add(shiftDir1)) cpts[1].append(pt2.dup().add(shiftDir1)) cpts[1].append(pt4.mid(pt6).add(shiftDir2.mid(shiftDir3))) cpts[1].append(pt4.dup().add(shiftDir2)) cpts[2].append(pt1.dup().add(shiftDir1)) cpts[2].append(pt2.dup().add(shiftDir1)) cpts[2].append(pt4.mid(pt6).add(shiftDir2.mid(shiftDir3))) cpts[2].append(pt6.dup().add(shiftDir3)) cpts[3].append(pt1.dup().add(shiftDir1)) cpts[3].append(pt2.dup().add(shiftDir1)) cpts[3].append(pt6.dup().add(shiftDir3)) cpts[3].append(pt5.dup().add(shiftDir3)) return ISurface(cpts, 3, 3)