def dynamic(current_angle): if abs(current_angle) > 0.6: return False my_speed = course.rotate(current_angle) * context.speed.norm() my_line = Line(context.position, context.position + my_speed) for unit in all_units: if unit.speed.norm() == 0: continue unit_line = Line(unit.position, unit.position + unit.speed) intersection = my_line.intersection(unit_line) if intersection is None: continue if not is_in_world(intersection, world_tiles, tile_size): continue if is_in_empty_tile(intersection, world_tiles, tile_size): continue unit_dir = intersection - unit.position if unit_dir.norm() == 0 or unit_dir.cos(unit.speed) < 0: continue if unit_dir.norm() > my_speed.norm() * 100: continue my_dir = intersection - context.position if my_dir.norm() == 0 or my_dir.cos(my_speed) < 0: continue unit_time = unit_dir.norm() / unit.speed.norm() my_time = my_dir.norm() / my_speed.norm() if abs(my_time - unit_time) <= MY_INTERVAL: return True return False
def generate(): to_begin = Line(nearest, line.begin) if to_begin.length() > 0: def func(parameter): return (self.position.distance(to_begin(parameter)) - self.radius) if sign(func(0)) != sign(func(1)): yield to_begin(bisect(func, 0, 1)) to_end = Line(nearest, line.end) if to_end.length() > 0: def func(parameter): return (self.position.distance(to_end(parameter)) - self.radius) if sign(func(0)) != sign(func(1)): yield to_end(bisect(func, 0, 1))
def intersection_with_line(self, line: Line): nearest = line.nearest(self.position) distance = self.position.distance(nearest) if (distance > self.radius or (line.begin - nearest).dot(line.end - nearest) > 0): return [] if self.radius == distance: return [nearest] def generate(): to_begin = Line(nearest, line.begin) if to_begin.length() > 0: def func(parameter): return (self.position.distance(to_begin(parameter)) - self.radius) if sign(func(0)) != sign(func(1)): yield to_begin(bisect(func, 0, 1)) to_end = Line(nearest, line.end) if to_end.length() > 0: def func(parameter): return (self.position.distance(to_end(parameter)) - self.radius) if sign(func(0)) != sign(func(1)): yield to_end(bisect(func, 0, 1)) return list(generate())
def impl(angle): end = position + course.rotate(angle) line = Line(position, end) filtered = chain( (v.value for v in barriers if isinstance(v, BarrierLimit) and abs(angle) <= v.angle), (v for v in barriers if not isinstance(v, BarrierLimit)), ) return next( (True for v in filtered if v.has_intersection_with_line(line)), False)
def generate(): for car in context.opponents_cars: car_position = Point(car.x, car.y) car_speed = Point(car.speed_x, car.speed_y) car_barriers = list(make_units_barriers([car])) distance = (context.position - car_position).norm() if car_speed.norm() < 1: yield (not has_intersection_with_tiles(distance) and make_has_intersection_with_lane( position=context.position, course=tire_speed * 50, barriers=car_barriers, width=context.game.tire_radius, )(0)) else: car_line = Line(car_position, car_position + car_speed) tire_line = Line(context.position, context.position + tire_speed) intersection = tire_line.intersection(car_line) if intersection is None: continue if not is_in_world(intersection, world_tiles, tile_size): continue if is_in_empty_tile(intersection, world_tiles, tile_size): continue car_dir = intersection - car_position if car_dir.norm() > 0 and car_dir.cos(car_speed) < 0: continue if car_dir.norm() > context.game.tire_initial_speed * 50: continue tire_dir = intersection - context.position if tire_dir.norm() > 0 and tire_dir.cos(tire_speed) < 0: continue if has_intersection_with_tiles(tire_dir.norm()): continue car_time = car_dir.norm() / car_speed.norm() tire_time = tire_dir.norm() / tire_speed.norm() if abs(car_time - tire_time) <= TIRE_INTERVAL: yield True
def generate(): for car in context.opponents_cars: car_position = Point(car.x, car.y) car_speed = Point(car.speed_x, car.speed_y) car_barriers = list(make_units_barriers([car])) if car_speed.norm() < 1: for washer in washers: yield make_has_intersection_with_lane( position=washer.position, course=washer.speed * 150, barriers=car_barriers, width=context.game.washer_radius, )(0) else: car_line = Line(car_position, car_position + car_speed) for washer in washers: washer_line = Line(washer.position, washer.position + washer.speed) intersection = washer_line.intersection(car_line) if intersection is None: continue if not is_in_world(intersection, world_tiles, tile_size): continue if is_in_empty_tile(intersection, world_tiles, tile_size): continue car_dir = intersection - car_position if car_dir.norm() > 0 and car_dir.cos(car_speed) < 0: continue if car_dir.norm() > washer_speed * 150: continue washer_dir = intersection - washer.position if (washer_dir.norm() > 0 and washer_dir.cos(washer.speed) < 0): continue car_time = car_dir.norm() / car_speed.norm() washer_time = washer_dir.norm() / washer.speed.norm() if abs(car_time - washer_time) <= WASHER_INTERVAL: yield True
def clip_line(self, line: Line): k1 = self.point_code(line.begin) k2 = self.point_code(line.end) x1 = line.begin.x y1 = line.begin.y x2 = line.end.x y2 = line.end.y left = self.left_top.x top = self.left_top.y right = self.right_bottom.x bottom = self.right_bottom.y accept = False while True: if (k1 | k2) == 0: accept = True break if (k1 & k2) != 0: break opt = k1 or k2 if opt & Rectangle.TOP: x = x1 + (x2 - x1) * (bottom - y1) / (y2 - y1) y = bottom elif opt & Rectangle.BOTTOM: x = x1 + (x2 - x1) * (top - y1) / (y2 - y1) y = top if opt & Rectangle.RIGHT: y = y1 + (y2 - y1) * (right - x1) / (x2 - x1) x = right elif opt & Rectangle.LEFT: y = y1 + (y2 - y1) * (left - x1) / (x2 - x1) x = left if opt == k1: x1, y1 = x, y k1 = self.point_code(Point(x1, y1)) elif opt == k2: x2, y2 = x, y k2 = self.point_code(Point(x2, y2)) if accept: return Line(Point(x1, y1), Point(x2, y2)) else: return line
def has_intersection_with_line(self, line: Line): nearest = line.nearest(self.position) if nearest.distance(self.position) > self.radius: return False return line.has_point(nearest)
def test_nearest_to_degenerate_line_returns_that_point(self): line = Line(begin=Point(0, 0), end=Point(0, 0)) result = line.nearest(Point(1, 0)) assert_that(result, equal_to(Point(0, 0)))
def test_nearest_not_at_line_returns_at_line(self): line = Line(begin=Point(0, 0), end=Point(1, 0)) result = line.nearest(Point(1, 1)) assert_that(result, equal_to(Point(1, 0)))
def bottom(self): return Line(begin=self.right_bottom - Point(self.width(), 0), end=self.right_bottom)
def right(self): return Line(begin=self.right_bottom, end=self.right_bottom - Point(0, self.height()))
def left(self): return Line(begin=self.left_top, end=self.left_top + Point(0, self.height()))
def test_nearest_at_line_but_not_in_segment_returns_equal(self): line = Line(begin=Point(0, 0), end=Point(1, 0)) result = line.nearest(Point(2, 0)) assert_that(result, equal_to(Point(2, 0)))
def top(self): return Line(begin=self.left_top + Point(self.width(), 0), end=self.left_top)