def render(maze: Maze, solution: Solution = None, filename=None): lw = ImageMazeRenderer.line_width dlw = 2 * lw def convert(maze_coord): return dlw * maze_coord + dlw img_size = convert(maze.n) + lw image = Image.new('RGB', (img_size, img_size), color='black') drawer = ImageDraw.Draw(image) def as_box(e: Edge): xr = {convert(vtx.x) for vtx in e.v} yr = {convert(vtx.y) for vtx in e.v} return min(xr), min(yr), max(xr) + 1, max(yr) + 1 def draw(*edges, color='white'): for e in edges: drawer.rectangle(as_box(e), fill=color) entrance = Edge(Vertex(-1, 0), Vertex(0, 0)) the_exit = Edge(Vertex(maze.n - 1, maze.n - 1), Vertex(maze.n, maze.n - 1)) draw(*maze.get_all_edges()) draw(entrance, the_exit) if solution: solution_color = 'limegreen' draw(*solution.edges, color=solution_color) draw(entrance, the_exit, color=solution_color) image.save(build_output_path('jpg', file_name=filename), 'JPEG')
class Direction(Enum): NORTH = lambda v: Vertex(v.x, v.y + 1) EAST = lambda v: Vertex(v.x + 1, v.y) SOUTH = lambda v: Vertex(v.x, v.y - 1) WEST = lambda v: Vertex(v.x - 1, v.y) def __call__(self, *args, **kwargs): return self(args[0])
def make_triangle(poly_id, initial_vertex_id): db.session.add(Poly(poly_id=poly_id)) db.session.commit() x2 = random() y2 = random() next_id = None vertex_id = initial_vertex_id for i in range(3): x1 = random() y1 = random() vertex = Vertex(vertex_id=vertex_id, poly_id=poly_id, x1=x1, y1=y1, x2=x2, y2=y2, next_id=next_id) db.session.add(vertex) db.session.commit() x2 = x1 y2 = y1 next_id = vertex_id vertex_id += 1
def _get_neighbours(self, vtx: Vertex): adj = [] for delta in [[0, 1], [0, -1], [1, 0], [-1, 0]]: adj.append(Vertex(vtx.x + delta[0], vtx.y + delta[1])) if not self.maze.contains(adj[-1]): del adj[-1] return adj
def _canvas_left_click(self, event): if not self._scene or not self._current_layer: return x, y = self._canvas.window_to_canvas_coords(event.x, event.y) if self._is_drawing_polygon: polygon = self._current_layer.get_polygon_at(-1) # Move vtx away from mouse to not interfere with search for closest polygon.get_vertex_at(-1).\ set_coords(x-self.SNAP_RADIUS, y-self.SNAP_RADIUS) closest_vertex = self._current_layer.get_closest_vertex( x, y, self.SNAP_RADIUS) if closest_vertex: polygon.remove_vertex_at(-1) if closest_vertex is polygon.get_vertex_at(0): self._is_drawing_polygon = False else: polygon.add_vertex(closest_vertex) polygon.add_vertex(Vertex(x, y)) else: polygon.get_vertex_at(-1)\ .set_coords(x, y) polygon.add_vertex(Vertex(x, y)) self._canvas.notify_polygon_change( self._current_layer.get_polygon_count() - 1) else: # Create start vertex or use already existing one start_vertex = self._current_layer\ .get_closest_vertex(x, y, self.SNAP_RADIUS) if not start_vertex: start_vertex = Vertex(x, y) # Vertex for mouse cursor next_vertex = Vertex(x, y) self._current_layer.add_polygon( Polygon([start_vertex, next_vertex])) self._is_drawing_polygon = True self._canvas.notify_layer_change()
def __init__(self, maze: Maze): self.loops_count = 0 visited = set() stack = deque() def visit(vtx, prev): if vtx in visited: self.loops_count += 1 return visited.add(vtx) for nxt in maze.get_accessible_neighbours(vtx): if nxt != prev: stack.append((nxt, vtx)) stack.append((Vertex(0, 0), Vertex(0, 0))) while stack: visit(*stack.pop())
def _read_vertex(self): x, y, z = struct.unpack("<3h", self.data.read(2 * 3)) vertex = Vertex(x, y, z, self.current_group) # scale the models vertex.r /= 4096 grp_index = struct.unpack("<H", self.data.read(2))[0] if grp_index == 1: self.current_group += 1 return vertex
def read(path: str) -> Scene: zipfile = ZipFile(path, 'r') # Read data data_file = zipfile.open('data.json', 'r') if not data_file: zipfile.close() return None json_scene = json.loads(data_file.read().decode("utf-8")) data_file.close() try: scene = Scene(json_scene["width"], json_scene["height"]) except KeyError: zipfile.close() return None if "layers" in json_scene: for i in range(0, len(json_scene["layers"])): json_layer = json_scene["layers"][i] name = "Layer " + str(i) if "name" in json_layer: name = json_layer["name"] try: layer = ImageLayer( name, json_layer["x"], json_layer["y"], Image.open(BytesIO(zipfile.read(json_layer["image"])))) except KeyError: # TODO Find out about image loading errors continue vertices = list() if "vertices" in json_layer: for json_vertex in json_layer["vertices"]: try: vertices.append( Vertex(json_vertex["x"], json_vertex["y"])) except KeyError: pass if "polygons" in json_layer: for json_polygon in json_layer["polygons"]: polygon = Polygon() for index in json_polygon: polygon.add_vertex(vertices[index]) layer.add_polygon(polygon) scene.add_layer(layer) zipfile.close() return scene
def generate(self): stack = deque([Vertex(0, 0)]) visited = set() def dive(vtx): visited.add(vtx) next_candidates = [n for n in self._get_neighbours(vtx) if n not in visited] if not next_candidates: return nxt = self.random.choice(next_candidates) self.maze.add_edge(Edge(vtx, nxt)) stack.append(nxt) dive(nxt) while stack: dive(stack.pop()) return self.maze
def apply_to_model(self, model): """\ Produces a new model with the rotation and translation applied to the correct vertex groups. """ verts = model.verts norms = model.norms # transform all verts and norms newverts = [] newnorms = [] for i in range(len(verts)): group = verts[i].group sf = self.subframes[group] rot_matrix = sf.rot.as_dcm() v_rotated = verts[i].r.dot(rot_matrix) v_rotated += sf.trans newvert = Vertex(v_rotated[0], v_rotated[1], v_rotated[2], group) n_rotated = norms[i].r.dot(rot_matrix) newnorm = Normal(n_rotated[0], n_rotated[1], n_rotated[2], group) newverts.append(newvert) newnorms.append(newnorm) return Model(newverts, newnorms, model.faces[:], model.groups)
def _create_vertices(self): return [Vertex(j, self.i) for j in range(self.maze_gen.maze.n)]