def compute_blast_radius(self, collision_bodies): blast_radius = Geometry.Polygon('blast_radius') x = int(self.collision_geometry.sphere.pose.copy()[0]) y = int(self.collision_geometry.sphere.pose.copy()[1]) blast_radius.sphere = Geometry.Sphere(x, y, self.blast_radius) for body in collision_bodies: if body.name != 'ground': if Geometry.sphere_is_collision(blast_radius, body.collision_geometry): body.hit(self, self.parent, blast=True)
def __init__(self, logger, debug_mode, parent, shell_file, name, starting_pose, launch_angle): super().__init__() self.logger = logger self.debug_mode = debug_mode self.parent = parent self.shell_file = shell_file self.collided_with = [] self.launched = False self.collided = False self.done = False fp = open(f'{self.shells_path}{shell_file}', 'r') shell_data = json.load(fp) fp.close() self.collision_geometry = Geometry.Polygon(name) self.collision_geometry.from_shell_data(shell_data) self.collision_geometry.teleport(starting_pose) self.visual_geometry_file = QtGui.QPixmap( f"{self.shells_path}{shell_data['visual_geometry']}") self.visual_geometry = self.visual_geometry_file self.visual_offset = shell_data['visual_offset'] self.angle = 0.0 self.name = f"{shell_data['name']}_{name}" self.mass = float(shell_data['mass']) self.max_vel = float(shell_data['max_vel']) self.gravity_force = numpy.array([[0], [self.mass * Geometry.m_to_px(9.8)]]) self.launch_force = float(shell_data['launch_force']) self.launch_angle = launch_angle self.angle = launch_angle self.blast_radius = float(shell_data['blast_radius']) self.max_damage = float(shell_data['max_damage']) self.capacity = shell_data['capacity'] self.physics = Physics.Physics2D(self.mass, self.max_vel, drag=False) self.physics.position = self.collision_geometry.sphere.pose.copy() # C library for collision checking self.c_double_p = ctypes.POINTER(ctypes.c_double) self.cc_fun = ctypes.CDLL( f'{self.lib_path}{self.cc_lib_path}') # Or full path to file self.cc_fun.polygon_is_collision.argtypes = [ self.c_double_p, ctypes.c_int, ctypes.c_int, self.c_double_p, ctypes.c_int, ctypes.c_int ] self.heartbeats = 0 self.heartbeat_timer = QtCore.QTimer() self.heartbeat_timer.timeout.connect(self.heartbeat) self.heartbeat_timer.start(1000 * 15)
def set_power(self): sols = [] launch_angle = self.barrel_angle + self.angle starting_pose = self.barrel_tip shell = Shell.Shell(self.logger, self.debug_mode, self, self.shell_type, f'{self.shots_fired}', starting_pose, launch_angle) x_goal = float(self.target[0]) y_goal = float(self.target[1]) grav = Geometry.m_to_px(9.8) for scale in numpy.linspace(.1, 1, num=50): vx = scale * shell.max_vel * math.cos(launch_angle) vy = scale * shell.max_vel * math.sin(launch_angle) # Compute time to travel x distance at this starting velocity and angle delta_x = x_goal - float(self.barrel_tip[0]) tx = delta_x / vx # Compute time to travel y distance at this starting velocity and angle delta_y_peak = (-1. * math.pow(vy, 2)) / (2. * grav) t_up = -1. * vy / grav y_max = self.barrel_tip[1] + delta_y_peak delta_y_goal = abs(y_goal - y_max) v_max = math.sqrt(2. * grav * delta_y_goal) t_down = v_max / grav ty = t_up + t_down # The times should be equal to satisfy this equation if abs(tx - ty) < .3: sols.append(scale) if len(sols) > 0: self.power_scale = sols[0]
def mousePressEvent(self, e): self.logger.log(f'Mouse Press: {e.button()} {e.x()} {e.y()}') self.mouse_pose = numpy.array([[e.x()], [e.y()]]) self.prev_mouse_pose = numpy.array([[e.x()], [e.y()]]) for idx, tank in enumerate(self.tanks): clicked = Geometry.point_is_collision(tank.collision_geometry, self.mouse_pose) if clicked: self.logger.log(f'Mouse collided with: {tank.name}') self.drag_tank_idx = idx return self.collision_bodies = self.shells + [self.map] for body in self.collision_bodies: selected_entity = Geometry.point_is_collision( body.collision_geometry, self.mouse_pose) if selected_entity: self.logger.log(f'Mouse collided with: {body.name}')
def allimages(self): ''' Manipulates the given RGB images using the Geometry script. args: imagesnames (str): Images' names. ''' for imagename in self.imagesnames: image = Geometry.Image(imagename, self.feature_extraction_method) image.imgid = self.imagesnames.index(imagename) self.images.append(image)
def random(self): self.name = 'ground' vertices = self.map_creator.random_map() self.collision_geometry = Geometry.Polygon(self.name) self.collision_geometry.custom(vertices) self.seed_pose = numpy.array([[100.], [300.]]) offset = numpy.array([[0.], [800]]) self.collision_geometry.translate(offset) self.set_visual_geometry() self.set_topology()
def read_from_file(self, map_file): fp = open(f'{self.maps_path}{map_file}', 'r') map_data = json.load(fp) self.name = map_data['name'] self.collision_geometry = Geometry.Polygon(self.name) self.collision_geometry.from_map_data(map_data) ox, oy = map_data['offset'] offset = numpy.array([[ox], [oy]]) tx, ty = map_data['seed_pose'] self.seed_pose = numpy.array([[tx], [ty]]) self.collision_geometry.translate(offset) self.set_visual_geometry() self.set_topology()
def update_position(self, forces, delta_t, angle, collision_bodies): self.previous_pose = self.physics.position.copy() initial_velocity = self.physics.velocity.copy() rot_dir = 1.0 * numpy.sign(angle - self.angle) self.rotate(rot_dir, point=self.collision_geometry.sphere.pose) # self.rotate(angle,point=self.collision_geometry.sphere.pose) offset = self.physics.accelerate(forces, delta_t) self.collision_geometry.translate(offset) self.barrel_geometry.translate(offset) self.barrel_tip += offset self.collided_with = [] for body in collision_bodies: data = self.collision_geometry.vertices r1, c1 = self.collision_geometry.vertices.shape data = data.astype(numpy.double) data_p = data.ctypes.data_as(self.c_double_p) data2 = body.collision_geometry.vertices r2, c2 = body.collision_geometry.vertices.shape data2 = data2.astype(numpy.double) data_p2 = data2.ctypes.data_as(self.c_double_p) # C Function call in python if Geometry.sphere_is_collision(self.collision_geometry, body.collision_geometry): res = self.cc_fun.polygon_is_collision(data_p, int(r1), int(c1), data_p2, int(r2), int(c2)) if res: self.rotate(-1.0 * rot_dir, point=self.collision_geometry.sphere.pose) self.physics.position = self.previous_pose.copy() self.collision_geometry.translate(-1 * offset) self.barrel_geometry.translate(-1 * offset) self.barrel_tip -= offset self.physics.velocity = numpy.zeros([2, 1]) self.collided_with.append(body.name) print(self.collided_with) self.update_visual_geometry()
def update_position(self, forces, delta_t, collision_bodies): if self.collided: self.done = True self.done_signal.emit() return old_pose = self.physics.position.copy() old_vel = self.physics.velocity.copy() offset = self.physics.accelerate(forces, delta_t) theta_0 = math.atan(old_vel[1] / old_vel[0]) theta_1 = math.atan(self.physics.velocity[1] / self.physics.velocity[0]) theta = theta_1 - theta_0 self.rotate(theta, point=self.collision_geometry.sphere.pose.copy()) self.collision_geometry.translate(offset) for body in collision_bodies: data = self.collision_geometry.vertices r1, c1 = self.collision_geometry.vertices.shape data = data.astype(numpy.double) data_p = data.ctypes.data_as(self.c_double_p) data2 = body.collision_geometry.vertices r2, c2 = body.collision_geometry.vertices.shape data2 = data2.astype(numpy.double) data_p2 = data2.ctypes.data_as(self.c_double_p) # # C Function call in python if Geometry.sphere_is_collision(self.collision_geometry, body.collision_geometry): res1 = self.cc_fun.polygon_is_collision( data_p, int(r1), int(c1), data_p2, int(r2), int(c2)) # res2 = Geometry.poly_lies_inside(self.collision_geometry,body.collision_geometry) res2 = False if res1 or res2: self.collided_with.append(body.name) body.hit(self, self.parent) if body.name == 'ground': self.compute_blast_radius(collision_bodies) self.collided = True
def rotate(self, sign, point=None): step_size = 0.01 self.angle += (step_size * sign) self.collision_geometry.rotate(sign, step_size, point=point) self.collision_geometry.set_bounding_sphere() self.physics.position = self.collision_geometry.sphere.pose.copy() self.collision_geometry.origin = self.collision_geometry.vertices[:, 0].reshape( 2, 1 ).copy( ) prev_offset = self.barrel_offset.copy() tmp_offset = Geometry.rotate_2d(prev_offset, sign * step_size) self.barrel_offset = tmp_offset self.barrel_geometry.teleport(self.collision_geometry.origin + self.barrel_offset) self.rotate_barrel(sign)
def __init__(self, logger, debug_mode, tank_file, shell_file, shell_list, name, color): super().__init__() self.logger = logger self.debug_mode = debug_mode self.tank_file = tank_file self.alive = True self.collided_with = [] self.prev_shot_time = -1.0 self.shell_type = shell_file self.shell_list = shell_list self.shell_idx = self.shell_list.index(self.shell_type) shell = Shell.Shell(self.logger, self.debug_mode, self, shell_file, f'{0}', numpy.zeros([2, 1]), 0.0) self.shot_limit = shell.capacity self.shots_fired = 0 self.shots_left = self.shot_limit - self.shots_fired self.xp = 0.0 self.turn_over = False self.angle = 0.0 self.barrel_angle = 0.0 self.power_scale = 1.0 self.armour_rating = None fp = open(f'{self.tanks_path}{tank_file}', 'r') tank_data = json.load(fp) fp.close() self.name = f"{tank_data['name']}_{name}" self.logger.log(f'Creating tank: {self.name}') self.color = color self.mass = float(tank_data['mass']) self.max_vel = Geometry.m_to_px(float(tank_data['max_vel'])) self.fire_rate = 1.0 / (float(tank_data['fire_rate']) / 60. ) # seconds per round self.gravity_force = numpy.array([[0.0], [self.mass * Geometry.m_to_px(9.8)]]) self.drive_force = float(tank_data['drive_force']) self.upper_barrel_limit = math.radians(20.0) self.lower_barrel_limit = math.radians(-200.0) self.health = float(tank_data['health']) self.max_health = float(tank_data['health']) self.gas_limit = float(tank_data['gas']) self.gas_used = 0.0 self.gas_left = self.gas_limit - self.gas_used self.collision_geometry = Geometry.Polygon(self.name) self.collision_geometry.from_tank_data(tank_data, 'vertices') self.barrel_geometry = Geometry.Polygon(self.name) self.barrel_geometry.from_tank_data(tank_data, 'barrel') x, y = tank_data['barrel_offset'] self.barrel_offset = numpy.array([[float(x)], [float(y)]]) self.barrel_geometry.translate(self.barrel_offset) self.barrel_length = float(tank_data['barrel_length']) x = self.barrel_length * math.cos(self.barrel_angle) y = self.barrel_length * math.sin(self.barrel_angle) self.barrel_tip = self.barrel_offset + numpy.array([[x], [y]]) self.armour_rating = float(tank_data['armour_rating']) self.visual_geometry = QtGui.QPolygonF() self.visual_barrel = QtGui.QPolygonF() self.update_visual_geometry() self.physics = Physics.Physics2D(self.mass, self.max_vel) self.physics.position = self.collision_geometry.sphere.pose.copy() # C library for collision checking self.c_double_p = ctypes.POINTER(ctypes.c_double) self.cc_fun = ctypes.CDLL( f'{self.lib_path}{self.cc_lib_path}') # Or full path to file self.cc_fun.polygon_is_collision.argtypes = [ self.c_double_p, ctypes.c_int, ctypes.c_int, self.c_double_p, ctypes.c_int, ctypes.c_int ]
from tkinter import Tk from lib import Title, Menu, Geometry, Resize from frame import Intro, Path, License, Control root = Tk() Title(root) Menu(root) Geometry(root) Resize(root) Intro(root).pack() Path(root).pack() License(root).pack() Control(root).pack() root.mainloop()