def calculate_forces(self): preys = self.world.prey_sets[self] chase_x, chase_y = 0.0, 0.0 for boid in preys: distance = self.world.distances[self, boid] factor = 1 - distance / self.world.neighbourhood_radius dir_x, dir_y = normalize_vector(*self.relative_coordinates(boid.x, boid.y)) chase_x += factor * dir_x chase_y += factor * dir_y return {"chase": normalize_vector(chase_x, chase_y)}
def calculate_forces(self): preys = self.world.prey_sets[self] chase_x, chase_y = 0.0, 0.0 for boid in preys: distance = self.world.distances[self, boid] factor = 1 - distance / self.world.neighbourhood_radius dir_x, dir_y = normalize_vector( *self.relative_coordinates(boid.x, boid.y)) chase_x += factor * dir_x chase_y += factor * dir_y return {'chase': normalize_vector(chase_x, chase_y)}
def calculate_forces(self): """ The force calculations have been joined into a single function for performance reasons. """ forces = {"separation": (0, 0), "alignment": (0, 0), "cohesion": (0, 0), "avoidance": (0, 0), "flight": (0, 0)} self.fleeing = False flight_x, flight_y = 0.0, 0.0 for predator in self.predators: self.fleeing = True distance = self.distance(predator) if distance < PREDATOR_RADIUS: dead = self.die() if dead: return forces factor = 1 - distance / self.world.neighbourhood_radius rel_x, rel_y = self.relative_coordinates(predator.x, predator.y) flight_x -= factor * rel_x flight_y -= factor * rel_y forces["flight"] = (flight_x, flight_y) self.avoiding = False avoidance_x, avoidance_y = 0.0, 0.0 for obstacle in self.world.obstacles: distance = self.shortest_distance(obstacle.x, obstacle.y) if distance < (BOID_RADIUS + self.world.neighbourhood_radius + OBSTACLE_RADIUS): if distance < OBSTACLE_RADIUS: dead = self.die() if dead: return forces normalized_vx, normalized_vy = self.normalized_velocity intersection = False for n in xrange(1, int(distance)): future_x = self.x + n * normalized_vx future_y = self.y + n * normalized_vy d = euclidean_distance((future_x, future_y), obstacle.position) if d < (obstacle.r + BOID_RADIUS): intersection = True break if intersection: self.avoiding = True factor = 1 - (distance - obstacle.r) / self.world.neighbourhood_radius future_x = self.x + distance * normalized_vx future_y = self.y + distance * normalized_vy v1 = self.relative_coordinates(*obstacle.position) v2 = self.relative_coordinates(future_x, future_y) a = angle(v1, v2) if a < 0: factor *= -1 avoidance_x += factor * -normalized_vy avoidance_y += factor * normalized_vx forces["avoidance"] = (avoidance_x, avoidance_y) if len(self.neighbours) == 0: return forces sum_x, sum_y = 0.0, 0.0 sum_vx, sum_vy = 0.0, 0.0 sep_x, sep_y = 0.0, 0.0 for boid in self.neighbours: distance = self.world.distances[self, boid] factor = 1 - distance / self.world.neighbourhood_radius nvx, nvy = boid.normalized_velocity sum_vx += nvx sum_vy += nvy sum_x += boid.x sum_y += boid.y rel_x, rel_y = normalize_vector(*self.relative_coordinates(boid.x, boid.y)) sep_x -= factor * rel_x sep_y -= factor * rel_y forces["separation"] = (sep_x, sep_y) forces["alignment"] = normalize_vector(sum_vx, sum_vy) avg_x = sum_x / len(self.neighbours) avg_y = sum_y / len(self.neighbours) forces["cohesion"] = normalize_vector(*self.relative_coordinates(avg_x, avg_y)) return forces
def normalized_velocity(self): """ aka a length 1 vector in the current movement direction """ return normalize_vector(self.vx, self.vy)
def calculate_forces(self): """ The force calculations have been joined into a single function for performance reasons. """ forces = { 'separation': (0, 0), 'alignment': (0, 0), 'cohesion': (0, 0), 'avoidance': (0, 0), 'flight': (0, 0) } self.fleeing = False flight_x, flight_y = 0.0, 0.0 for predator in self.predators: self.fleeing = True distance = self.distance(predator) if distance < PREDATOR_RADIUS: dead = self.die() if dead: return forces factor = 1 - distance / self.world.neighbourhood_radius rel_x, rel_y = self.relative_coordinates(predator.x, predator.y) flight_x -= factor * rel_x flight_y -= factor * rel_y forces['flight'] = (flight_x, flight_y) self.avoiding = False avoidance_x, avoidance_y = 0.0, 0.0 for obstacle in self.world.obstacles: distance = self.shortest_distance(obstacle.x, obstacle.y) if distance < (BOID_RADIUS + self.world.neighbourhood_radius + OBSTACLE_RADIUS): if distance < OBSTACLE_RADIUS: dead = self.die() if dead: return forces normalized_vx, normalized_vy = self.normalized_velocity intersection = False for n in xrange(1, int(distance)): future_x = self.x + n * normalized_vx future_y = self.y + n * normalized_vy d = euclidean_distance((future_x, future_y), obstacle.position) if d < (obstacle.r + BOID_RADIUS): intersection = True break if intersection: self.avoiding = True factor = 1 - (distance - obstacle.r) / self.world.neighbourhood_radius future_x = self.x + distance * normalized_vx future_y = self.y + distance * normalized_vy v1 = self.relative_coordinates(*obstacle.position) v2 = self.relative_coordinates(future_x, future_y) a = angle(v1, v2) if a < 0: factor *= -1 avoidance_x += factor * -normalized_vy avoidance_y += factor * normalized_vx forces['avoidance'] = (avoidance_x, avoidance_y) if len(self.neighbours) == 0: return forces sum_x, sum_y = 0.0, 0.0 sum_vx, sum_vy = 0.0, 0.0 sep_x, sep_y = 0.0, 0.0 for boid in self.neighbours: distance = self.world.distances[self, boid] factor = 1 - distance / self.world.neighbourhood_radius nvx, nvy = boid.normalized_velocity sum_vx += nvx sum_vy += nvy sum_x += boid.x sum_y += boid.y rel_x, rel_y = normalize_vector( *self.relative_coordinates(boid.x, boid.y)) sep_x -= factor * rel_x sep_y -= factor * rel_y forces['separation'] = (sep_x, sep_y) forces['alignment'] = normalize_vector(sum_vx, sum_vy) avg_x = sum_x / len(self.neighbours) avg_y = sum_y / len(self.neighbours) forces['cohesion'] = normalize_vector( *self.relative_coordinates(avg_x, avg_y)) return forces