Esempio n. 1
0
    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)}
Esempio n. 2
0
    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)}
Esempio n. 3
0
    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
Esempio n. 4
0
 def normalized_velocity(self):
     """
     aka a length 1 vector in the current movement direction
     """
     return normalize_vector(self.vx, self.vy)
Esempio n. 5
0
    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
Esempio n. 6
0
 def normalized_velocity(self):
     """
     aka a length 1 vector in the current movement direction
     """
     return normalize_vector(self.vx, self.vy)