def draw(self, context): super(World, self).draw(context) if self.show_grid: self.displaygrid(context) # render inhabitants for inhabitant in self.inhabitants: # cull # render relationships context.set_source_rgb(0.0, 0.0, 0.0) context.set_line_width(0.4) if TheMouse.connecting is not None: # relationship in progress (x1,y1) = TheMouse.connecting.position#_output (x2,y2) = (TheMouse.last_motion_x, TheMouse.last_motion_y) # clip (discard, discard, x1, y1) = MathLib.clip_line_to_rectangle(x1, y1, x2, y2, TheMouse.connecting) context.move_to(x1, y1) context.line_to(x2, y2) context.stroke() self.arrowhead(context, x2, y2, x1, y1, 1.5) if TheMouse.associating is not None: # association in progress object = TheMouse.associating radius = object.decorator_size / max(object.scale_x, object.scale_y) (x,y) = (TheMouse.last_motion_x, TheMouse.last_motion_y) context.move_to(x - radius, y) context.arc(x, y, radius, -math.pi, 0.0) context.stroke() for output in inhabitant.outputs(): # clip (discard, discard, x1, y1) = MathLib.clip_line_to_rectangle(inhabitant.x, inhabitant.y, output.x, output.y, inhabitant) (discard, discard, x2, y2) = MathLib.clip_line_to_rectangle(output.x, output.y, inhabitant.x, inhabitant.y, output) context.move_to(x1, y1) context.line_to(x2, y2) context.stroke() self.arrowhead(context, x2, y2, x1, y1, 1.5) # render inhabitant context.save() (x, y) = inhabitant.position context.translate(x, y) if inhabitant.rotation != 0: context.rotate(math.radians(inhabitant.rotation)) scale = max(inhabitant.world_width / (self.unit_range*2.0), inhabitant.world_height / (self.unit_range*2.0)) context.scale(scale, scale) #scale_x = inhabitant.world_width / (self.unit_range * 2.0) #scale_y = inhabitant.world_height / (self.unit_range * 2.0) #context.scale(scale_x, scale_y) inhabitant.draw(context) context.restore()
def receives__look(self): """return heading of first object seen""" # set up view poly self.Ax = 0.0 self.Ay = 0.0 self.Bx = (self.sight_distance * math.cos(math.radians(self.rotation - 45.0))) self.By = (self.sight_distance * math.sin(math.radians(self.rotation - 45.0))) self.Cx = (self.sight_distance * math.cos(math.radians(self.rotation + 45.0))) self.Cy = (self.sight_distance * math.sin(math.radians(self.rotation + 45.0))) poly_x = [self.Ax, self.Bx, self.Cx] poly_y = [self.Ay, self.By, self.Cy] # for every inhabitant for inhabitant in TheWorld.inhabitants: if inhabitant == self: continue # get pos of inhabitant relative to fov unit square coords Px = (inhabitant.x / self.width) - (self.x / self.width) Py = (inhabitant.y / self.height) - (self.y / self.width) if MathLib.polygon_test(Px, Py, poly_x, poly_y): ret = 0.0 Dx = inhabitant.x - self.x Dy = inhabitant.y - self.y ret = math.degrees(math.atan2(Dy, Dx)) if ret < 0: ret += 360.0 #print "I can see: ", inhabitant, "at", ret, "degrees" return ret - self.rotation
def receives__forward(self, value = random() * 0.01): # calculate new x,y pos for vector of mag value at angle self.rotation # sin(rotation) = y / h # cos(rotation) = x / h # tan(rotation) = y / x # POSx = -(value) * (cos(rotation)) # POSy = +(value) * (sin(rotation)) new_x = (value * math.cos(math.radians(self.rotation))) new_y = (value * math.sin(math.radians(self.rotation))) # naive collision detection - TODO Optimizing _this_ would increase fps radically for inhabitant in TheWorld.inhabitants: if inhabitant == self or inhabitant.__class__ == widgets.graph.Graph: # TODO graph needs to have a center_x/y ! continue if MathLib.distance_test(self.center_x + new_x, self.center_y + new_y, \ inhabitant.center_x, inhabitant.center_y, \ 0.025): self.x -= new_x / 2.0 self.y -= new_y / 2.0 self.left(60.0) return self.x += new_x self.y += new_y # wrap screen if self.x < -1.0: self.x = 1.0 if self.y < -1.0: self.y = 1.0 if self.x > 1.0: self.x = -1.0 if self.y > 1.0: self.y = -1.0
def hit_test(self, pointer_x, pointer_y): # translate to local coords (x, y) = self._translate_pointer_local(pointer_x, pointer_y) self.mouse_over_property = MathLib.rect_test(x, y, 0.0, -self.world_height-(self.decorator_size/4.0), self.decorator_size, self.decorator_size/2.0) return Newton.hit_test(self, pointer_x, pointer_y)
def draw(self, context): context.restore() # TODO: FIX !!!! -> cheating to get access to world coords (x1,y1,x2,y2) = MathLib.calc_connector(self.source, self.sink) context.set_source_rgb(0.0, 0.0, 1.0) context.set_line_width(5.0) context.move_to(x1, y1) context.line_to(x2, y2) #gradient = cairo.LinearGradient(self.source.x - 5.0, self.source.y - 5.0, self.source.x - 5.0, self.sink.y + 5.0) #gradient.add_color_stop_rgba(0.0, 0.0, 0.0, 1.0, 0.2) #gradient.add_color_stop_rgba(1.0, 0.0, 0.0, 1.0, 0.8) #context.set_source(gradient) context.stroke() context.save() # TODO: FIX !!!! -> cheating to get access to world coords
def hit_test(self, pointer_x, pointer_y): (pointer_x, pointer_y) = self._translate_pointer(pointer_x, pointer_y) hit = MathLib.rect_test( pointer_x, pointer_y, self.x, self.y, # self.world_width, self.world_height) self.world_width + self.decorator_size, self.world_height + self.decorator_size, ) # if not hit: # return False # check decorations -> Lower right pointer_x = (pointer_x - self.x) * 2.0 pointer_y = (pointer_y - self.y) * 2.0 self.mouse_over_sizer = MathLib.rect_test( pointer_x, pointer_y, self.world_width, self.world_height, self.decorator_size, self.decorator_size ) self.mouse_over_scaler = MathLib.rect_test( pointer_x, pointer_y, -self.world_width, self.world_height, self.decorator_size, self.decorator_size ) self.mouse_over_rotater = MathLib.rect_test( pointer_x, pointer_y, self.world_width, -self.world_height, self.decorator_size, self.decorator_size ) self.mouse_over_input = MathLib.rect_test( pointer_x, pointer_y, -self.world_width - (self.decorator_size / 2.0), 0, self.decorator_size, self.decorator_size, ) self.mouse_over_output = MathLib.rect_test( pointer_x, pointer_y, self.world_width + (self.decorator_size / 2.0), 0, self.decorator_size, self.decorator_size, ) return hit
def hit_test(self, x, y): return MathLib.rect_test(x, y, self.x, self.y, self.width, self.height)
def __init__(self, x, y, num_particles = [], do_reaction = False): Reactor.__init__(self, x, y, do_reaction=do_reaction) #self._ode_world.setGravity( (0,100.0,0) ) # some helpful constants pipe_size = 50.0 thick = 2.0 spacing = 1.0 # To create a wall: # # self.create_wall(x, y, # width, height) # # For example: # # A baffle: # # self.create_wall(0, 0, self.right - thick - spacing, thick) # # (0,0 would be the center of the reactor) # # top long self.create_wall(self.left-pipe_size, self.top, self.width+pipe_size, thick) # top short self.create_wall(self.left-pipe_size, self.top+pipe_size-thick, pipe_size+thick, thick) # input cap self.create_wall(self.left-pipe_size-thick-spacing, self.top, thick, pipe_size) # left self.create_wall(self.left, self.top+pipe_size+spacing, thick, self.height-pipe_size-thick-(spacing*2)) # right self.create_wall(self.right-thick, self.top+thick+spacing, thick, self.height-pipe_size-thick-(spacing*2)) # bottom short self.create_wall(self.right-thick, self.bottom-pipe_size, pipe_size+thick, thick) # bottom long self.create_wall(self.left, self.bottom-thick, self.width+pipe_size, thick) # To create the reactor input: # # self.create_input(x, y) # self.create_input(self.left - (pipe_size / 2.0) - 6.0, # - ReactorParticle.particle_radius, self.top + (pipe_size / 2.0)) # To create the reactor output: # # self.create_output(x, y, size) # self.create_output(self.right+pipe_size, self.bottom-(pipe_size/2.0), 40.0) # Initialize the system with some particles if len(num_particles) > 0: n = 0 for count in num_particles: w = (abs(self.left) + abs(self.right)) grid = MathLib.make_grid(count, w) for (x,y) in grid: self.add_body(ReactorParticle(color=colour.list[n], newton=None, # TODO - fix bug where ode_init called twice when constructing w/ a newton initial_position=(x, y), initial_force=(0,0))) n += 1