예제 #1
0
    def compute_velocity(self, screen_distance_unit, velocity_adjustment):
        repulsive_force: Velocity = Velocity((0, 0))

        for node in (World.agents - {self}):
            repulsive_force += self.force_as_dxdy(self.center_pixel,
                                                  node.center_pixel,
                                                  screen_distance_unit,
                                                  repulsive=True)

        # Also consider repulsive force from walls.
        repulsive_wall_force: Velocity = Velocity((0, 0))

        horizontal_walls = [
            Pixel_xy((0, 0)),
            Pixel_xy((SCREEN_PIXEL_WIDTH(), 0))
        ]
        x_pixel = Pixel_xy((self.center_pixel.x, 0))
        for h_wall_pixel in horizontal_walls:
            repulsive_wall_force += self.force_as_dxdy(x_pixel,
                                                       h_wall_pixel,
                                                       screen_distance_unit,
                                                       repulsive=True)

        vertical_walls = [
            Pixel_xy((0, 0)),
            Pixel_xy((0, SCREEN_PIXEL_HEIGHT()))
        ]
        y_pixel = Pixel_xy((0, self.center_pixel.y))
        for v_wall_pixel in vertical_walls:
            repulsive_wall_force += self.force_as_dxdy(y_pixel,
                                                       v_wall_pixel,
                                                       screen_distance_unit,
                                                       repulsive=True)

        attractive_force: Velocity = Velocity((0, 0))
        for node in (World.agents - {self}):
            if link_exists(self, node):
                attractive_force += self.force_as_dxdy(self.center_pixel,
                                                       node.center_pixel,
                                                       screen_distance_unit,
                                                       repulsive=False)

        # noinspection PyTypeChecker
        net_force: Velocity = repulsive_force + repulsive_wall_force + attractive_force
        normalized_force: Velocity = net_force / max(
            [net_force.x, net_force.y, velocity_adjustment])
        normalized_force *= 10

        if gui_get(PRINT_FORCE_VALUES):
            print(f'{self}. \n'
                  f'rep-force {tuple(repulsive_force.round(2))}; \n'
                  f'rep-wall-force {tuple(repulsive_wall_force.round(2))}; \n'
                  f'att-force {tuple(attractive_force.round(2))}; \n'
                  f'net-force {tuple(net_force.round(2))}; \n'
                  f'normalized_force {tuple(normalized_force.round(2))}; \n\n')
        return normalized_force
예제 #2
0
    def setup(self):
        nbr_agents = SimEngine.get_gui_value('nbr_agents')
        for _ in range(nbr_agents):
            # When created, a agent adds itself to self.agents and to its patch's list of Agents.
            # self.agent_class(scale=1)
            Agent(scale=1)

        initial_velocities = cycle([Velocity((-1, -1)), Velocity((-1, 1)),
                                    Velocity((0, 0)),
                                    Velocity((1, -1)), Velocity((1, 1))])
        for (agent, vel) in zip(World.agents, initial_velocities):
            agent.set_velocity(vel)
예제 #3
0
    def setup(self):
        nbr_agents = gui_get('nbr_agents')
        for _ in range(nbr_agents):
            self.agent_class(scale=1)

        vs = [
            Velocity((-1, -1)),
            Velocity((-1, 1)),
            Velocity((0, 0)),
            Velocity((1, -1)),
            Velocity((1, 1))
        ]
        for (agent, vel) in zip(World.agents, cycle(vs)):
            agent.set_velocity(vel)
예제 #4
0
    def move_agent(self, delta: Velocity):
        Agent.some_agent_changed = True
        (capped_x, capped_y) = delta.cap_abs_value(1)

        # Note that x and y have been defined to be getters for center pixels (x, y).
        new_center_pixel = Pixel_xy((self.x + capped_x, self.y + capped_y))
        self.move_to_xy(new_center_pixel)
예제 #5
0
 def step(self):
     """
     Update the world by moving the agents.
     """
     for agent in World.agents:
         agent.move_by_velocity()
         if World.ticks > 125 and random() < 0.01:
             agent.set_velocity(Velocity((uniform(-2, 2), uniform(-2, 2))))
