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
def step(self): dist_unit = SimEngine.gui_get(DIST_UNIT) screen_distance_unit = sqrt(SCREEN_PIXEL_WIDTH()**2 + SCREEN_PIXEL_HEIGHT()**2) / dist_unit if SimEngine.gui_get(LAYOUT) == FORCE_DIRECTED: for node in World.agents: node.adjust_distances(screen_distance_unit, self.velocity_adjustment) self.compute_metrics()
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()
def __init__(self): center_pixel = Pixel_xy( (uniform(0, SCREEN_PIXEL_WIDTH()), uniform(0, SCREEN_PIXEL_HEIGHT()))) color = utils.color_random_variation(Color('yellow')) super().__init__(center_pixel=center_pixel, color=color, scale=1)
def screen_distance_unit(): dist_unit = gui_get(DIST_UNIT) screen_distance_unit = sqrt(SCREEN_PIXEL_WIDTH()**2 + SCREEN_PIXEL_HEIGHT()**2) / dist_unit return screen_distance_unit
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()