def test_canvas_shapes4(self): b0 = Blok([Point(10, 11), Point(12, 13), Point(13, 11)]) nb0 = Blok([Point(5, 5), Point(5, 8), Point(8, 9), Point(7, 5)]) b1 = Blok([Point(10, 11), Point(12, 13), Point(13, 11)]) shape_b0 = PolygonShape(b0.points, style=Style(color='green')) shape_b1 = PolygonShape(b1.points, style=Style(color='blue')) shape_nb0 = PolygonShape(nb0.points, style=Style(color='red')) shape_c1 = CompositeShape([shape_b0, shape_nb0]) cv = Canvas(width=20, height=20, nrows=4, ncols=4) for r in range(4): for c in range(4): box = cv.get_box_for_cell(r, c) if r == 3 and c == 3: cv = Canvas.add_shape2(cv, shape_b1, box, label=f"({str(r)},{str(c)})") else: cv = Canvas.add_shape2(cv, shape_c1, box, label=f"({str(r)},{str(c)})") with open('canvas4.svg', 'w') as fd: Canvas.render_as_svg(cv, file=fd)
def bounding_box(self: CompositeShape) -> Box: bbs = [s.bounding_box() for s in self.shapes] minx = min([b.minx() for b in bbs]) miny = min([b.miny() for b in bbs]) maxx = max([b.maxx() for b in bbs]) maxy = max([b.maxy() for b in bbs]) return (Box(Point(minx, miny), Point(maxx, maxy)))
def add_shape3(c: Canvas, shape: Shape, container_box: Box, super_shape_box: Box, outline: bool = True, margin_percent: float = 0.2, label: str = None) -> Canvas: shape_box = super_shape_box width_margin = container_box.width() * margin_percent height_margin = container_box.height() * margin_percent inner_box = Box( Point(container_box.lower_left_pt.x + width_margin / 2, container_box.lower_left_pt.y + height_margin / 2), Point(container_box.upper_right_pt.x - height_margin / 2, container_box.upper_right_pt.y - height_margin / 2)) scalex = inner_box.width() / (shape_box.width()) scaley = inner_box.height() / (shape_box.height()) scalexy = min([scalex, scaley]) scaled_shape = shape.scale(xfactor=scalexy, yfactor=scalexy) scaled_shape_box = scaled_shape.bounding_box() translation_amt = diff(inner_box.lower_left_pt, scaled_shape_box.lower_left_pt) translated_shape = scaled_shape.translate(translation_amt) outline_shape = [] if outline: outline_shape.append( PolygonShape(container_box.get_path(), label=label)) nc = Canvas(c.shapes + [translated_shape] + outline_shape, c.lines, c.viewBoxHeight, c.viewBoxWidth, c.num_rows, c.num_cols) return nc
def test_rearrange(self): points = [Point(0, 0), Point(0, 2), Point(2, 2), Point(2, 0)] print(f"orig: {points}") for i in range(len(points)): pt = points[i] rearr = rearrange_origin(points, pt) print(f"rearr({i}): {rearr}")
def test_rotate(self): """Test some sample rotations""" point = Point(8, 10) around = Point(7, 7) self.assertEqual(point.rotate(around=around, degrees=90), Point(10, 6)) self.assertEqual(point.rotate(around=around, degrees=180), Point(6, 4)) self.assertEqual(point.rotate(around=around, degrees=270), Point(4, 8)) self.assertEqual(point.rotate(around=around, degrees=-90), Point(4, 8))
def get_box_for_cell(self, cell_row_, cell_col_): rhgt = self.viewBoxHeight / self.num_rows cwdth = self.viewBoxWidth / self.num_cols # cell_row = cell_row_ cell_col = cell_col_ cell_row = self.num_rows - cell_row_ - 1 #cell_col = self.num_cols - cell_col_ -1 return Box(Point(cwdth * cell_col, rhgt * cell_row), Point(cwdth * (cell_col + 1), rhgt * (cell_row + 1)))
def get_path(self): minx = self.minx() miny = self.miny() maxx = self.maxx() maxy = self.maxy() return [ Point(minx, miny), Point(minx, maxy), Point(maxx, maxy), Point(maxx, miny) ]
def test_determinent(self): a = Point(0, 0) b = Point(1, 0) c = Point(1, 1) d = Point(0, 1) print(is_path_clockwise(c, b, a)) print(is_path_clockwise(a, b, c)) print(is_path_clockwise(a, d, c)) print(is_path_clockwise(c, d, a)) print(is_path_clockwise(b, a, c)) print(is_path_clockwise(c, a, b))
def I3(cls, origin: Point) -> "Shape": # pylint: disable=invalid-name """ Return the I3 shape. [X][ ][ ] """ points = { origin, Point(x=origin.x + 1, y=origin.y), Point(x=origin.x + 2, y=origin.y), } return Shape(origin=origin, points=points)
def test_align_block1(self): b1 = Blok([Point(0, 0), Point(0, 2), Point(2, 2), Point(2, 0)]) b2 = Blok.translate(b1, 4, 4) b3 = Blok.rotate(b2, b2.points[0], math.pi / 4) print(f"b1: {b1}") print(f"b3: {b3}") for i in range(4): print(f"{i}:") for j in range(4): orig, aligned = Blok.align_blocks_on_edge(b1, i, b3, j) print(f"aligned edge {i} {j}: {aligned}")
def test_simple_reflection(self): """Test reflecting a shape containing a single point""" origin = Point(4, 4) x_value, y_value = 7, 6 shape = Shape.I1(origin) self.assertEqual( shape.reflect(x=x_value).origin, origin.reflect(x=x_value)) self.assertEqual( shape.reflect(y=y_value).origin, origin.reflect(y=y_value)) self.assertEqual( shape.reflect(x=x_value, y=y_value).origin, origin.reflect(x=x_value, y=y_value), )
def T4(cls, origin: Point) -> "Shape": # pylint: disable=invalid-name """ Return the T4 shape. [ ] [ ][X][ ] """ points = { origin, Point(x=origin.x - 1, y=origin.y), Point(x=origin.x + 1, y=origin.y), Point(x=origin.x, y=origin.y + 1), } return Shape(origin=origin, points=points)
def test_w_sides(self): """Test returning the sides of the W shape""" shape = Shape.W(Point(5, 5)) sides = { Point(3, 4), Point(4, 3), Point(4, 5), Point(5, 3), Point(5, 6), Point(6, 4), Point(6, 7), Point(7, 5), Point(7, 6), } self.assertEqual(shape.sides(), sides)
def test_canvas_shapes3(self): b0 = Blok([Point(10, 11), Point(12, 13), Point(13, 11)]) nb0 = Blok.normalize(b0) shape_b0 = PolygonShape(b0.points, style=Style(color='green')) shape_nb0 = PolygonShape(nb0.points, style=Style(color='red')) shape_c1 = CompositeShape([shape_b0, shape_nb0]) cv = Canvas(width=20, height=20, nrows=4, ncols=4) for r in range(4): for c in range(4): box = cv.get_box_for_cell(r, c) cv = Canvas.add_shape2(cv, shape_c1, box) with open('canvas3.svg', 'w') as fd: Canvas.render_as_svg(cv, file=fd)
def translate(b: Blok, x: float, y: float) -> Blok: moved_points = list(map(lambda p: Point.translate(p, x, y), b.points)) component_blocks = None if b.component_blocks: component_blocks = [ Blok.translate(cb, x, y) for cb in b.component_blocks ] return Blok(moved_points, component_blocks)
def test_rotate_identity(self): """Test rotating a point over itself""" point = Point(4, 4) around = Point(4, 4) rotation = Point(4, 4) self.assertEqual(point.rotate(around=around, degrees=0), rotation) self.assertEqual(point.rotate(around=around, degrees=90), rotation) self.assertEqual(point.rotate(around=around, degrees=180), rotation) self.assertEqual(point.rotate(around=around, degrees=270), rotation)
def test_w_corners(self): """Test returning the corners of the W shape""" shape = Shape.W(Point(5, 5)) corners = { Point(3, 3), Point(3, 5), Point(4, 6), Point(5, 7), Point(6, 3), Point(7, 4), Point(7, 7), } self.assertEqual(shape.corners(), corners)
def test_is_side(self): """Test identifying whether two points are sides of each other""" first, second, third = Point(4, 4), Point(5, 5), Point(4, 5) self.assertTrue(first.is_side(third)) self.assertTrue(third.is_side(second)) self.assertFalse(first.is_side(second)) self.assertFalse(second.is_side(first))
def test_w_reflection(self): """Test reflecting the W shape""" origin = Point(5, 5) shape = Shape.W(origin) shape = shape.reflect(x=8) points = { Point(12, 4), Point(11, 4), Point(11, 5), Point(10, 5), Point(10, 6) } self.assertEqual(shape.points, points) self.assertEqual(shape.origin, Point(11, 5))
def flip_point_func(edge: Edge): # a little helper function that will return a # function that can be applied to a set of points to flip those # points to the other side of an edge acting as a reflection line a = edge.start_pt b = edge.end_pt (x2, y2) = (a.x, a.y) (x3, y3) = (b.x, b.y) m = (y3 - y2) / (x3 - x2) c = (x3 * y2 - x2 * y3) / (x3 - x2) m2 = (1 + m**2) return lambda p: Point( 2 * ((p.x + (p.y - c) * m) / m2) - p.x, 2 * ((p.x + (p.y - c) * m) / m2) * m - p.y + 2 * c)
def test_simple_rotation(self): """Test rotating a shape containing a single point""" origin = Point(4, 4) around = Point(7, 6) shape = Shape.I1(origin) self.assertEqual( shape.rotate(around, 90).origin, origin.rotate(around, 90)) self.assertEqual( shape.rotate(around, 180).origin, origin.rotate(around, 180)) self.assertEqual( shape.rotate(around, 270).origin, origin.rotate(around, 270))
def test_w_rotation(self): """Test rotating the W shape""" origin = Point(5, 5) shape = Shape.W(origin) shape = shape.rotate(around=shape.origin, degrees=180) points = { Point(5, 5), Point(6, 6), Point(4, 4), Point(4, 5), Point(5, 6) } self.assertEqual(shape.points, points) self.assertEqual(shape.origin, origin)
def test_canvas_shapes2(self): b0 = Blok([Point(10, 11), Point(12, 13), Point(13, 11)]) nb0 = Blok.normalize(b0) c1 = Canvas(width=20, height=20) shape_b0 = PolygonShape(b0.points, style=Style(color='green')) shape_nb0 = PolygonShape(nb0.points, style=Style(color='red')) shape_c1 = CompositeShape([shape_b0, shape_nb0]) c1 = Canvas.add_shape(c1, shape_c1) box = Box(Point(10, 0), Point(20, 10)) c2 = Canvas.add_shape2(c1, shape_c1, box) c3 = Canvas.add_shape2(c2, shape_c1, Box(Point(10, 10), Point(12, 12))) with open('canvas2.1.svg', 'w') as fd: Canvas.render_as_svg(c3, file=fd)
def test_canvas_shapes(self): b0 = Blok([Point(10, 11), Point(12, 13), Point(13, 11)]) nb0 = Blok.normalize(b0) c1 = Canvas(width=20, height=20) shape_b0 = PolygonShape(b0.points) shape_nb0 = PolygonShape(nb0.points, style=Style(color='red')) bbox = shape_nb0.bounding_box() path = bbox.get_path() shape_bb = PolygonShape(path, style=Style(color='blue')) c2 = Canvas.add_shape(c1, shape_b0) c3 = Canvas.add_shape(c2, shape_nb0) c4 = Canvas.add_shape(c3, shape_bb) box = Box(Point(10, 0), Point(20, 10)) c5 = Canvas.add_shape2( c4, PolygonShape(nb0.points, style=Style(color='green')), box) box2 = Box(Point(10, 10), Point(20, 20)) c6 = Canvas.add_shape2( c5, PolygonShape(nb0.points, style=Style(color='yellow')), box2) with open('canvas1.svg', 'w') as fd: Canvas.render_as_svg(c6, file=fd)
def get_bounding_box(self: Blok) -> Box: minx = min([p.x for p in self.points]) miny = min([p.y for p in self.points]) maxx = max([p.x for p in self.points]) maxy = max([p.y for p in self.points]) return (Box(Point(minx, miny), Point(maxx, maxy)))
def get_edge(b: Blok, ei: int) -> Edge: p0 = b.points[ei % b.num_edges] p1 = b.points[(ei + 1) % b.num_edges] return Edge(Point(p0.x, p0.y), Point(p1.x, p1.y))
def create_from_nparray(nparray: np.ndarray) -> Blok: return Blok([Point(p[0], p[1]) for p in nparray])
FC = BC * math.sin(pent_angle) BF = BC * math.cos(pent_angle) FO = r - BF A = (-FC, FO) B = (0.0, r) C = (FC, FO) D = (ND, -ON) E = (-ND, -ON) return [A, B, C, D, E] if __name__ == '__main__': SQUARE = [ Point(0.0, 0.0), Point(1.0, 0.0), Point(1.0, 1.0), Point(0.0, 1.0) ] TRIANGLE = [ Point(0.0, 0.0), Point(0.5, (1 / 2) * math.sqrt(3)), Point(1.0, 0.0) ] ISOTRIANGLE = [Point(0.0, 0.0), Point(1.0, 1.0), Point(1.0, 0.0)] PENTAGON = [Point(x, y) for (x, y) in pentagon(1.0)] h = math.sin(math.pi / 3.0) hex = [(-0.5, -h), (-1, 0), (-0.5, h), (0.5, h), (1, 0), (0.5, -h)] HEXAGON = [Point(x, y) for (x, y) in hex]
def translate(self: PolygonShape, pt: Point) -> PolygonShape: translated = [Point(p.x + pt.x, p.y + pt.y) for p in self.points] return PolygonShape(translated, self.label, self.style)
def scale(self: PolygonShape, xfactor: float, yfactor: float) -> PolygonShape: scaled = [Point(p.x * xfactor, p.y * yfactor) for p in self.points] return PolygonShape(scaled, self.label, self.style)