예제 #6
0
    def bounce_off_screen_edge(self, dxdy):
        """
       Bounce agent off the screen edges. dxdv is the current agent velocity.
       If the agent should bounce, change it as needed.
       """
        # The center pixel of this agent.
        current_center_pixel = self.center_pixel
        # Where the agent will be it if moves by dxdy.
        next_center_pixel = current_center_pixel + dxdy
        # The patch's row_col or next_center_pixel. Is that off the screen? If so, the agent should bounce.
        next_row_col = next_center_pixel.pixel_to_row_col()
        if next_row_col.row < 0 or gui.PATCH_ROWS <= next_row_col.row:
            dxdy = Velocity((dxdy.dx, dxdy.dy * (-1)))
        if next_row_col.col < 0 or gui.PATCH_COLS <= next_row_col.col:
            dxdy = Velocity((dxdy.dx * (-1), dxdy.dy))

        return dxdy
예제 #7
0
 def adjust_nodes(self):
     """
     If the actual length doesn't match the proper length, move Node_2 vertically (up or down) until
     it does match. Each step moves Node_2 by at most 1 pixel.
     """
     actual_length = self.node_1.distance_to(self.node_2)
     discrepancy = self.proper_length() - actual_length
     if abs(discrepancy) > 0:
         self.node_2.move_node(Velocity((0, discrepancy)))
    def setup(self):
        nbr_agents = int(SimEngine.gui_get('nbr_agents'))
        for i in range(nbr_agents):
            # Adds itself to self.agents and to its patch's list of Agents.
            agent = self.agent_class(color=Color('red'))
            agent.set_velocity(Velocity((uniform(-2, 2), uniform(-2, 2))))

        for patch in self.patches:
            patch.update_collision_color(World.agents)
예제 #9
0
    def setup(self):
        nbr_agents = SimEngine.gui_get('nbr_agents')
        for _ in range(nbr_agents):
            # When created, a agent adds itself to World.agents and to its patch's list of Agents.

            # To create an agent:
            #         Agent(scale=1)
            # More generallly, though, you can use the agent_class the system knows about.
            self.agent_class(scale=1)

        initial_velocities = cycle([
            Velocity((-1, -1)),
            Velocity((-1, 1)),
            Velocity((0, 0)),
            Velocity((1, -1)),
            Velocity((1, 1))
        ])
        for (agent, vel) in zip(World.agents, initial_velocities):
            agent.set_velocity(vel)
    def step(self):
        """
        Update the world by moving the agent and indicating the patches that intersect the agent
        """
        for agent in World.agents:
            agent.move_by_velocity()
            if random() < 0.01:
                agent.set_velocity(Velocity((randint(-2, 2), randint(-2, 2))))

        for patch in self.patches:
            patch.update_collision_color(World.agents)
