def draw_long_spline(spline_sequence, xlim, ylim, plot_vectors=False): """Draw a spline_sequence on a plot spline_sequence = [all_points, all_points, ...] """ logg = logging.getLogger(f"c.{__name__}.draw_long_spline") # logg.setLevel("INFO") logg.debug(f"Starting draw_long_spline") fig, ax = plt.subplots() ax.set_xlim(*xlim) ax.set_ylim(*ylim) for all_points in spline_sequence: for i in range(len(all_points) - 1): p0 = all_points[i] p1 = all_points[i + 1] if plot_vectors: utils.add_vector(p0, ax, color="k", vec_len=20) # spline_x, spline_y = compute_spline(p0, p1) spline_x, spline_y = compute_thick_spline(p0, p1, 40) utils.add_points(spline_x, spline_y, ax, color="y", marker=".", ls="") if plot_vectors: utils.add_vector(p1, ax, color="k", vec_len=20) utils.plot_build(fig, ax) plt.show()
def assemble_tiles(graph): corner = set_top_left_corner(graph) positions = {corner: (0, 0)} for edge in nx.bfs_edges(graph, corner): # pylint: disable=cell-var-from-loop edges = graph.edges[edge]['edge'] tile_id_1, tile_id_2 = edge tile_1, tile_2 = graph.nodes[tile_id_1]['tile'], graph.nodes[tile_id_2]['tile'] assert tile_id_1 in positions tile_1_edges = tile_1.edges() edge_1 = iterutils.first(range(4), key=lambda i: tile_1_edges[i] in edges) positions[tile_id_2] = utils.add_vector(positions[tile_id_1], EDGE_TO_VECTOR[edge_1]) orient_tile_to_edge(tile_1, edge_1, tile_2) # Now that positions have been determined, form grid of sub-images dims = utils.add_vector(max(positions.values()), (1, 1)) grid = [ [None for _ in range(dims[1])] for _ in range(dims[0]) ] for tile_id, (i, j) in positions.items(): tile = graph.nodes[tile_id]['tile'] grid[i][j] = tile # Truncate tile borders tile.points = tile.points[1:-1, 1:-1] # Merge truncated tiles into final image return np.vstack([ np.hstack([tile.points for tile in row]) for row in grid ])
def example_spline(): """ """ logg = logging.getLogger(f"c.{__name__}.example_spline") logg.setLevel("INFO") logg.debug(f"Starting example_spline") # create the plot fig, ax = plt.subplots() ax.set_xlim(0, 4) ax.set_ylim(-3, 4) # sample per segment num_samples = 100 # first segment p0 = SPoint(1, 1, 30) # p1 = SPoint(3, 2, 45) p1 = SPoint(2.6, 3, 60) logg.debug(f"p0: {p0} p1: {p1}") # plot the points utils.add_vector(p0, ax, color="k") utils.add_vector(p1, ax, color="k") # compute the spline spline_x, spline_y = compute_spline(p0, p1, ax=ax) # plot the finished spline utils.add_points(spline_x, spline_y, ax, color="y") # plot everything utils.plot_build(fig, ax) plt.show()
def compute_spline(p0, p1, num_samples=100, ax=None): """Compute the cubic spline between two points * translate to the origin and rotate the points to have both on the x axis * compute the spline * rotate and translate to original position """ logg = logging.getLogger(f"c.{__name__}.compute_spline") logg.setLevel("INFO") logg.debug(f"Starting compute_spline") # translate and rotate the point to the origin rot_p0, rot_p1, dir_01 = translate_points_to_origin(p0, p1) # plot the rotated vectors if not ax is None: utils.add_vector(rot_p0, ax, color="r") utils.add_vector(rot_p1, ax, color="r") # compute the spline points coeff = cubic_curve(rot_p0, rot_p1) x_sample, y_segment = compute_segment_points(rot_p0.x, rot_p1.x, coeff) if not ax is None: utils.add_points(x_sample, y_segment, ax, color="g") # rototranslate points to the original position rototran_x, rototran_y = rototranslate_points( x_sample, y_segment, -dir_01, p0.x, p0.y, ) return rototran_x, rototran_y
def part_2(): floor = get_initial_floor() for _ in range(100): black_neighbors = collections.defaultdict(int) for position, color in floor.items(): if color == Color.BLACK: neighbor_colors = [] for vector in VECTORS.values(): neighbor = utils.add_vector(position, vector) neighbor_colors.append(floor.get(neighbor, Color.WHITE)) black_neighbors[neighbor] += 1 if all([color == Color.WHITE for color in neighbor_colors]): black_neighbors[position] = 0 for position, count in black_neighbors.items(): color = floor[position] if color == Color.BLACK and count not in [1, 2]: floor[position] = Color.flip(color) elif color == Color.WHITE and count == 2: floor[position] = Color.flip(color) print(list(floor.values()).count(Color.BLACK))
def get_visible_occupied_seats(self, point): visible_occupied_seats = [] for i in [-1, 0, 1]: for j in [-1, 0, 1]: vector = (i, j) if vector != (0, 0): visible_point = utils.add_vector(point, vector) while self.points.get(visible_point) == PointType.FLOOR: visible_point = utils.add_vector(visible_point, vector) if self.points.get(visible_point) == PointType.OCCUPIED_SEAT: visible_occupied_seats.append(visible_point) return visible_occupied_seats
def checkOptions(self, player, otherPos, rotSeq): currentPos = (self.dict['x'], self.dict['y']) if otherPos == currentPos: options = self.generateCollisionOptions(player) bestDirection = utils.direction((self.dict['x'], self.dict['y']), self.dict['prevpos']) bdpos = utils.round_vector(bestDirection) if utils.magnitude(bdpos) == 0: bdpos = rand.choice(optKeys) if options[bdpos] and player.getRoom().validPosition(utils.add_vector(currentPos, bdpos)): self.dict['x'] += bdpos[0] self.dict['y'] += bdpos[1] return True else: for rot in rotSeq: testvec = utils.rotate(bdpos, rot) testvec = utils.round_vector(testvec) if options[testvec]: self.dict['x'] += testvec[0] self.dict['y'] += testvec[1] return True # if nothing worked -- this could be expanded to do proper step-by-step # checking until invalid self.dict['x'] = self.dict['prevpos'][0] self.dict['y'] = self.dict['prevpos'][1] return True return False
def get_trees_encountered(grid, slope): position = (0, 0) trees = 0 while position[0] < grid.rows: trees += grid[position] == '#' position = utils.add_vector(position, slope) return trees
def rotated_match(scanner_1, scanner_2): for point_1, point_2 in itertools.product(scanner_1, scanner_2): diff = tuple(x - y for x, y in zip(point_1, point_2)) oriented_scanner_2 = Scanner( scanner_2.id, frozenset([utils.add_vector(point, diff) for point in scanner_2]), ) if len(scanner_1.points & oriented_scanner_2.points) >= 12: return oriented_scanner_2, diff return None
def get_initial_floor(): tiles = utils.get_input(__file__, delimiter=None, cast=str) lexer = TileLexer() floor = collections.defaultdict(lambda: Color.WHITE) for tile in tiles: position = (0, 0, 0) for token in lexer.tokenize(tile): position = utils.add_vector(position, VECTORS[token.value]) floor[position] = Color.flip(floor[position]) return floor
def get_label(graph, first_letter): # Either down or right second_letter_vectors = [VECTORS[1], VECTORS[2]] for vector in second_letter_vectors: neighbor = utils.add_vector(first_letter, vector) if is_letter(graph, neighbor): label_position = None candidate_positions = [ utils.add_vector(first_letter, -1 * vector), utils.add_vector(neighbor, vector), ] for position in candidate_positions: if is_empty(graph, position): label_position = position if label_position: label = graph.nodes[first_letter]['value'] + graph.nodes[ neighbor]['value'] return Label(label, label_position, [first_letter, neighbor]) return None
def generateCollisionOptions(self, player): currentPos = (self.dict['x'], self.dict['y']) room = player.getRoom() getRel = lambda x, y : (x.dict['x'] - y.dict['x'], x.dict['y'] - y.dict['y']) relpos = [getRel(x, self) for x in player.getRoom().dict['things']] ppos = room.getPlayerPos(player) relpos.append((ppos[0] - self.dict['x'], ppos[1] - self.dict['y'])) opts = {k:True for k in optKeys} for pos in relpos: if pos in opts: opts[pos] = False for pos in opts: if not room.validPosition(utils.add_vector(currentPos, pos)): opts[pos] = False return opts
def neighbors(self, coordinate): neighbors = [] for vector in VECTORS: neighbor = utils.add_vector(coordinate, vector) val = self.get(neighbor) if val is not None: neighbors.append(val) if not self.recursive: return neighbors i, j, k = coordinate more_neighbors = [] if (i, j) == (2, 1): more_neighbors = itertools.product(range(5), [0], [k + 1]) elif (i, j) == (2, 3): more_neighbors = itertools.product(range(5), [4], [k + 1]) elif (i, j) == (1, 2): more_neighbors = itertools.product([0], range(5), [k + 1]) elif (i, j) == (3, 2): more_neighbors = itertools.product([4], range(5), [k + 1]) else: if i == 0: more_neighbors.append((1, 2, k - 1)) elif i == 4: more_neighbors.append((3, 2, k - 1)) if j == 0: more_neighbors.append((2, 1, k - 1)) elif j == 4: more_neighbors.append((2, 3, k - 1)) for neighbor in more_neighbors: val = self.get(neighbor) if val is not None: neighbors.append(val) return neighbors
def compute_thick_spline(p0, p1, thickness, num_samples=100, ax=None): """Compute the thick cubic spline between two points * translate to the origin and rotate the points to have both on the x axis * compute the spline * make it thicker * rotate and translate to original position """ logg = logging.getLogger(f"c.{__name__}.compute_spline") logg.setLevel("INFO") logg.debug(f"Starting compute_spline") # translate and rotate the point to the origin rot_p0, rot_p1, dir_01 = translate_points_to_origin(p0, p1) logg.debug(f"rot_p0: {rot_p0} rot_p1: {rot_p1}") # compute the normal direction to the vectors np0_ori_rad = rot_p0.ori_rad + pi / 2 np1_ori_rad = rot_p1.ori_rad + pi / 2 # compute the corner points of the thick spline offset_x_0 = cos(np0_ori_rad) * thickness offset_y_0 = sin(np0_ori_rad) * thickness logg.debug(f"offset_x_0: {offset_x_0} offset_y_0: {offset_y_0}") p0t = SPoint(rot_p0.x + offset_x_0, rot_p0.y + offset_y_0, rot_p0.ori_deg) p0b = SPoint(rot_p0.x - offset_x_0, rot_p0.y - offset_y_0, rot_p0.ori_deg) logg.debug(f"p0t: {p0t} p0b: {p0b}") offset_x_1 = cos(np1_ori_rad) * thickness offset_y_1 = sin(np1_ori_rad) * thickness logg.debug(f"offset_x_1: {offset_x_1} offset_y_1: {offset_y_1}") p1t = SPoint(rot_p1.x + offset_x_1, rot_p1.y + offset_y_1, rot_p1.ori_deg) p1b = SPoint(rot_p1.x - offset_x_1, rot_p1.y - offset_y_1, rot_p1.ori_deg) logg.debug(f"p1t: {p1t} p1b: {p1b}") # compute the coeff of the line passing through the points coeff_l = line_curve(p0t, p0b) coeff_r = line_curve(p1t, p1b) logg.debug(f"coeff_l: {coeff_l} coeff_r: {coeff_r}") # compute the spline points coeff_t = cubic_curve(p0t, p1t) coeff_b = cubic_curve(p0b, p1b) x_sample_t, y_segment_t = sample_segment_points(p0t.x, p1t.x, coeff_t) x_sample_b, y_segment_b = sample_segment_points(p0b.x, p1b.x, coeff_b) logg.debug(f"x_sample_t.shape: {x_sample_t.shape}") logg.debug(f"x_sample_b.shape: {x_sample_b.shape}") contour_t, contour_b, x_sample = build_contour( p0t, p0b, p1t, p1b, coeff_l, coeff_r, x_sample_t, y_segment_t, x_sample_b, y_segment_b, ax, ) # compute the top and bottom contours logg.debug(f"x_sample.shape: {x_sample.shape}") logg.debug(f"contour_t.shape: {contour_t.shape}") logg.debug(f"contour_b.shape: {contour_b.shape}") # get the max and min y, aligned on the grid max_y = np.amax(contour_t) min_y = np.amin(contour_b) logg.debug(f"max_y: {max_y} min_y: {min_y}") max_y_aligned = floor(max_y) min_y_aligned = ceil(min_y) logg.debug(f"max_y_aligned: {max_y_aligned} min_y_aligned: {min_y_aligned}") # sample all the points inside the spline, aligned on the grid on_points_x = [] on_points_y = [] for i, x_curr in enumerate(x_sample): for y_curr in range(min_y_aligned, max_y_aligned + 1): if contour_b[i] <= y_curr <= contour_t[i]: on_points_x.append(x_curr) on_points_y.append(y_curr) # rototranslate points to the original position rototran_x, rototran_y = rototranslate_points( on_points_x, on_points_y, -dir_01, p0.x, p0.y, ) # plot everything to debug things if not ax is None: vec_len = 3 ## plot the points utils.add_vector(p0, ax, color="r", vec_len=vec_len) utils.add_vector(p1, ax, color="r", vec_len=vec_len) ## plot the rotated vectors utils.add_vector(rot_p0, ax, color="k", vec_len=vec_len) utils.add_vector(rot_p1, ax, color="k", vec_len=vec_len) ## plot the corner of the spline utils.add_vector(p0t, ax, color="k", vec_len=vec_len) utils.add_vector(p1t, ax, color="k", vec_len=vec_len) utils.add_vector(p0b, ax, color="k", vec_len=vec_len) utils.add_vector(p1b, ax, color="k", vec_len=vec_len) ## plot top and bottom splines # utils.add_points(x_sample_t, y_segment_t, ax, color="b", marker=".", ls="") # utils.add_points(x_sample_b, y_segment_b, ax, color="b", marker=".", ls="") utils.add_points(x_sample_t, y_segment_t, ax, color="r", marker="", ls="-") utils.add_points(x_sample_b, y_segment_b, ax, color="r", marker="", ls="-") ## plot top and bottom contours utils.add_points(x_sample, contour_t, ax, color="r", marker=".", ls="") utils.add_points(x_sample, contour_b, ax, color="r", marker=".", ls="") ## plot on point utils.add_points(on_points_x, on_points_y, ax, color="b", marker=".", ls="") ## plot on point translated back to original position utils.add_points(rototran_x, rototran_y, ax, color="b", marker=".", ls="") return rototran_x, rototran_y
def pre_update(self): pressed = pygame.key.get_pressed() if self.active_rock: self.pannable.pan_to_game_object(self.active_rock) if self.game_state is PRE_GAME: self.p1_score, self.p2_score = 0, 0 self.game_state = PRE_END self.end = 0 if self.game_state is PRE_END: self.end += 1 self.remove_all_rocks() print('just removed all rocks:', self.rocks) self.team = not self.end % 2 self.throws_left = 6 self.update_bottom_panel() self.game_state = PRE_THROW if self.game_state is PRE_THROW: self.start_aim() self.broom.move_to( self.sweeper.rect.move((150, 75 + self.broom_offset)).topleft) if self.game_state is AIMING: if not self.active_rock: self.active_rock = self.add_rock((1000, 500)) # region Aim rot_limit = 3 if up_key_is_pressed( ) and not 180 > self.trajectory.get_rotation() > rot_limit: self.trajectory.rotate(0.1) if down_key_is_pressed( ) and not 180 < self.trajectory.get_rotation() < 360 - rot_limit: self.trajectory.rotate(-0.1) self.mini_trajectory.set_rotation(self.trajectory.get_rotation()) source = (605, 500) if self.trajectory.get_rotation() < 180: self.trajectory.move_to( (source[0], source[1] - self.trajectory.rect.height + 2)) self.mini_trajectory.move_to( (source[0] // 5, source[1] // 5 - self.mini_trajectory.rect.height + 1)) else: self.trajectory.move_to((source[0], source[1] - 2)) self.mini_trajectory.move_to( (source[0] // 5, source[1] // 5 - 1)) traj_pos = self.trajectory.rect.topleft #endregion if self.game_state is THROWING: if self.active_rock.rect.right > 2590: # hog line self.release_rock() if up_key_is_pressed(): self.active_rock.rotvel += 3 if down_key_is_pressed(): self.active_rock.rotvel -= 3 # TODO adjust spin if self.game_state is SWEEPING: sweep_limit = 50 sweep_speed = 3 if up_key_is_pressed() and self.sweeper_offset > -50: self.sweeper_offset -= sweep_speed self.sweeper.move((0, -sweep_speed)) if down_key_is_pressed() and self.sweeper_offset < 50: self.sweeper_offset += sweep_speed self.sweeper.move((0, sweep_speed)) if action_key_is_pressed(): self.active_rock.use_reduced_friction() self.active_rock.vel = utils.add_vector( self.active_rock.vel, (0, math.hypot(*self.active_rock.vel) * self.sweeper_offset / 200000)) self.animate_broom_frame() else: self.active_rock.use_normal_friction() if self.active_rock.rect.right > 9000 or self.active_rock.vel[ 0] < 30: self.deactivate_sweeper() if self.game_state is WATCHING: if self.timer or not (any(r.vel != (0, 0) or r.rotvel for r in self.rocks)): self.timer += 1 if self.timer >= 60: self.timer = 0 if self.throws_left: self.prep_next_throw() else: s = self.get_end_scores() print('last throw happened; here are the rocks') for r in self.rocks: print(r.rect.center, r.team) print() self.p1_score += s[0] self.p2_score += s[1] self.game_state = PRE_END self.update_bottom_panel() # if self.end == 2: # TODO if self.end == 1: self.end_game()