Python Tutorials | (back to the list of tutorials) |
The first code below has the swarm agent class MyBoid inheriting IBoid class. This adds a behavior to stay in the range from 0.0 to 1.0 in X and Y. In the update() method the position of the agent is checked and if it's out of the range, it adds or subtracts 1.0 to X or Y to jump to the other end of the range. To avoid drawing a line from one end to the other end, boolean variable jump is defined to check if it's jumping and if so it doesn't create a line. In setup() method, IG.top() method turns iGeo to show only top view instead of 4 views and IG.focus() method adjusts the view to zoom into the existing geometries.
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.duration(800) for i in range(200) : MyBoid(IRand.pt(1,1,0),IRand.pt(-0.01,-0.01,0,0.01,0.01,0)) IG.top() #only showing the top view IG.focus() #focusing into existing geometries class MyBoid(IBoid) : def __init__(self, pos, vel) : IBoid.__init__(self,pos,vel) self.prevPos = None self.cohesionDist(0.03) self.cohesionRatio(1) self.separationDist(0.04) self.separationRatio(2) self.alignmentDist(0.03) self.alignmentRatio(0) def update(self) : jump=False if self.pos().x() < 0.0 : self.pos().add(1, 0, 0) jump=True elif self.pos().x() > 1.0 : self.pos().sub(1, 0, 0) jump=True if self.pos().y() < 0.0 : self.pos().add(0, 1, 0) jump=True elif self.pos().y() > 1.0 : self.pos().sub(0, 1, 0) jump=True curPos = self.pos().cp() if self.prevPos is not None and not jump : ICurve(self.prevPos, curPos).clr(0) self.prevPos = curPos
This second code keeps movements of the swarm agents same but
drawing lines in different locations.
Whereas the previous code draws lines on the trace of the movement,
this code draws lines between two agents when two agents
are closer than a certain distance.
These two lines calculates a distance between two agents and
limit the condition when the distance is smaller than 0.08
(note that the whole range is from 0.0 to 1.0).
       
double dist = pos().dist( b.pos() );
           
