def cohesion(self, fish): if len(fish) < 1: return # calculate the average distances from the other boids com = Vector() count = 0 for boid in fish: if boid.pos == self.pos: continue elif (boid.pos - self.pos).length() < self.per: com += (self.pos - boid.pos) count += 1 if count > 0: com = com.divide(count) return -com.normalize() else: return Vector()
class Fsh: def __init__(self, pos, bounds, imgr, imgl): self.bounds = bounds self.max_vel = 75 self.imgr = imgr self.imgl = imgl self.size = 25 self.per = self.size * 3 self.pos = pos angle = random.random() * math.pi * 2 self.vel = Vector(math.cos(angle), math.sin(angle)) * 20 def draw(self, canvas): #canvas.draw_circle(self.pos.get_p(),4,1,"red","red") a = self.vel.angle(Vector(0, 1)) if self.vel.x > 0: a *= -1 img = self.imgr a += math.pi / 2 else: a -= math.pi / 2 img = self.imgl img.pos = self.pos img.draw(canvas, rotation=a) #canvas.draw_line(self.pos.get_p(),(self.pos+self.vel).get_p(),2,"blue") #canvas.draw_circle(self.pos.get_p(),self.size,1,"black") def allign(self, fish): if len(fish) < 1: return # calculate the average velocities of the other boids avg = Vector() count = 0 for boid in fish: if (boid.pos - self.pos).length() < self.per: count += 1 avg += boid.vel if count > 0: avg = avg.divide(count) # set our velocity towards the others return (avg).normalize() else: return Vector() def cohesion(self, fish): if len(fish) < 1: return # calculate the average distances from the other boids com = Vector() count = 0 for boid in fish: if boid.pos == self.pos: continue elif (boid.pos - self.pos).length() < self.per: com += (self.pos - boid.pos) count += 1 if count > 0: com = com.divide(count) return -com.normalize() else: return Vector() def seperation(self, fish, minDistance): if len(fish) < 1: return Vector() distance = 0 numClose = 0 distsum = Vector() for boid in fish: distance = (self.pos - boid.pos).length() if distance < minDistance and distance != 0: numClose += 1 distsum += (boid.pos - self.pos).divide(distance**2) if numClose == 0: return Vector() return (-distsum.divide(numClose)).normalize() def update(self, delta, fish): self.vel = self.vel.add(self.allign(fish).multiply(self.max_vel / 50)) self.vel = self.vel.add( self.cohesion(fish).multiply(self.max_vel / 50)) self.vel = self.vel.add( self.seperation(fish, self.per * 3 / 5).multiply(self.max_vel / 30)) self.vel = self.vel.normalize().multiply(self.max_vel) self.vel.rotate((random.random() * 2 - 1) * delta * 20) self.pos = self.pos.add(self.vel * delta) self.pos = self.bounds.correct(self)