def test_sketch_layers(vsk): sub = vsketch.Vsketch() sub.stroke(5) sub.polygon(UNIT_SQUARE.real, UNIT_SQUARE.imag) sub.stroke(7) sub.polygon(UNIT_SQUARE.real, UNIT_SQUARE.imag) vsk.sketch(sub) vsk.translate(2, 0) vsk.sketch(sub) vsk.translate(0, 2) vsk.sketch(sub) vsk.translate(-2, 0) vsk.sketch(sub) assert line_count_equal(vsk, (5, 4), (7, 4))
def __init__(self, poly, lod=4, falloff=None, noiseSeed=71, noise_scale=0.001, output_range=(0, np.pi * 2)): self.p = poly self.vsk = vsketch.Vsketch() self.lod = lod self.falloff = falloff self.noiseSeed = noiseSeed self.noise_scale = noise_scale self.vsk.noiseSeed(self.noiseSeed) self.vsk.noiseDetail(lod=self.lod, falloff=self.falloff) self.output_range = output_range
def test_sketch(vsk): sub = vsketch.Vsketch() sub.polygon(UNIT_SQUARE.real, UNIT_SQUARE.imag) vsk.sketch(sub) vsk.translate(2, 0) vsk.sketch(sub) vsk.translate(0, 2) vsk.sketch(sub) vsk.translate(-2, 0) vsk.sketch(sub) assert line_count_equal(vsk, 4) assert line_exists(vsk, UNIT_SQUARE) assert line_exists(vsk, UNIT_SQUARE + 2) assert line_exists(vsk, UNIT_SQUARE + 2j) assert line_exists(vsk, UNIT_SQUARE + 2 + 2j)
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 __init__(self, poly, xstep=0.1, ystep=0.1, lod=4, falloff=None, noiseSeed=71, noise_scale=0.001): self.p = poly self.xbins, self.ybins = overlay_grid(poly, xstep, ystep) self.gxs, self.gys = np.meshgrid(self.xbins, self.ybins) self.vsk = vsketch.Vsketch() self.lod = lod self.falloff = falloff self.noiseSeed = noiseSeed self.noise_scale = noise_scale self.z = self.make_noisegrid() self.a = np.interp(self.z, [0, 1], [0, np.pi * 2])
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 test_noise_seed_different(): vsk1 = vsketch.Vsketch() vsk2 = vsketch.Vsketch() assert vsk1.noise(0.5) != vsk2.noise(0.5)
def test_random_seed_different(): vsk1 = vsketch.Vsketch() vsk2 = vsketch.Vsketch() assert vsk1.random(10, 20) != vsk2.random(10, 20)
def main( image_path, filename, paper_size: str = '11x17 inches', border: float = 20, # mm image_rescale_factor: float = 0.25, smooth_disk_size: int = 2, hist_clip_limit=0.1, hist_nbins=32, intensity_min=0., intensity_max=1., hatch_spacing_min=0.3, # mm hatch_spacing_max=1., # mm pixel_width=0.9, # mm pixel_height=0.9, # mm angle_jitter='0', # degrees pixel_rotation='0', # degrees merge_tolerances=[0.3, 0.4, 0.5], # mm simplify_tolerances=[0.2], # mm savedir='/mnt/c/code/side/plotter_images/oned_outputs'): # make page paper = Paper(paper_size) drawbox = paper.get_drawbox(border) # load img = rgb2gray(io.imread(Path(image_path))) img_rescale = rescale(img, image_rescale_factor) # img_renorm = exposure.equalize_adapthist(img_rescale, clip_limit=hist_clip_limit, nbins=hist_nbins) # calc dominant angle selem = disk(smooth_disk_size) filt_img = filters.rank.mean(img_renorm, selem) angle_farid = local_angle(filters.farid_h(filt_img), filters.farid_v(filt_img)) # make pixel polys prms = [] for y, row in tqdm(enumerate(img_renorm)): for x, intensity in enumerate(row): p = gp.centered_box(Point(x, y), width=pixel_width, height=pixel_height) a = np.degrees(angle_farid[y, x]) prm = { 'geometry': p, 'x': x, 'y': y, 'raw_pixel_width': pixel_width, 'raw_pixel_height': pixel_height, 'intensity': intensity, 'angle': a, 'group': 'raw_hatch_pixel', } prms.append(prm) raw_hatch_pixels = geopandas.GeoDataFrame(prms) # rescale polys to fit in drawbox bbox = box(*raw_hatch_pixels.total_bounds) _, transform = gp.make_like(bbox, drawbox, return_transform=True) A = gp.AffineMatrix(**transform) scaled_hatch_pixels = raw_hatch_pixels.copy() scaled_hatch_pixels['geometry'] = scaled_hatch_pixels.affine_transform( A.A_flat) scaled_hatch_pixels['scaled_pixel_height'] = scaled_hatch_pixels[ 'geometry'].apply(gp.get_height) scaled_hatch_pixels['scaled_pixel_width'] = scaled_hatch_pixels[ 'geometry'].apply(gp.get_width) # distributions etc angle_jitter_gen = gp.make_callable(eval(angle_jitter)) pixel_rotation_gen = gp.make_callable(eval(pixel_rotation)) scaled_hatch_pixels['angle_jitter'] = angle_jitter_gen( len(scaled_hatch_pixels)) scaled_hatch_pixels['hatch_angle'] = scaled_hatch_pixels[ 'angle'] + scaled_hatch_pixels['angle_jitter'] scaled_hatch_pixels['pixel_rotation'] = pixel_rotation_gen( len(scaled_hatch_pixels)) example_height = scaled_hatch_pixels.loc[0, 'scaled_pixel_height'] example_width = scaled_hatch_pixels.loc[0, 'scaled_pixel_width'] print(f'pixel size = {example_width:.2}x{example_height:.2}mm') spacing_func = functools.partial(np.interp, xp=[intensity_min, intensity_max], fp=[ hatch_spacing_max, hatch_spacing_min, ]) scaled_hatch_pixels['spacing'] = spacing_func( 1 - scaled_hatch_pixels['intensity']) new_rows = [] for i, row in tqdm(scaled_hatch_pixels.iterrows(), total=len(scaled_hatch_pixels)): r = row.copy() p = r['geometry'] if abs(r['pixel_rotation']) > np.finfo(float).eps: p = sa.rotate(p, r['pixel_rotation']) f = gp.hatchbox(p, spacing=r['spacing'], angle=r['hatch_angle']) r['geometry'] = f new_rows.append(r) fills = geopandas.GeoDataFrame(new_rows) fills = fills[fills.length > 0] fill_layer = gp.merge_LineStrings(fills.geometry) sk = vsketch.Vsketch() sk.size(paper.page_format_mm) sk.scale('1mm') sk.stroke(1) sk.geometry(fill_layer) sk.vpype('linesort') for tolerance in merge_tolerances: sk.vpype(f'linemerge --tolerance {tolerance}mm') for tolerance in simplify_tolerances: sk.vpype(f'linesimplify --tolerance {tolerance}mm') sk.vpype('linesort') savepath = Path(savedir).joinpath(filename).as_posix() sk.save(savepath)
PEN_SPACING = 0.7 OFFSET_MULTIPLIER = 1.02 WIDTH = 4 HEIGHT = 6 MARGIN = 4 / 25.4 MM = 1 / 25.4 W = WIDTH - 2 * MARGIN qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_H) qr.add_data('https://ideo.github.io/widschicago-2021/') qr.make() outfilename = "back.svg" sketch = vsketch.Vsketch() sketch.size("{}in".format(WIDTH), "{}in".format(HEIGHT)) sketch.scale("1in") sketch._center_on_page = False actual_pen_width_mm = 0.5 dx = 5 * MM dy = 5 * MM size = actual_pen_width_mm * MM sketch.stroke(1) sketch.penWidth(f"{actual_pen_width_mm}mm", 1) graph = make_graph(qr.modules) for path in path_cover(graph): while len(path) < 3:
def vsk(): return vsketch.Vsketch()