Swarm Python Component
Swarm in Grasshopper using GH_Python component. Testing swarm behaviour in Rhino is in this post: Rhino.Python Swarm Bridge
For more discussion please visit my post in grasshopper example forum.
GH_Python Code:
### --Written by Gene Ting-Chun Kao-- ###
ghenv.Component.Message = "written by +GENEATCG"
import rhinoscriptsyntax as rs
import Rhino as rc
from random import *
rectX = 600
rectY = 600
class Runner:
def __init__(self, p, v):
self.p = p
self.v = v
self.a = rs.VectorCreate( (0,0,0),(0,0,0) )
def ptRun(self):
self.v = rs.VectorAdd(self.v, self.a)
v = rs.VectorLength(self.v)
if v > 2:
self.v = rs.VectorScale(rs.VectorUnitize(self.v), 2)
self.p = rs.VectorAdd(self.p, self.v)
self.a = rs.VectorCreate( (0,0,0),(0,0,0) )
def reflect(self):
if self.p[0] >= rectX or self.p[0] < 0:
self.v[0] *= -1.2
if self.p[1] >= rectY or self.p[1] < 0:
self.v[1] *= -1.2
def door(self):
if self.p[0] >= rectX:
self.p[0] -= rectX
if self.p[0] <= 0:
self.p[0] += rectX
if self.p[1] >= rectY:
self.p[1] -= rectY
if self.p[1] <= 0:
self.p[1] += rectY
def flock(self):
self.separate(ms)
self.cohesion(mc)
self.align(ma)
def align(self, mag):
steer = rs.VectorCreate( (0,0,0) , (0,0,0) )
count = 0
for i in pts:
distance = rs.Distance(i.p, self.p)
if distance > 0 and distance < 40:
steer = rs.VectorAdd(steer, i.v)
count += 1
if count>0:
steer = rs.VectorScale(steer, 1.0/count)
steer = rs.VectorScale(steer, mag)
self.a = rs.VectorAdd(self.a, steer)
def cohesion(self, mag):
sum = rs.VectorCreate( (0,0,0) , (0,0,0) )
count = 0
for i in pts:
distance = rs.Distance(i.p, self.p)
if distance > 0 and distance < 60:
sum = rs.VectorAdd(sum, i.p)
count += 1
if count>0:
sum = rs.VectorScale(sum, 1.0/count)
steer = rs.VectorSubtract(sum, self.p)
steer = rs.VectorScale(steer, mag)
self.a = rs.VectorAdd(self.a, steer)
#print(self.a)
def separate(self, mag):
steer = rs.VectorCreate( (0,0,0) , (0,0,0) )
count = 0
for i in pts:
distance = rs.Distance(i.p, self.p)
if distance > 0 and distance < 30:
diff = rs.VectorSubtract(self.p, i.p)
diff = rs.VectorUnitize(diff)
diff = rs.VectorScale(diff, 1.0/distance)
steer = rs.VectorAdd(steer , diff)
count += 1
if count>0:
steer = rs.VectorScale(steer, 1.0/count)
steer = rs.VectorScale(steer, mag)
self.a = rs.VectorAdd(self.a, steer)
#print(self.a)
def drawPt(self):
pt = rc.Geometry.Point3d(self.p[0], self.p[1], self.p[2])
return pt
if reset:
pts = []
for i in range(20):
p = rs.VectorCreate( rs.AddPoint( randint(1,rectX-1), randint(1,rectY-1),0 ) , rs.AddPoint(0,0,0) )
v = rs.VectorCreate( rs.AddPoint( randint(1,3) , randint(1,3),0 ) , rs.AddPoint(0,0,0) )
run1 = Runner(p, v)
pts.append(run1)
else:
pos = []
vec = []
if not stop:
for i in pts:
pos.append(i.drawPt())
vec.append(i.v)
for i in pts:
if bound:
i.reflect()
else:
i.door()
#i.separate(magnitude)
i.flock()
i.ptRun()
else:
for i in pts:
pos.append(i.drawPt())
vec.append(i.v)
plane = rs.WorldXYPlane()
rect = rs.AddRectangle(plane, rectX, rectY)