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 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 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 draw(self, vsk: vsketch.Vsketch) -> None: vsk.size(self.width, self.height, landscape=self.landscape, center=False) delta = (vsk.height - vsk.width) / (self.M - self.N) margin = (self.M * vsk.width - self.N * vsk.height) / 2 / (self.M - self.N) vsk.stroke(1) vsk.vpype( f"text -p 10 20 -s 25 'cell size = {delta*PX_TO_CM:0.2f}cm / " f"margin = {margin*PX_TO_CM:0.2f}cm' penwidth -l1 3") if delta < 0: vsk.vpype( "text -p 10 55 -s 25 'negative cell size, adjust M and N!!!'") else: vsk.stroke(2) vsk.translate(margin, margin) for i in range(self.N + 1): vsk.line(i * delta, 0, i * delta, self.M * delta) for j in range(self.M + 1): vsk.line(0, j * delta, self.N * delta, j * delta) vsk.vpype("color -l2 #ccc") vsk.stroke(3) vsk.penWidth(3, 3) for i, j in itertools.product(range(self.N + 1), range(self.M + 1)): vsk.point(i * delta, j * delta) vsk.vpype("color -l3 red")
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 draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("5x5cm", landscape=False, center=False) random.seed(vsk.random(1.0)) rays = tuple( Ray( random.randint(1, self.m + 1), random.randint(0, self.n), vsk.random(-0.2, 1.2), 3.0, 0.5, ) for _ in range(100)) time = self.frame / self.frame_count for ray in rays: for time_offset in (-1, 0, 1): start_pos = ((time + time_offset) - ray.start_time) * ray.speed * vsk.width vsk.stroke(ray.x) vsk.line( start_pos, ray.y / self.n * vsk.height, start_pos - ray.length * vsk.width, ray.y / self.n * vsk.height, ) vsk.vpype("crop 0 0 {vp_page_size[0]} {vp_page_size[1]}") vsk.vpype( f"pspread {5/self.m}cm perspective --hfov 100 --pan 90 --move 0 0 -1cm" ) vsk.vpype("lmove all 1")
def finalize(self, vsk: vsketch.Vsketch) -> None: vsk.vpype("linemerge linesimplify reloop linesort")
def finalize(self, vsk: vsketch.Vsketch) -> None: vsk.vpype("linesimplify linesort")
def finalize(self, vsk: vsketch.Vsketch) -> None: vsk.vpype("reloop linesort")
def finalize(self, vsk: vsketch.Vsketch) -> None: vsk.vpype("linesimplify -t 0.001mm linemerge -t 0.5mm")
def finalize(self, vsk: vsketch.Vsketch) -> None: vsk.vpype( "linemerge linesimplify -t 0.01mm reloop linesort -l 4 lmove 4 1")
def draw(self, vsk: vsketch.Vsketch) -> None: print(os.getcwd()) vsk.size("a6", landscape=False, center=False) vsk.scale(1) vsk.penWidth(self.pen_width) glyph_poly = load_glyph(self.font, self.glyph, self.face_index) # normalize glyph size bounds = glyph_poly.bounds scale_factor = min( (vsk.width - 2 * self.glyph_margin) / (bounds[2] - bounds[0]), (vsk.height - 2 * self.glyph_margin) / (bounds[3] - bounds[1]), ) glyph_poly = scale(glyph_poly, scale_factor, scale_factor) bounds = glyph_poly.bounds glyph_poly = translate( glyph_poly, vsk.width / 2 - bounds[0] - (bounds[2] - bounds[0]) / 2, vsk.height / 2 - bounds[1] - (bounds[3] - bounds[1]) / 2 + self.glyph_voffset, ) if self.draw_glyph: vsk.strokeWeight(self.glyph_weight) if self.fill_glyph: vsk.fill(1) vsk.geometry(glyph_poly) if self.fill_glyph and self.glyph_chroma: angle = self.glyph_chroma_angle / 180.0 * math.pi glyph_poly_chroma1 = translate( glyph_poly, -self.glyph_chroma_offset * math.cos(angle), -self.glyph_chroma_offset * math.sin(angle), ).difference(glyph_poly) glyph_poly_chroma2 = translate( glyph_poly, self.glyph_chroma_offset * math.cos(angle), self.glyph_chroma_offset * math.sin(angle), ).difference(glyph_poly) vsk.strokeWeight(1) vsk.stroke(2) vsk.fill(2) vsk.geometry(glyph_poly_chroma1) vsk.stroke(3) vsk.fill(3) vsk.geometry(glyph_poly_chroma2) glyph_poly = unary_union( [glyph_poly, glyph_poly_chroma1, glyph_poly_chroma2]) vsk.strokeWeight(1) vsk.stroke(1) vsk.noFill() glyph_shadow = None if self.glyph_shadow: angle = self.glyph_chroma_angle / 180.0 * math.pi glyph_shadow = translate( glyph_poly, self.glyph_chroma_offset * math.cos(angle), self.glyph_chroma_offset * math.sin(angle), ).difference(glyph_poly) vsk.fill(3) vsk.stroke(3) vsk.geometry(glyph_shadow) vsk.noFill() vsk.stroke(1) glyph_poly = glyph_poly.union(glyph_shadow) if self.glyph_weight == 1: glyph_poly_ext = glyph_poly.buffer( self.glyph_space, join_style=JOIN_STYLE.mitre, ) glyph_poly_int = glyph_poly.buffer( -self.glyph_space_inside, join_style=JOIN_STYLE.mitre, ) else: buf_len = (self.glyph_weight - 1) / 2 * self.pen_width glyph_poly_ext = glyph_poly.buffer( buf_len * 2 + self.glyph_space, join_style=JOIN_STYLE.mitre, ) glyph_poly_int = glyph_poly.buffer( -buf_len - self.glyph_space_inside, join_style=JOIN_STYLE.mitre, ) if glyph_shadow is not None: glyph_poly_int = glyph_poly_int.difference(glyph_shadow) # horizontal stripes if self.draw_h_stripes: count = round( (vsk.height - 2 * self.margin) / self.h_stripes_pitch) corrected_pitch = (vsk.height - 2 * self.margin) / count hstripes = MultiLineString([[ (self.margin, self.margin + i * corrected_pitch), (vsk.width - self.margin, self.margin + i * corrected_pitch), ] for i in range(count + 1)]) vsk.geometry(hstripes.difference(glyph_poly_ext)) if self.h_stripes_inside: inside_stripes = translate(hstripes, 0, corrected_pitch / 2).intersection(glyph_poly_int) vsk.geometry(inside_stripes) if self.h_stripes_inside_chroma: chroma_offset = math.sqrt(2) * self.pen_width vsk.stroke(2) vsk.geometry( translate(inside_stripes, -chroma_offset, -chroma_offset)) vsk.stroke(3) vsk.geometry( translate(inside_stripes, chroma_offset, chroma_offset)) vsk.stroke(1) # concentric if self.draw_concentric: circle_count = int( math.ceil( math.hypot(vsk.width, vsk.height) / 2 / self.concentric_pitch)) circles = unary_union([ Point(vsk.width / 2, vsk.height / 2).buffer( (i + 1) * self.concentric_pitch, resolution=int(1 * (i + 1) * self.concentric_pitch), ).exterior for i in range(circle_count) ]) vsk.geometry( circles.difference(glyph_poly_ext).intersection( box( self.margin, self.margin, vsk.width - self.margin, vsk.height - self.margin, ))) # dots vsk.fill(1) if self.draw_dots or self.draw_cut_circles: v_pitch = self.pitch * math.tan(math.pi / 3) / 2 h_count = int((vsk.width - 2 * self.margin) // self.pitch) v_count = int((vsk.height - 2 * self.margin) // v_pitch) h_offset = (vsk.width - h_count * self.pitch) / 2 v_offset = (vsk.height - v_count * v_pitch) / 2 dot_array = [] for j in range(v_count + 1): odd_line = j % 2 == 1 for i in range(h_count + (0 if odd_line else 1)): dot = Point( h_offset + i * self.pitch + (self.pitch / 2 if odd_line else 0), v_offset + j * v_pitch, ).buffer(self.thickness / 2) if self.draw_dots: if not dot.buffer( self.thickness / 2).intersects(glyph_poly_ext): dot_array.append(dot) else: dot_array.append(dot) dots = unary_union(dot_array) if self.draw_dots: vsk.geometry(dots) if self.draw_cut_circles: if self.cut_circles_inside: op_func = lambda geom: geom.intersection(glyph_poly_int) else: op_func = lambda geom: geom.difference(glyph_poly_ext) vsk.geometry(op_func(dots)) if self.cut_circle_chroma: angle = math.pi / 6 dist = self.pitch * 0.1 vsk.fill(2) vsk.stroke(2) vsk.geometry( op_func( translate(dots, -dist * math.cos(angle), -dist * math.sin(angle)).difference(dots))) vsk.fill(3) vsk.stroke(3) vsk.geometry( op_func( translate(dots, dist * math.cos(angle), dist * math.sin(angle)).difference(dots))) vsk.fill(1) vsk.stroke(1) vsk.stroke(4) # apply line sort, see finalize() if self.draw_dot_matrix: h_count = int( (vsk.width - 2 * self.margin) // self.dot_matrix_pitch) + 1 v_count = int( (vsk.height - 2 * self.margin) // self.dot_matrix_pitch) + 1 h_pitch = (vsk.width - 2 * self.margin) / (h_count - 1) v_pitch = (vsk.height - 2 * self.margin) / (v_count - 1) mp = MultiPoint([ (self.margin + i * h_pitch, self.margin + j * v_pitch) for i, j in itertools.product(range(h_count), range(v_count)) if vsk.random(1) < self.dot_matrix_density ]) if self.draw_dot_matrix_inside: mp = mp.intersection(glyph_poly_int) else: mp = mp.difference(glyph_poly_ext) vsk.geometry(mp) vsk.vpype("color -l4 black") vsk.vpype("color -l1 black color -l2 cyan color -l3 magenta")