예제 #11
0
    def adjust_distances(self, velocity_adjustment):
        #get from gui what the base distance units
        dist_unit = SimEngine.gui_get(('dist_unit'))

        #define how many distance units exist per screen
        screen_distance_unit = sqrt(SCREEN_PIXEL_WIDTH()**2 +
                                    SCREEN_PIXEL_HEIGHT()**2) / dist_unit

        #define initial Veolocity as (0,0), forces act in the x and y directions
        repulsive_force: Velocity = Velocity((0, 0))

        #for all other agents excluding this instance
        for agent in (World.agents - {self}):
            #add their respective influence of each other element towards this element, calculate using
            #this center pixel, elements center pixel and using defined units (optional repulsove flag)
            repulsive_force += self.force_as_dxdy(self.center_pixel,
                                                  agent.center_pixel,
                                                  screen_distance_unit,
                                                  repulsive=True)

        # Also consider repulsive force from walls.
        repulsive_wall_force: Velocity = Velocity((0, 0))

        horizontal_walls = [
            Pixel_xy((0, 0)),
            Pixel_xy((SCREEN_PIXEL_WIDTH(), 0))
        ]
        x_pixel = Pixel_xy((self.center_pixel.x, 0))
        for h_wall_pixel in horizontal_walls:
            repulsive_wall_force += self.force_as_dxdy(x_pixel,
                                                       h_wall_pixel,
                                                       screen_distance_unit,
                                                       repulsive=True)

        vertical_walls = [
            Pixel_xy((0, 0)),
            Pixel_xy((0, SCREEN_PIXEL_HEIGHT()))
        ]
        y_pixel = Pixel_xy((0, self.center_pixel.y))
        for v_wall_pixel in vertical_walls:
            repulsive_wall_force += self.force_as_dxdy(y_pixel,
                                                       v_wall_pixel,
                                                       screen_distance_unit,
                                                       repulsive=True)

        #calculate the attractive force generated by all the nodes connected by a link
        attractive_force: Velocity = Velocity((0, 0))
        for agent in (World.agents - {self}):
            if link_exists(self, agent):
                attractive_force += self.force_as_dxdy(self.center_pixel,
                                                       agent.center_pixel,
                                                       screen_distance_unit,
                                                       repulsive=False)

        #find the final force, find out what velocity adjustment is
        net_force = repulsive_force + repulsive_wall_force + attractive_force
        normalized_force: Velocity = net_force / max(
            [net_force.x, net_force.y, velocity_adjustment])
        normalized_force *= 10

        #print force values if selected
        if SimEngine.gui_get('Print force values'):
            print(f'{self}. \n'
                  f'rep-force {tuple(repulsive_force.round(2))}; \n'
                  f'rep-wall-force {tuple(repulsive_wall_force.round(2))}; \n'
                  f'att-force {tuple(attractive_force.round(2))}; \n'
                  f'net-force {tuple(net_force.round(2))}; \n'
                  f'normalized_force {tuple(normalized_force.round(2))}; \n\n')

        #set the velocity of this object
        self.set_velocity(normalized_force)
        #take a step
        self.forward()
예제 #12
0
 def random_velocity():
     limit = gui_get('Max_speed')
     return Velocity(
         (uniform(-limit / 100,
                  limit / 100), uniform(-limit / 100, limit / 100)))
예제 #13
0
    def setup_a(self):
        """
        Set up for the drop weight animation.
        """

        # Move out by a small amount so that the two lines can be seen.
        step = 5 if SimEngine.gui_get('Pause?') else 0

        self.top_spring.move_by_dxdy((step, 0))
        self.top_spring.set_target_by_dxdy((self.x_offset-step, 0))

        self.weight_cord.set_target_by_dxdy((0, Braess_World.cord_slack))

        center_bar_node = self.bottom_spring.node_2

        # Construct the full bar.
        bar_y = center_bar_node.y
        left_bar_node = Braess_Node(Pixel_xy( (self.x, bar_y) ) )
        right_bar_node = Braess_Node(Pixel_xy( (self.x, bar_y) ) )

        # By convention, the position of node_1 determines node_2's position.
        # In this case, since we will be pulling the bar up by its ends,
        # make the ends the controlling nodes.
        self.bar_right = Braess_Bar(right_bar_node, center_bar_node)
        self.bar_left = Braess_Bar(left_bar_node, center_bar_node)

        # Attach the bottom spring to the left end of the bar.
        self.bottom_spring.node_2 = left_bar_node

        left_bar_node.move_by_dxdy(Velocity((-step, 0)))
        right_bar_node.move_by_dxdy(Velocity((step, 0)))

        left_bar_node.set_target_by_dxdy(Velocity((-self.x_offset+step, Braess_World.cord_slack)))
        right_bar_node.set_target_by_dxdy(Velocity((self.x_offset-step, Braess_World.cord_slack)))

        # Attach the top cord to the right end of the bar rather than the center.
        self.top_cord.node_2 = right_bar_node

        # The left cord is a new element in state 2. It is offset to the left.
        x_coord = self.x
        cord_length = self.bottom_spring.node_1.y - Braess_World.top
        self.left_cord = Braess_Link.vertical_linked_nodes(Braess_Cord,
                                                           x_coord, Braess_World.top,
                                                           length=cord_length)

        # The left cord is offset to the left.
        self.left_cord.move_by_dxdy((-step, 0))
        self.left_cord.node_1.set_target_by_dxdy(Velocity((-self.x_offset + step, 0)))
        self.left_cord.node_2.set_target_by_dxdy(Velocity((-self.x_offset + step, Braess_World.cord_slack)))

        self.left_cord.color = Color('yellow2')
        self.top_cord.color = Color('yellow2')

        # Make the left_cord's bottom node the top node of the bottom spring.
        World.agents.remove(self.bottom_spring.node_1)
        self.bottom_spring.node_1 = self.left_cord.node_2

        # Add the new cord and bars to the adjustable links.
        self.adjustable_links.extend([self.left_cord, self.bar_right, self.bar_left])

        Agent.key_step_done = False

        #                            ## Done with the setup for the animation. ##                            #

        SimEngine.gui_set(Braess_World.CUT_CORD, enabled=False)
        SimEngine.gui_set(GO_ONCE, enabled=True)
        SimEngine.gui_set(GOSTOP, enabled=True)
        if SimEngine.gui_get('Slow?'):
            SimEngine.fps = 15
        if not SimEngine.gui_get('Pause?'):
            gui.WINDOW['GoStop'].click()
        Braess_World.state = 'a'
