def start_drawing(opt, **drawing_args): """Make a Drawing based on the options passed.""" width, height = opt['size'] bg = opt['background'] def_bg = drawing_args.pop('bg', (1, 1, 1)) if bg is None: bg = def_bg name = opt['output'] def_name = drawing_args.pop('name', 'drawing') format = opt['format'] dwg = Drawing(width, height, name=name or def_name, format=format, bg=bg, **drawing_args) dwg.translate(width / 2, height / 2) dwg.rotate(opt['rotate']) dwg.translate(-width / 2, -height / 2) return dwg
def candystripe(**opt): width, height = opt['size'] TILEW = int(width / opt['tiles']) dwg = Drawing(width, height, name="candy") pt = PathTiler() design_class = get_design(opt['design']) draw = design_class(TILEW) draw.draw(pt, dwg.get_size()) paths = combine_paths(pt.paths) LINE_WIDTH = TILEW / 4 dwg.multi_stroke( paths, [ #(LINE_WIDTH, (0, 0, 0)), (LINE_WIDTH - 2, random_color), #(7, (0, 0, 0)), (5, (1, 1, 1)), ]) dwg.finish()
def debug_world(paths, width, height): dwg = Drawing(paths=paths, name="debug_world", bg=None) # Gray rectangle: the desired visible canvas. with dwg.style(rgb=(.95, .95, .95)): dwg.rectangle(0, 0, width, height) dwg.fill() # Reference grid. llx, lly = dwg.llx, dwg.lly urx = llx + dwg.width ury = lly + dwg.height with dwg.style(rgb=(.5, 1, 1), width=1, dash=[5, 5], dash_offset=7.5): for xmin in tick_range(llx, urx, 20): dwg.move_to(xmin, lly) dwg.line_to(xmin, ury) dwg.stroke() for ymin in tick_range(lly, ury, 20): dwg.move_to(llx, ymin) dwg.line_to(urx, ymin) dwg.stroke() with dwg.style(rgb=(.5, 1, 1), width=1): dwg.circle_points([Point(0, 0)], radius=10) for xmaj in tick_range(llx, urx, 100): dwg.move_to(xmaj, lly) dwg.line_to(xmaj, ury) dwg.stroke() for ymaj in tick_range(lly, ury, 100): dwg.move_to(llx, ymaj) dwg.line_to(urx, ymaj) dwg.stroke() # The paths themselves. dwg.draw_paths(paths, width=1, rgb=(1, 0, 0)) dwg.finish() print("Wrote debug_world.png")
def straps(**opt): width, height = opt['size'] TILEW = int(width / opt['tiles']) if opt['strap_width'] > 0: strap_kwargs = dict(width=TILEW * opt['strap_width'] / 100, random_factor=0) else: strap_kwargs = dict(width=TILEW / 60, random_factor=4.9) dwg = Drawing(width, height, name="straps", bg=(.8, .8, .8)) pt = PathTiler() design_class = get_design(opt['design']) draw = design_class(TILEW) draw.draw(pt, dwg.get_size()) paths = combine_paths(pt.paths) if should_debug('world'): debug_world(paths, width, height) straps = strapify(paths, **strap_kwargs) with dwg.style(rgb=(1, 1, 1)): for strap in straps: replay_path(strap.sides[0], dwg) replay_path(strap.sides[1][::-1], dwg, append=True) dwg.close_path() dwg.fill() with dwg.style(rgb=(0, 0, 0), width=2): for strap in straps: for side in strap.sides: replay_path(side, dwg) dwg.stroke() dwg.finish()
def debug_output(dwgw=None, paths=None, segments=None, isects=None): dwg = Drawing(paths=paths, name="debug.png") dwg.draw_segments(segments, rgb=(0, 0, 0), width=1) dup_segments = [] segments.sort() for s1, s2 in zip(segments, segments[1:]): if s1 == s2: dup_segments.append(s1) dwg.draw_segments(dup_segments, rgb=(1, 0, 0), width=7) if dwgw is not None: with dwg.style(rgb=(0, 0, 1), width=2, dash=[5, 5]): dwg.rectangle(0, 0, dwgw, dwgw) dwg.stroke() if isects is not None: dwg.circle_points(isects, radius=9, rgb=(0, .5, 0), width=3) dwg.finish()
def talk_pictures(): size = (883, 683) tilew = int(DWGW / 3) dwgnum = iter(itertools.count()) def dwg_name(slug): return f'three_stars_{next(dwgnum):03d}_{slug}' dwg = Drawing(*size, name=dwg_name('start'), bg=(.85, .85, .85)) draw_it(tilew, dwg) dwg.finish() dwg = Drawing(*size, name=dwg_name('thin')) draw_it(tilew, dwg, fat=False) dwg.finish() dwg = Drawing(*size, name=dwg_name('symmetry')) tiler = PathTiler(dwg) draw = ThreeStarsDesign(tilew) tiler.tile_p6m(draw.draw_tiler_unit, tilew) with dwg.style(rgb=(1, .15, .15), width=1, dash=[5, 5]): draw_paths(tiler.paths, dwg) dwg.stroke() dwg.finish() def single_tiler(): tiler = PathTiler(dwg) tiler.pc.translate(2 * tilew * SQRT3 / 2, tilew) tiler.pc.reflect_xy(0, 0) return tiler dwg = Drawing(*size, name=dwg_name('triangle')) tiler = PathTiler(dwg) draw = ThreeStarsDesign(tilew) tiler.tile_p6m(draw.draw_tiler_unit, tilew) with dwg.style(rgb=(1, .5, .5), width=1, dash=[5, 5]): draw_paths(tiler.paths, dwg) dwg.stroke() tiler = single_tiler() draw.draw_tiler_unit(tiler.pc) with dwg.style(rgb=(1, 0, 0), width=3): draw_paths(tiler.paths, dwg) dwg.stroke() dwg.finish() dwg = Drawing(*size, name=dwg_name('design')) tiler = PathTiler(dwg) draw = ThreeStarsDesign(tilew) tiler.tile_p6m(draw.draw_tiler_unit, tilew) with dwg.style(rgb=(1, .5, .5), width=1, dash=[5, 5]): draw_paths(tiler.paths, dwg) dwg.stroke() tiler = single_tiler() draw.draw_tiler_unit(tiler.pc) with dwg.style(rgb=(1, 0, 0), width=3): draw_paths(tiler.paths, dwg) dwg.stroke() tiler = single_tiler() draw.draw_tile(tiler.pc) with dwg.style(rgb=(0, 0, 0), width=6): draw_paths(tiler.paths, dwg) dwg.stroke() dwg.finish() dwg = Drawing(*size, name=dwg_name('lined')) draw_it(tilew, dwg, fat=False, color=(.5, .5, .5)) tiler = PathTiler(dwg) draw = ThreeStarsDesign(tilew) tiler.tile_p6m(draw.draw_tiler_unit, tilew) with dwg.style(rgb=(1, .75, .75), width=1, dash=[5, 5]): draw_paths(tiler.paths, dwg) dwg.stroke() tiler = single_tiler() draw.draw_tile(tiler.pc) with dwg.style(rgb=(0, 0, 0), width=6): draw_paths(tiler.paths, dwg) dwg.stroke() dwg.finish() dwg = Drawing(*size, name=dwg_name('chaos')) draw_it(tilew, dwg, fat=False, color=random_color, combined=False, line_width=8) dwg.finish() dwg = Drawing(*size, name=dwg_name('joined')) draw_it(tilew, dwg, fat=False, color=random_color, combined=True, line_width=8) dwg.finish()
def final(): tilew = int(DWGW / 5) dwg = Drawing(DWGW, DWGW, bg=(.85, .85, .85), name='three_stars_final') draw_it(tilew, dwg) dwg.finish()
def talk_pictures(): size = (883, 683) TILEW = int(DWGW/3) dwgnum = iter(itertools.count()) def dwg_name(slug): return f'three_stars_{next(dwgnum):03d}_{slug}' dwg = Drawing(*size, name=dwg_name('start'), bg=(.85, .85, .85)) draw_it(TILEW, dwg) dwg.finish() dwg = Drawing(*size, name=dwg_name('thin')) draw_it(TILEW, dwg, fat=False) dwg.finish() dwg = Drawing(*size, name=dwg_name('symmetry')) pt = PathTiler() draw = ThreeStarsDesign(TILEW) pt.tile_p6m(draw.draw_triangle, dwg.get_size(), TILEW) with dwg.style(rgb=(1, .15, .15), width=1, dash=[5, 5]): pt.replay_paths(dwg) dwg.stroke() dwg.finish() def single_tiler(): pt = PathTiler() pt.translate(2 * TILEW * SQRT3 / 2, TILEW) pt.reflect_xy(0, 0) return pt dwg = Drawing(*size, name=dwg_name('triangle')) pt = PathTiler() draw = ThreeStarsDesign(TILEW) pt.tile_p6m(draw.draw_triangle, dwg.get_size(), TILEW) with dwg.style(rgb=(1, .5, .5), width=1, dash=[5, 5]): pt.replay_paths(dwg) dwg.stroke() pt = single_tiler() draw.draw_triangle(pt) with dwg.style(rgb=(1, 0, 0), width=3): pt.replay_paths(dwg) dwg.stroke() dwg.finish() dwg = Drawing(*size, name=dwg_name('design')) pt = PathTiler() draw = ThreeStarsDesign(TILEW) pt.tile_p6m(draw.draw_triangle, dwg.get_size(), TILEW) with dwg.style(rgb=(1, .5, .5), width=1, dash=[5, 5]): pt.replay_paths(dwg) dwg.stroke() pt = single_tiler() draw.draw_triangle(pt) with dwg.style(rgb=(1, 0, 0), width=3): pt.replay_paths(dwg) dwg.stroke() pt = single_tiler() draw.draw_tile(pt) with dwg.style(rgb=(0, 0, 0), width=6): pt.replay_paths(dwg) dwg.stroke() dwg.finish() dwg = Drawing(*size, name=dwg_name('lined')) draw_it(TILEW, dwg, fat=False, color=(.5, .5, .5)) pt = PathTiler() draw = ThreeStarsDesign(TILEW) pt.tile_p6m(draw.draw_triangle, dwg.get_size(), TILEW) with dwg.style(rgb=(1, .75, .75), width=1, dash=[5, 5]): pt.replay_paths(dwg) dwg.stroke() pt = single_tiler() draw.draw_tile(pt) with dwg.style(rgb=(0, 0, 0), width=6): pt.replay_paths(dwg) dwg.stroke() dwg.finish() dwg = Drawing(*size, name=dwg_name('chaos')) draw_it(TILEW, dwg, fat=False, color=random_color, combined=False, line_width=8) dwg.finish() dwg = Drawing(*size, name=dwg_name('joined')) draw_it(TILEW, dwg, fat=False, color=random_color, combined=True, line_width=8) dwg.finish()
def final(): TILEW = int(DWGW/5) dwg = Drawing(DWGW, DWGW, bg=(.85, .85, .85), name='three_stars_final') draw_it(TILEW, dwg) dwg.finish()
def debug_world(dwg0, paths_styles): """Draw a picture of the entire world. `dwg0` is the Drawing we're really making. `paths_styles` is a list of tuples: (paths, style) for drawing. """ # Get the perimeter of the real drawing. dwg0_path = dwg0.perimeter() # Get the bounds of everything we're going to draw. bounds = EmptyBounds() for paths, styles in paths_styles: bounds |= paths_bounds(paths) bounds |= dwg0_path.bounds() bounds = bounds.expand(percent=2) dwg = Drawing(bounds=bounds, name="debug_world", bg=(.95, .95, .95)) # White rectangle: the desired visible canvas. with dwg.style(rgb=(1, 1, 1)): dwg0_path.draw(dwg) dwg.fill() # Reference grid. llx, lly, urx, ury = dwg.bounds with dwg.style(rgb=(.5, 1, 1), width=1, dash=[5, 5], dash_offset=7.5): for xmin in tick_range(llx, urx, 20): dwg.move_to(xmin, lly) dwg.line_to(xmin, ury) dwg.stroke() for ymin in tick_range(lly, ury, 20): dwg.move_to(llx, ymin) dwg.line_to(urx, ymin) dwg.stroke() with dwg.style(rgb=(.5, 1, 1), width=1): for xmaj in tick_range(llx, urx, 100): dwg.move_to(xmaj, lly) dwg.line_to(xmaj, ury) dwg.stroke() for ymaj in tick_range(lly, ury, 100): dwg.move_to(llx, ymaj) dwg.line_to(urx, ymaj) dwg.stroke() # The origin. with dwg.style(rgb=(0, .75, .75), width=1): dwg.circle_points([Point(0, 0)], radius=10) dwg.move_to(-10, 0) dwg.line_to(10, 0) dwg.move_to(0, -10) dwg.line_to(0, 10) dwg.stroke() # The paths themselves. for paths, styles in paths_styles: dwg.draw_paths(paths, **styles) dwg.finish() print("Wrote debug_world.png")
def diagram(**opt): """Draw the underlying structure of a design""" width, height = opt['size'] tilew = int(width / opt['tiles']) dwg = Drawing(width, height, name="diagram") design_class = get_design(opt['design']) draw = design_class(tilew) # The full pattern. tiler = PathTiler(dwg) draw.draw(tiler) with dwg.style(rgb=(.5, .5, .5)): draw_paths(tiler.paths, dwg) dwg.stroke() # The symmetry. tiler = PathTiler(dwg) tiler.tile_p6m(draw.draw_tiler_unit, tilew) with dwg.style(rgb=(1, .75, .75), width=1, dash=[5, 5]): draw_paths(tiler.paths, dwg) dwg.stroke() def single_tiler(): """Make a PathTiler right for drawing just one unit.""" tiler = PathTiler(dwg) # TODO: make this work for other symmetries tiler.pc.translate(2 * tilew * math.sqrt(3) / 2, tilew) tiler.pc.reflect_xy(0, 0) return tiler # The tiler unit. tiler = single_tiler() draw.draw_tiler_unit(tiler.pc) with dwg.style(rgb=(1, 0, 0), width=3): draw_paths(tiler.paths, dwg) dwg.stroke() # The design. tiler = single_tiler() draw.draw_tile(tiler.pc) with dwg.style(rgb=(0, 0, 0), width=6): draw_paths(tiler.paths, dwg) dwg.stroke() dwg.finish()