def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a6", landscape=False) doc = execute( "msrandom -ms -q 0.01mm -n 5 10 module_sets/ms_neon_v1 linemerge -t 0.5mm " "layout -m 2cm a6 ") for line in doc.layers[1]: line = vp.interpolate(line, step=0.1) if not self.liquify: vsk.polygon(line) continue perlin_x = vsk.noise(self.freq * line.real, self.freq * line.imag, grid_mode=False) perlin_y = vsk.noise( self.freq * line.real, self.freq * line.imag, 1000 * np.ones_like(line.real), grid_mode=False, ) line += self.ampl * 2.0 * ((perlin_x - 0.5) + (perlin_y - 0.5) * 1j) vsk.polygon(line) vsk.vpype("linesimplify -t 0.005mm")
def test_square_default_success(vsk: vsketch.Vsketch) -> None: vsk.square(2, 2, 2.5) assert line_count_equal(vsk, 1) assert line_exists(vsk, np.array( [2 + 2j, 4.5 + 2j, 4.5 + 4.5j, 2 + 4.5j, 2 + 2j]), strict=False)
def test_polygon_1arg_success( vsk: vsketch.Vsketch, data: Iterable[Sequence[float]], expected: Sequence[complex] ) -> None: # polygon() with a single arg, polygon should accept an iterable of 2-size iterable vsk.polygon(data) assert line_count_equal(vsk, 1) assert line_exists(vsk, np.array(expected, dtype=complex))
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("10in", "10in") for row in range(self.row_count): for col in range(self.column_count): x = col * self.column_offset y = row * self.row_offset bug(vsk, x, y)
def test_polygon_2args_fail(vsk: vsketch.Vsketch) -> None: # wrong array dimensions with pytest.raises(ValueError): vsk.polygon(np.random.rand(5, 2), np.random.rand(5, 2)) # wrong array content with pytest.raises(ValueError): vsk.polygon(["red", "blue"], [1, 2]) # type: ignore
def test_rect_mode_success( vsk: vsketch.Vsketch, data: Tuple[float, float, float, float], mode: str, expected: Sequence[float], ) -> None: vsk.rect(*data, mode=mode) # type: ignore assert line_count_equal(vsk, 1) assert line_exists(vsk, np.array(expected, dtype=complex), strict=False)
def test_quad_arg(vsk: vsketch.Vsketch) -> None: # vsk.quad() expects exactly 8 args with pytest.raises(TypeError): # noinspection PyArgumentList vsk.quad(0.5, 2, 3, 3) # type: ignore with pytest.raises(TypeError): # noinspection PyTypeChecker vsk.quad("hey", 3, 5, 2.5, 2.5, 6, 3, 2) # type: ignore
def test_triangle_arg(vsk: vsketch.Vsketch) -> None: # vsk.triangle() expects exactly 6 args with pytest.raises(TypeError): # noinspection PyArgumentList vsk.triangle(2, 2, 2, 4, 3) # type: ignore with pytest.raises(TypeError): # noinspection PyTypeChecker vsk.triangle("hey", 3, 3, 5, 5, 4) # type: ignore
def test_arc_close_success( vsk: vsketch.Vsketch, data: Tuple[float, float, float, float, float, float], close: str, expected: Sequence[float], ) -> None: vsk.detail(0.01) vsk.arc(*data, close=close) assert line_count_equal(vsk, 1) assert bounds_equal(vsk, *expected)
def test_ellipse_mode_success( vsk: vsketch.Vsketch, data: Tuple[float, float, float, float], mode: str, expected: Tuple[float, float, float, float], ) -> None: vsk.detail(0.01) vsk.ellipse(*data, mode=mode) assert line_count_equal(vsk, 1) assert bounds_equal(vsk, *expected)
def draw_text( vsk: vsketch.Vsketch, lines: List[str], pos: Tuple[float, float], line_offset: float, text_size: float, ) -> None: for i, line in enumerate(lines): vsk.vpype( f"text -l 1 -s {text_size} -p {pos[0]}cm {pos[1] + i * line_offset}cm '{line}'" )
def test_arc_bad_args(vsk: vsketch.Vsketch) -> None: with pytest.raises(TypeError): vsk.arc(2, 3, mode="radius") # type: ignore with pytest.raises(ValueError): vsk.arc(2, 3, 1, 1, 0, 120, close="yes") with pytest.raises(ValueError): vsk.arc(2, 3, 1, 1, 0, -30, mode="jumbo") with pytest.raises(ValueError): vsk.arc(2, 3, 1, 1, 30, 30)
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a5", landscape=False) # Create some drawings in a sub-sketch sub = vsketch.Vsketch() sub.scale("cm") sub.rect(1, 1, 3, 4) sub.circle(6, 6, 2) sub.bezier(2.5, 3, 5, 2, 1, 7, 6, 6) # Iterate over the sub-sketch lines for line in sub.document.layers[1]: line = vp.interpolate(line, self.quantization) for i in range(math.floor(len(line) / self.dash_steps)): if i % 2 == 1: continue vsk.polygon(line[i * self.dash_steps:(i + 1) * self.dash_steps])
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a4", landscape=True) vsk.scale(2) make_bundle(vsk, (0, 0), (0.45, 0.45), self.k, self.freq, self.freq2) vsk.stroke(2) make_bundle(vsk, (300, 0), (-0.45, 0.45), self.k, self.freq, self.freq2) vsk.stroke(3) make_bundle(vsk, (500, 300), (-0.60, -0.3), self.k, self.freq, self.freq2)
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a4", landscape=False, center=False) vsk.scale(2) y_coords = np.linspace(0.0, 250.0, self.num_lines) x_coords = np.linspace(0.0, 250.0, 500) perlin = vsk.noise(x_coords * 0.1, y_coords * 0.2) x_factor = 0.5 * (1.0 - np.cos(x_coords / 250.0 * 2 * np.pi)) y_factor = 0.5 * (1.0 - np.cos(y_coords / 250.0 * 2 * np.pi)) for j, y in enumerate(y_coords): vsk.polygon(x_coords, y + perlin[:, j] * 12 * y_factor[j] * x_factor) vsk.vpype("layout -h center -v top a4 translate 0 3.8cm")
def test_ellipse_bad_args(vsk: vsketch.Vsketch) -> None: with pytest.raises(TypeError): vsk.ellipse(0.5, 3, mode="radius") # type: ignore with pytest.raises(TypeError): vsk.ellipse("hey", 2, 0.5, 4) # type: ignore with pytest.raises(ValueError): vsk.ellipse(2, 2, 1, 3, mode="jumbo")
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a4", landscape=False) vsk.scale("cm") flags = "" if self.invert_image: flags += "i" if self.delete_white: flags += "d" flags += "a" * self.outline_alpha if flags != "": flags = "-" + flags cmd = re.sub( r"\s+", " ", f""" variablewidth -s {self.image_scale} -p {self.pitch}mm -pw {self.pen_width}mm -bl {self.black_level} -wl {self.white_level} {flags} images/"{self.fish_image}.png" """, ) print(cmd) vsk.vpype(cmd)
def test_circle_bad_args(vsk: vsketch.Vsketch) -> None: with pytest.raises(ValueError): vsk.circle(0, 0) # type: ignore with pytest.raises(ValueError): vsk.circle(0, 0, radius=10, diameter=20) with pytest.raises(ValueError): vsk.circle(2, 2, 5, mode="jumbo")
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("10in", "10in") vsk.scale("3mm") i = 0 for i, prime in enumerate(get_primes(self.N)): vsk.circle(0, 0, 2 * (i + 1)) if self.random_phase: phase = np.random.random() * 2 * math.pi else: phase = -math.pi / 2 for angle in np.linspace(0, 2 * math.pi, prime, endpoint=False): vsk.line( (i + 1) * math.cos(angle + phase), (i + 1) * math.sin(angle + phase), (i + 2) * math.cos(angle + phase), (i + 2) * math.sin(angle + phase), ) vsk.circle(0, 0, 2 * (i + 2))
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a4", landscape=True) vsk.scale("cm") x_coords = np.linspace(0, 25, 1000) perlin = vsk.noise( x_coords * self.x_freq, np.arange(self.num_line) / self.num_line * self.y_freq) for i in range(self.num_line): y_coords = perlin[:, i] + self.y_offset / self.num_line * i vsk.polygon(x_coords, y_coords)
def test_square_arg(vsk: vsketch.Vsketch) -> None: # vsk.square() expects exactly 6 args with pytest.raises(TypeError): # noinspection PyArgumentList vsk.square(0.5, 2) # type: ignore with pytest.raises(TypeError): # noinspection PyTypeChecker vsk.square("hey", 3, 5) # type: ignore with pytest.raises(ValueError): vsk.square(2, 2, 2.5, mode="jumbo")
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a4", landscape=False) vsk.scale("4mm") for i in range(5): for j in range(7): shape = unary_union( [ Point(*np.random.random(2) * 5).buffer(np.random.random()) for _ in range(15) ] ) vsk.geometry(translate(shape, i * 8, j * 8))
def test_rect_arg_fail(vsk: vsketch.Vsketch) -> None: # vsk.rect() expects 3 float args + optional `h` float and `mode` arg with pytest.raises(TypeError): # noinspection PyArgumentList vsk.rect(0, 4, mode="corners") # type: ignore with pytest.raises(TypeError): # noinspection PyTypeChecker vsk.rect("hey", 0, 2.5, 4) # type: ignore # vsk.rect() expects `mode` parameter to be one of "corner", "corners", "center", "radius" with pytest.raises(ValueError): vsk.rect(0, 0, 2, 4, mode="jumbo")
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a6", landscape=True, center=False) vsk.scale("cm") address = ADDRESSES[self.addr_id].split("\n") if not self.address_only: vsk.line(8, 0.5, 8, 10) vsk.rect(12.5, 0.5, 1.8, 2.2) self.draw_text( vsk, HEADER.split("\n"), (0.5, 0.8), self.header_line_spacing, self.header_font_size, ) # deal with abbreviated first name name_line = address[0].split(" ") if len(name_line) > 2 and len(name_line[1]) > len(name_line[0]): name = name_line[1] else: name = name_line[0] self.draw_text( vsk, MESSAGE.replace("$FirstName$", name).split("\n"), (0.5, self.message_y_offset), self.message_line_spacing, self.message_font_size, ) self.draw_text( vsk, address, (8.5, self.address_y_offset), self.address_line_spacing, self.address_font_size, )
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a6", landscape=False) vsk.scale(self.scale_factor) vsk.rotate(self.rotation, degrees=True) N = 20 angles = np.array(random.sample(range(N), self.segment_count), dtype=float) angles *= 2 * math.pi / N x = np.cos(angles) y = np.sin(angles) speeds = np.random.uniform(-1, 1, (self.segment_count, 2)) speeds *= self.delta / np.hypot(speeds[:, 0], speeds[:, 1]).reshape( -1, 1) for _ in range(self.line_count): vsk.polygon(x, y) x += speeds[:, 0] y += speeds[:, 1]
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a4", landscape=False) vsk.scale("cm") t = np.arange(self.N) * self.freq perlin = vsk.noise(t, np.arange(8) * 1000) for i in range(self.N): v = i * self.drift vsk.bezier( perlin[i, 0] * 10 + v, perlin[i, 1] * 10 + v, perlin[i, 2] * 10 + v, perlin[i, 3] * 10 + v, perlin[i, 4] * 10 + v, perlin[i, 5] * 10 + v, perlin[i, 6] * 10 + v, perlin[i, 7] * 10 + v, )
def draw(self, vsk: vsketch.Vsketch) -> None: if self.override_page_size: vsk.size(f"{self.page_width}x{self.page_height}") else: vsk.size(self.page_size, landscape=False) vsk.stroke(1) vsk.fill(1) for i, (y, x) in enumerate( itertools.product(range(self.row_count), range(self.column_count))): pw = self.smallest_width_mm + i * self.width_increment_mm vsk.penWidth(f"{pw}mm", 1) vsk.rect( x * self.horizontal_offset, y * self.vertical_offset, self.box_width, self.box_height, ) vsk.text( f"{pw:.3}mm", x * self.horizontal_offset + self.box_width / 2, y * self.vertical_offset + self.box_height + vpype.convert_length("0.5cm"), mode="label", align="center", size=12, )
def finalize(self, vsk: vsketch.Vsketch) -> None: vsk.vpype("linemerge linesimplify reloop linesort")
def test_rect_default_success(vsk: vsketch.Vsketch) -> None: vsk.rect(0, 0, 2, 4) assert line_count_equal(vsk, 1) assert line_exists(vsk, np.array([0, 2, 2 + 4j, 4j, 0], dtype=complex), strict=False)
def test_rect_round_corners_success( vsk: vsketch.Vsketch, data: Sequence[float], expected: Tuple[float, float, float, float]) -> None: vsk.rect(*data) # type: ignore assert line_count_equal(vsk, 1) assert bounds_equal(vsk, *expected)