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 draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a6", landscape=self.orient == "landscape") vsk.penWidth(self.pen_width) for j in range(self.num_y): for i in range(self.num_x): if self.mapping == "grad": amt = j / self.num_y color_prob = 1.0 elif self.mapping == "double_grad": amt = abs(j - self.num_y / 2) / self.num_y * 2 color_prob = 1.0 elif self.mapping == "double_grad_inside": amt = 1.0 - abs(j - self.num_y / 2) / self.num_y * 2 color_prob = 1.0 elif self.mapping == "crossover": amt = 1.0 - abs(j - self.num_y / 2) / self.num_y * 2 color_prob = (j / self.num_y - 0.5) * 1.2 + 0.5 elif self.mapping == "circular": amt = 1 - math.hypot(i - self.num_x / 2, j - self.num_y / 2) / max(self.num_x, self.num_y) color_prob = 1.0 elif self.mapping == "circular_crossover": amt = 1 - math.hypot(i - self.num_x / 2, j - self.num_y / 2) / max(self.num_x, self.num_y) color_prob = (j / self.num_y - 0.5) * 1.2 + 0.5 elif self.mapping == "diagonal": amt = 1.0 - abs(1.0 - i / self.num_x - j / self.num_y) color_prob = 1.0 elif self.mapping == "diagonal_crossover": amt = 1.0 - abs(1.0 - i / self.num_x - j / self.num_y) color_prob = vsk.lerp( -0.2, 1.2, (i / self.num_x + j / self.num_y) / 2) elif self.mapping == "stripes": color_prob = math.floor(i / self.num_x * 9) % 2 amt = j / self.num_y if color_prob == 1: amt = 1 - amt elif self.mapping == "circle_grad": if math.hypot(i - self.num_x / 2, j - self.num_y / 2) > 0.4 * min(self.num_x, self.num_y): color_prob = 1.0 amt = j / self.num_y else: color_prob = 0.0 amt = vsk.lerp(-0.5, 1.5, 1 - j / self.num_y) else: raise NotImplementedError prob = vsk.lerp(self.hi_density, self.lo_density, amt) if vsk.random(1.0) < color_prob: vsk.stroke(1) else: vsk.stroke(2) if vsk.random(1.0) < prob: vsk.point(i * self.pitch, j * self.pitch)
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size(self.page_size) width = round((vsk.width - 2 * self.margin) / self.base_pitch) * self.base_pitch height = round((vsk.height - 2 * self.margin) / self.base_pitch) * self.base_pitch mls0 = MultiLineString( [ [(0, y), (width, y)] for y in np.arange(0, height + self.base_pitch, self.base_pitch) ] ) mls1 = MultiLineString( [ [(0, y), (width, y)] for y in np.arange(self.base_pitch / 2, height, self.base_pitch) ] ) mls2 = MultiLineString( [ [(0, y), (width, y)] for y in np.arange(self.base_pitch / 4, height, self.base_pitch / 2) ] ) # build a separation yy = np.linspace(0, height, 100) xx = np.array([vsk.noise(y * 0.002) for y in yy]) * width / 1.8 + 3 * width / 5 - 200 p1 = Polygon(list(zip(xx, yy)) + [(width, height), (width, 0)]) vsk.geometry(mls0) circles = [ Point(vsk.random(0, width), vsk.random(0, height)).buffer( vsk.random(self.min_radius, self.max_radius) ) for _ in range(5) ] all_geom = circles + [p1] itrsct = unary_union( [a.intersection(b) for a, b in itertools.combinations(all_geom, 2)] ) vsk.geometry(mls1.intersection(unary_union(all_geom))) vsk.geometry(mls2.intersection(itrsct))
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a4", landscape=False) vsk.scale("cm") for j in range(self.rows): with vsk.pushMatrix(): for i in range(self.columns): with vsk.pushMatrix(): vsk.rotate(self.fuzziness * 0.03 * vsk.random(-j, j)) vsk.translate( self.fuzziness * 0.01 * vsk.randomGaussian() * j, self.fuzziness * 0.01 * vsk.randomGaussian() * j, ) vsk.rect(0, 0, 1, 1) vsk.translate(1, 0) vsk.translate(0, 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")