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(self.page_size, landscape=self.landscape) vsk.penWidth("0.5mm") # obtain the datafile file_name = self.category + ".bin" file_path = pathlib.Path(file_name) url = "https://storage.googleapis.com/quickdraw_dataset/full/binary/" url += file_name.replace(" ", "%20") if not file_path.exists(): urllib.request.urlretrieve(url, file_name) # extract some drawings drawing_set = unpack_drawings(file_name) drawing_subset = list(islice(drawing_set, 10000)) # draw stuff width = vsk.width - 2 * self.margins height = vsk.height - 2 * self.margins n = self.columns * self.rows samples = random.sample(drawing_subset, n) for j in range(self.rows): with vsk.pushMatrix(): for i in range(self.columns): idx = j * self.columns + i with vsk.pushMatrix(): vsk.scale(self.scale_factor * min(1 / self.columns, 1 / self.rows)) drawing = quickdraw_to_linestring(samples[idx]) vsk.stroke((idx % self.layer_count) + 1) vsk.geometry(drawing) vsk.translate(width / self.columns, 0) vsk.translate(0, height / self.rows)
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(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("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: 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 draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a4", landscape=True) vsk.scale("2cm") # build a star angles = np.linspace(0, 2 * np.pi, 5, endpoint=False) idx = [0, 2, 4, 1, 3, 0] x = np.cos(angles[idx] - np.pi / 2) y = np.sin(angles[idx] - np.pi / 2) with vsk.pushMatrix(): for i in range(5): with vsk.pushMatrix(): vsk.scale(0.8**i) vsk.polygon(x, y) vsk.translate(2, 0) vsk.translate(0, 4) for i in range(5): with vsk.pushMatrix(): vsk.rotate(i * 4, degrees=True) vsk.polygon(x, y) vsk.translate(2, 0)
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 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("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) 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 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 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: 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("a4", landscape=True) vsk.scale("1cm") vsk.penWidth("0.5mm") p = translate( Polygon( [(-3, -1), (1.5, -2), (1.4, 2), (0, 1.5), (-1, 2.3)], holes=[[(-0.5, -0.5), (0.5, -0.5), (0.5, 0.5), (-0.5, 0.5)]], ), 2.5, 14, ) # the default is no fill and stroke to layer 1 vsk.square(0, 0, 4) vsk.circle(2, 8, 4) vsk.geometry(p) vsk.translate(7, 0) # add some fill to layer 2 vsk.fill(2) vsk.penWidth("1mm", 2) vsk.square(0, 0, 4) vsk.circle(2, 8, 4) vsk.geometry(p) vsk.translate(7, 0) # with thick stroke vsk.fill(2) vsk.penWidth("1mm", 2) vsk.strokeWeight(4) vsk.square(0, 0, 4) vsk.circle(2, 8, 4) vsk.geometry(p) vsk.translate(7, 0) # remove stroke and set fill to layer 3 with a thicker pen vsk.fill(3) vsk.penWidth("2mm", 3) vsk.noStroke() vsk.square(0, 0, 4) vsk.circle(2, 8, 4) vsk.geometry(p)
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("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(self.page_size, landscape=False) vsk.scale("cm") vsk.scale(self.scale_factor) prob = { # modifiers "+": self.prob_plus, "-": self.prob_minus, "O": self.prob_bigger, "o": self.prob_smaller, "^": self.prob_raise, "v": self.prob_lower, " ": self.prob_segsep, "\n": self.prob_ringsep, # primitives "d": self.prob_dot, "D": self.prob_dotbar, "c": self.prob_circle, "b": self.prob_bar, "p": self.prob_cross, "s": self.prob_spring, "r": self.prob_box, "S": self.prob_sine, "C": self.prob_carbon, "l": self.prob_line, "L": self.prob_multiline, } for j in range(self.ny): for i in range(self.nx): # noinspection SpellCheckingInspection drawing = "".join( random.choices(list(prob.keys()), list(prob.values()), k=self.letter_count)) lc = make_drawing(drawing) vsk.stroke((i + j * self.nx) % self.nlayer + 1) with vsk.pushMatrix(): vsk.translate(i * self.dx, j * self.dy) for line in lc: vsk.polygon(line)
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: vsk.size("a4", landscape=True) vsk.scale("cm") vsk.rotate(-90, degrees=True) noise_coord = np.linspace(0, 1, self.point_per_line) dirs = np.linspace(0, 2 * math.pi, self.num_line) perlin = vsk.noise(noise_coord, dirs, [0, 100]) for i, direction in enumerate(dirs): rdir = vsk.map(perlin[:, i, 0], 0, 1, direction - self.rdir_range, direction + self.rdir_range) roffset = vsk.map(perlin[:, i, 1], 0, 1, 0.05, 0.12) xoffset = roffset * np.cos(rdir) yoffset = roffset * np.sin(rdir) vsk.polygon(np.cumsum(xoffset), np.cumsum(yoffset))
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a5", landscape=True) vsk.scale("1.5cm") vsk.detail(self.detail_value) vsk.circle(0, 0, 1) vsk.circle(0, 0, 2) with vsk.pushMatrix(): vsk.scale(4) # the scale is taken into account to compute details vsk.circle(0, 0, 1) vsk.translate(4, 0) for i in range(-4, 5): with vsk.pushMatrix(): vsk.translate(0, i * 0.4) vsk.bezier(0, 0, 1, -2, 2, 2, 3, 0)
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a4", landscape=True) vsk.scale("cm") # create a stick figure sub = vsketch.Vsketch() sub.detail(0.01) sub.rect(0, 0, 1, 2) sub.circle(0.5, -0.5, 1) sub.line(0, 0, -0.5, 1) sub.line(1, 0, 1.5, 1) sub.line(0, 2, -0.3, 4) sub.line(1, 2, 1.3, 4) for i in range(8): with vsk.pushMatrix(): vsk.scale(0.95**i) vsk.rotate(8 * i, degrees=True) vsk.sketch(sub) vsk.translate(3, 0)
def draw(self, vsk: vsketch.Vsketch) -> None: vsk.size("a4", landscape=False) vsk.scale("1mm") with vsk.pushMatrix(): for _ in range(40): vsk.rotate(2, degrees=True) vsk.scale(0.95) vsk.point(-75, 75) vsk.point(0, 75) vsk.point(75, 75) vsk.point(75, 0) vsk.point(75, -75) vsk.point(0, -75) vsk.point(-75, -75) vsk.point(-75, 0) with vsk.pushMatrix(): vsk.rotate(80, degrees=True) vsk.scale(0.95**40) vsk.square(0, 0, 150, mode="center")
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("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("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: 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")