예제 #14
0
 def random_velocity(limit=0.75):
     return Velocity((uniform(-limit, limit), uniform(-limit, limit)))
예제 #15
0
 def move_by_dxdy(self, dxdy: Tuple):
     self.node_1.move_by_dxdy(Velocity(dxdy))
     self.node_2.move_by_dxdy(Velocity(dxdy))
예제 #16
0
 def set_target_by_dxdy(self, dxdy: Tuple):
     for node in [self.node_1, self.node_2]:
         node.set_target_by_dxdy(Velocity(dxdy))
예제 #17
0
    def adjust_distances(self, velocity_adjustment):
        dist_unit = 8
        screen_distance_unit = sqrt(SCREEN_PIXEL_WIDTH()**2 +
                                    SCREEN_PIXEL_HEIGHT()**2) / dist_unit

        repulsive_force: Velocity = Velocity((0, 0))

        for agent in (World.agents - {self}):
            repulsive_force += self.force_as_dxdy(self.center_pixel,
                                                  agent.center_pixel,
                                                  screen_distance_unit,
                                                  repulsive=True)

        # Also consider repulsive force from walls.
        repulsive_wall_force: Velocity = Velocity((0, 0))

        horizontal_walls = [
            Pixel_xy((0, 0)),
            Pixel_xy((SCREEN_PIXEL_WIDTH(), 0))
        ]
        x_pixel = Pixel_xy((self.center_pixel.x, 0))
        for h_wall_pixel in horizontal_walls:
            repulsive_wall_force += self.force_as_dxdy(x_pixel,
                                                       h_wall_pixel,
                                                       screen_distance_unit,
                                                       repulsive=True)

        vertical_walls = [
            Pixel_xy((0, 0)),
            Pixel_xy((0, SCREEN_PIXEL_HEIGHT()))
        ]
        y_pixel = Pixel_xy((0, self.center_pixel.y))
        for v_wall_pixel in vertical_walls:
            repulsive_wall_force += self.force_as_dxdy(y_pixel,
                                                       v_wall_pixel,
                                                       screen_distance_unit,
                                                       repulsive=True)

        attractive_force: Velocity = Velocity((0, 0))
        for agent in (World.agents - {self}):
            if link_exists(self, agent):
                attractive_force += self.force_as_dxdy(self.center_pixel,
                                                       agent.center_pixel,
                                                       screen_distance_unit,
                                                       repulsive=False)

        net_force = repulsive_force + repulsive_wall_force + attractive_force
        normalized_force: Velocity = net_force / max(
            [net_force.x, net_force.y, velocity_adjustment])
        normalized_force *= 10

        if SimEngine.gui_get('Print force values'):
            print(f'{self}. \n'
                  f'rep-force {tuple(repulsive_force.round(2))}; \n'
                  f'rep-wall-force {tuple(repulsive_wall_force.round(2))}; \n'
                  f'att-force {tuple(attractive_force.round(2))}; \n'
                  f'net-force {tuple(net_force.round(2))}; \n'
                  f'normalized_force {tuple(normalized_force.round(2))}; \n\n')

        self.set_velocity(normalized_force)
        self.forward()