if ( dist < 0.08 ) {
Another if-condition of
if ( IG.time()%15==0 ) {
is added to control the density of lines.
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.duration(800) for i in range(200) : MyBoid(IRand.pt(1,1,0),IRand.pt(-0.01,-0.01,0,0.01,0.01,0)) IG.top() #only showing the top view IG.focus() #focusing into existing geometries class MyBoid(IBoid) : def __init__(self, pos, vel) : IBoid.__init__(self,pos,vel) self.cohesionDist(0.03) self.cohesionRatio(1) self.separationDist(0.04) self.separationRatio(2) self.alignmentDist(0.03) self.alignmentRatio(0) def interact(self, agents) : for agent in agents : if agent is self : return if isinstance(agent, MyBoid) : dist = self.pos().dist(agent.pos()) if dist < 0.08 : if IG.time()%15==0 : ICurve(self.pos().cp(),agent.pos().cp()).clr(0) def update(self) : if self.pos().x() < 0.0 : self.pos().add(1, 0, 0) elif self.pos().x() > 1.0 : self.pos().sub(1, 0, 0) if self.pos().y() < 0.0 : self.pos().add(0, 1, 0) elif self.pos().y() > 1.0 : self.pos().sub(0, 1, 0)
The next code only changes the color of line drawing.
The background color is changed by the method IG.bg(0)
to black.
When you put one number into this method ( IG.bg(double) )
it's gray scale color and when you put three numbers
(IG.bg(double,double,double) ) it's RGB color.
The color of the lines is changed to transparent white color at this line
by setting the alpha value of the color to 0.2.
       
new ICurve(pos().cp(), b.pos().cp()).clr(1.0,0.2); //transparent white
The points of agents are also hidden by the agent's method hide().
       
if ( time()==0 ) { hide(); } //hiding a point of boid
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.duration(800) for i in range(200) : MyBoid(IRand.pt(1,1,0),IRand.pt(-0.01,-0.01,0,0.01,0.01,0)) IG.bg(0) #black background IG.top() #only showing the top view IG.focus() #focusing into existing geometries class MyBoid(IBoid) : def __init__(self, pos, vel) : IBoid.__init__(self,pos,vel) self.cohesionDist(0.03) self.cohesionRatio(1) self.separationDist(0.04) self.separationRatio(2) self.alignmentDist(0.03) self.alignmentRatio(0) def interact(self, agents) : for agent in agents : if agent is self : return if isinstance(agent, MyBoid) : dist = self.pos().dist(agent.pos()) if dist < 0.08 : if IG.time()%15==0 : ICurve(self.pos().cp(),agent.pos().cp()).clr(1.0,0.2) #transparent white def update(self) : if self.pos().x() < 0.0 : self.pos().add(1, 0, 0) elif self.pos().x() > 1.0 : self.pos().sub(1, 0, 0) if self.pos().y() < 0.0 : self.pos().add(0, 1, 0) elif self.pos().y() > 1.0 : self.pos().sub(0, 1, 0)
The code below maps the swarm agents onto a surface.
It reads an input Rhino file and
takes one surface out to put it into an agent of MyBoidOnSurface class.
MyBoidOnSurface class contains two data fields.
       
ISurface surface;
       
IVec surfPt;
With those fields, the agent keeps the information of a surface to map onto
and mapped vector location on the surface.
The original position information on the agent pos()
is used as U-V coordinates.
Although the original position is interpreted as U-V coordinates,
the actual point of the agent still exists in X-Y-Z coordinates.
To hide this point, the method hide() is called inside the
constructor. If you don't hide the point, it floats somewhere on X-Y plane
within (0.0, 0.0) - (1.0, 1.0).
This agent's original position pos() is then mapped onto the position
on the surface by this line inside the constructor and also inside
update() method to keep the field surfPt updated.
       
surfPt = surface.pt(pos);
Then this surfPt is used to
measure the distance and to
create a line in 3D X-Y-Z coordinates.
The input Rhino file used in the example is this one below.
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.duration(800) IG.open("surface13.3dm") surf = IG.surface(0) for i in range(300) : MyBoidOnSurface(surf,IRand.pt(1,1,0),IRand.pt(-0.01,-0.01,0,0.01,0.01,0)) surf.del() class MyBoidOnSurface(IBoid) : def __init__(self, srf, pos, vel) : IBoid.__init__(self,pos,vel) self.surface = srf self.surfPt = srf.pt(pos) self.hide() #hiding a point of boid self.cohesionDist(0.03) self.cohesionRatio(1) self.separationDist(0.04) self.separationRatio(2) self.alignmentDist(0.03) self.alignmentRatio(0) def interact(self, agents) : for agent in agents : if agent is self : return if isinstance(agent, MyBoidOnSurface) : dist = self.surfPt.dist(agent.surfPt) if dist < 5.0 : if IG.time()%15==0 : ICurve(self.surfPt.cp(),agent.surfPt.cp()).clr(0) def update(self) : if self.pos().x() < 0.0 : self.pos().add(1, 0, 0) elif self.pos().x() > 1.0 : self.pos().sub(1, 0, 0) if self.pos().y() < 0.0 : self.pos().add(0, 1, 0) elif self.pos().y() > 1.0 : self.pos().sub(0, 1, 0) self.surfPt = self.surface.pt(self.pos()) #update surface point
add_library('igeo') def setup() : size(480, 360, IG.GL) IG.duration(800) IG.open("surface13.3dm") surf = IG.surface(0) for i in range(300) : MyBoidOnSurface(surf,IRand.pt(1,1,0),IRand.pt(-0.01,-0.01,0,0.01,0.01,0)) surf.del() class MyBoidOnSurface(IBoid) : def __init__(self, srf, pos, vel) : IBoid.__init__(self,pos,vel) self.surface = srf self.surfPt = srf.pt(pos) self.hide() #hiding a point of boid self.cohesionDist(0.03) self.cohesionRatio(1) self.separationDist(0.04) self.separationRatio(2) self.alignmentDist(0.03) self.alignmentRatio(0) def interact(self, agents) : for agent in agents : if agent is self : return if isinstance(agent, MyBoidOnSurface) : dist = self.surfPt.dist(agent.surfPt) if dist < 5.0 and dist > 2.0 : if IG.time()%15==0 : #controlling depth depth = sin(IG.time()*0.01)*1.5 pt1 = self.surface.pt(self.pos().x(), self.pos().y(), depth) pt2 = agent.surface.pt(agent.pos().x(), agent.pos().y(), depth) gray = sin(IG.time()*0.01)*0.5+0.5 IG.meshSquareStick(pt1,pt2,0.4).clr(gray) def update(self) : if self.pos().x() < 0.0 : self.pos().add(1, 0, 0) elif self.pos().x() > 1.0 : self.pos().sub(1, 0, 0) if self.pos().y() < 0.0 : self.pos().add(0, 1, 0) elif self.pos().y() > 1.0 : self.pos().sub(0, 1, 0) self.surfPt = self.surface.pt(self.pos()) #update surface point