def createtiles_truchet_roundonly(drawing, tile_size, nlines=None): circumference = tile_size * math.pi * 2 sections = circumference / drawing.pen_type.pen_width n = int(sections / 4) nlines = 3 if nlines is None else nlines paths = [[] for i in range(0, nlines)] for i in range(0, n+1): a = math.pi * i / (2*n) for j in range(0, nlines): paths[j].append(Point(math.cos(a), math.sin(a)) * tile_size * (j+1)/nlines) clip_path = [x for x in paths[nlines-1]] clip_path.append(Point(0,0)) sf = ShapeFiller([clip_path]) paths2 = [[] for i in range(0, nlines)] for i in range(0, n+1): a = math.pi * i / (2*n) for j in range(0, nlines): paths2[j].append(Point(tile_size, tile_size) - Point(math.cos(a), math.sin(a)) * tile_size * (j+1)/nlines) paths2 = sf.clip(paths2) tile_paths1 = paths tile_paths1.extend(paths2) return [tile_paths1]
def draw_shape_clips(d): all_polylines = [] shapes = [] for i in range(0, 40): x = 20 + random.random() * 25 y = 20 + random.random() * 25 size = 2.5 + 30 * random.random() shape = d.make_square(Point(x, y), size) a = random.random() * math.pi * 2 shape = [ StandardDrawing.rotate_about(pt, (x + size / 2, y + size / 2), a) for pt in shape ] shape_polyline = [x for x in shape] shape_polyline.append(shape_polyline[0]) # print(shape_polyline) if i == 0: all_polylines.append(shape_polyline) else: # print(f"shapes={shapes}") sf = ShapeFiller(shapes) clipped_polylines = sf.clip([shape_polyline], union=True) #print(polyline) #print(polylines) all_polylines.extend(clipped_polylines) #print(all_polylines[-1]) shapes.append(shape) d.add_polylines(all_polylines)
def draw_wakefield(drawing): import lsystem nslice = 40 polylines = [] paper_centre = Point(102.5, 148) rect_size = Point(192, 276) clip_2 = drawing.make_rect(paper_centre - rect_size / 2, rect_size.x, rect_size.y) clip_shape = drawing.make_circle(paper_centre, 44, x_scale=0.8) sf = ShapeFiller([clip_shape, clip_2]) drawing.image_spiral_single(drawing.dwg, 'wakefield2.jpg', paper_centre, 40, x_scale=0.8) all_lines = lsystem.test_lsystem_hilbert(order=8, size=1) def centre_on(polylines, new_centre): n = 0 sumx = 0 sumy = 0 for line in polylines: for point in line[:-1]: n += 1 sumx += point.x sumy += point.y centre = Point(sumx / n, sumy / n) adj = paper_centre - centre return [[p + adj for p in line] for line in polylines] all_lines = centre_on(all_lines, paper_centre) all_lines = sf.clip(all_lines, inverse=True) background_layer = drawing.add_layer("2-hilbert") drawing.add_polylines(all_lines, container=background_layer)
def draw_shape_clips2(d): paper_centre = Point(102.5, 148) paper_size = Point(192, 276) all_polylines = [] shapes = [] size = 10 for i in range(0, 1000): cx = paper_centre.x + (random.random() - 0.5) * (paper_size.x - size - 20) cy = paper_centre.y + (random.random() - 0.5) * (paper_size.y - size - 20) shape = d.make_square(Point(cx - size / 2, cy - size / 2), size) a = random.random() * math.pi * 2 shape = [StandardDrawing.rotate_about(pt, (cx, cy), a) for pt in shape] shape_polyline = [x for x in shape] shape_polyline.append(shape_polyline[0]) if len(shapes) == 0: all_polylines.append(shape_polyline) shapes.append(shape) else: sf = ShapeFiller(shapes) clipped_polylines = sf.clip([shape_polyline], union=True) if (len(clipped_polylines) > 0): # print(shape_polyline) # print(clipped_polylines) all_polylines.extend(clipped_polylines) shapes.append(shape) d.add_polylines(all_polylines)
def make_hash_square2(tl, side, gap, a, factor): centre = tl + Point(1, 1) * side / 2 r = side * math.sqrt(2) gap = 2 disp = 0 while disp > -r / 2: disp -= gap unclipped_lines = [] while disp < r / 2: line = [] x = -r / 2 indic = -1 while x < r / 2: line.append(centre + Point(x, disp + indic * gap * factor)) indic *= -1 x += gap unclipped_lines.append(line) disp += gap unclipped_lines = [[ StandardDrawing.rotate_about(x, centre, a) for x in line ] for line in unclipped_lines] c = math.cos(a) shape = [ tl, tl + Point(side, 0), tl + Point(side, side), tl + Point(0, side) ] sf = ShapeFiller([shape]) return sf.clip(unclipped_lines, inverse=True)
def make_hash_square3(tl, side, gap, a, pen_width, factor): centre = tl + Point(1, 1) * side / 2 r = side * math.sqrt(2) gap = 2 disp = 0 while disp > -r / 2: disp -= gap unclipped_lines = [] while disp < r / 2: line = [] x = -r / 2 a1 = 0 x_inc = pen_width a_inc = math.pi * 2 * (x_inc / gap) * factor while x < r / 2: line.append(centre + Point(x, disp + gap * math.sin(a1) * factor)) x += x_inc a1 += a_inc unclipped_lines.append(line) disp += gap unclipped_lines = [[ StandardDrawing.rotate_about(x, centre, a) for x in line ] for line in unclipped_lines] c = math.cos(a) shape = [ tl, tl + Point(side, 0), tl + Point(side, side), tl + Point(0, side) ] sf = ShapeFiller([shape]) return sf.clip(unclipped_lines, inverse=True)
def spiral_moire(drawing): centre = Point(102.5, 148) scale = 80 factor = 2 side = 2 h = side * 0.5 * math.sqrt(3) drawing.add_spiral(centre + Point(0, 0), scale, r_per_circle = (factor*1.00) * drawing.pen_type.pen_width) centre2 = centre + Point(0,5) all_polylines = [drawing.make_spiral(centre2, scale*1.09, r_per_circle = (factor*1.09) * drawing.pen_type.pen_width)] ''' shapes = [] for i in range(0,6): a = math.pi * 2 * i / 6 shapes = [] shapes.append(drawing.make_circle(centre + Point(math.cos(a), math.sin(a)) * scale * (2/3), scale * (1/3), n=100)) sf = ShapeFiller(shapes) polylines = sf.clip(all_polylines, union=True, inverse=True) #for p in polylines: # drawing.add_polyline(p) drawing.add_polylines(polylines) # drawing.add_polylines(shapes) shapes = [] shapes.append(drawing.make_circle(centre, scale * (1/3), n=100)) sf = ShapeFiller(shapes) polylines = sf.clip(all_polylines, union=True, inverse=True) drawing.add_polylines(polylines) ''' shapes = [] sgap = 9 size = sgap while size < scale*2: # math.sqrt(2): shapes.append(drawing.make_square(centre - Point(size/2, size/2), size)) size += sgap sf = ShapeFiller(shapes) polylines = sf.clip(all_polylines, inverse=True) shapes2 = [drawing.make_circle(centre, scale, n=100)] sf2 = ShapeFiller(shapes2) polylines = sf2.clip(polylines, inverse=True) drawing.add_polylines(polylines)
def linked_shapes(d): paper_centre = Point(102.5, 148) radius = 70 node_size = 5 n = 29 pts_and_angles = [] for i in range(0, n): a = math.pi * 2 * i / n c = math.cos(a) s = math.sin(a) pt = paper_centre + Point(c, s) * radius pts_and_angles.append((pt, a)) unclipped_lines = [] for i1 in range(0, len(pts_and_angles)): for i2 in range(0, i1): (pt1, _) = pts_and_angles[i1] (pt2, _) = pts_and_angles[i2] if pt1.x != pt2.x or pt1.y != pt2.y: unclipped_lines.append([pt1, pt2]) shapes = [] for (pt, a) in pts_and_angles: shape = [pt + Point(1,1)*node_size/2, pt + Point(1,-1)*node_size/2, pt + Point(-1,-1)*node_size/2, pt + Point(-1,1)*node_size/2] shape = [StandardDrawing.rotate_about(x, pt, a) for x in shape] shapes.append(shape) sf = ShapeFiller(shapes) clipped_lines = sf.clip(unclipped_lines) for shape in shapes: closed_shape = [x for x in shape] closed_shape.append(shape[0]) clipped_lines.append(closed_shape) d.add_polylines(clipped_lines)
def clip(sorted_faces): tStart = time.perf_counter() all_shapes = [] all_polylines = [] for face in sorted_faces: # First face if len(all_shapes) == 0: all_polylines.append(face) shape = face[0:-1] all_shapes.append(shape) sf = ShapeFiller([shape]) continue # 4% just from this! print(f".", end='', flush=True) # Only 50% of the time spent here? clipped = sf.clip([face], union=True) # Only do anything if the shape has something to display if len(clipped) == 0: continue all_polylines.extend(clipped) shape = face[0:-1] all_shapes.append(shape) sf.add_shape(shape) tEnd = time.perf_counter() print(f"clip-tot={tEnd - tStart:.2f}s") print(f"len(all_polylines)={len(all_polylines)}") print(f"len(shapes)={len(all_shapes)}") return all_polylines
def make_hash_square(tl, side, gap, a): centre = tl + Point(1, 1) * side / 2 r = side * math.sqrt(2) gap = 2 disp = 0 while disp > -r / 2: disp -= gap unclipped_lines = [] while disp < r / 2: unclipped_lines.append( [centre + Point(-r / 2, disp), centre + Point(r / 2, +disp)]) disp += gap unclipped_lines = [[ StandardDrawing.rotate_about(x, centre, a) for x in line ] for line in unclipped_lines] c = math.cos(a) shape = [ tl, tl + Point(side, 0), tl + Point(side, side), tl + Point(0, side) ] sf = ShapeFiller([shape]) return sf.clip(unclipped_lines, inverse=True)
def test_clip(): disp = (0, 5) shape1 = [Point(10, 10), Point(20, 10), Point(20, 20), Point(10, 20)] # all inside: clip everything shape2 = [Point(11, 11), Point(19, 11), Point(19, 19), Point(11, 19)] sf = ShapeFiller([shape1]) polylines = sf.clip([shape2], union=True) assert (len(polylines) == 0) def clip_displaced_square(sf, disp): shape2 = [(x[0] + disp[0], x[1] + disp[1]) for x in shape1] shape2.append(shape2[0]) return sf.clip([shape2], union=True) # on boundary - no clipping polylines = clip_displaced_square(sf, (0, 0)) assert (len(polylines) == 1) assert (len(polylines[0]) == 5) assert (polylines[0][0] == (10, 10)) assert (polylines[0][1] == (20, 10)) assert (polylines[0][2] == (20, 20)) assert (polylines[0][3] == (10, 20)) assert (polylines[0][4] == (10, 10)) # (15,15) - (25,15) - (25,25) - (15,25) - (15,15) polylines = clip_displaced_square(sf, (5, 5)) assert (len(polylines) == 1) assert (len(polylines[0]) == 5) print(polylines) assert (polylines[0][0] == (20, 15)) assert (polylines[0][1] == (25, 15)) assert (polylines[0][2] == (25, 25)) assert (polylines[0][3] == (15, 25)) assert (polylines[0][4] == (15, 20)) # (5,15) - (15,15) - (15,25) - (5,25) - (5,15) polylines = clip_displaced_square(sf, (-5, 5)) assert (len(polylines) == 2) assert (len(polylines[0]) == 2) assert (len(polylines[1]) == 4) assert (polylines[0][0] == (5, 15)) assert (polylines[0][1] == (10, 15)) assert (polylines[1][0] == (15, 20)) assert (polylines[1][1] == (15, 25)) assert (polylines[1][2] == (5, 25)) assert (polylines[1][3] == (5, 15)) # (5,5) - (15,5) - (15,15) - (5,15) - (5,5) polylines = clip_displaced_square(sf, (-5, -5)) assert (len(polylines) == 2) assert (len(polylines[0]) == 3) assert (len(polylines[1]) == 3) assert (polylines[0][0] == (5, 5)) assert (polylines[0][1] == (15, 5)) assert (polylines[0][2] == (15, 10)) assert (polylines[1][0] == (10, 15)) assert (polylines[1][1] == (5, 15)) assert (polylines[1][2] == (5, 5)) # (15,5) - (25,5) - (25,15) - (15,15) - (15,5) polylines = clip_displaced_square(sf, (5, -5)) assert (len(polylines) == 2) assert (len(polylines[0]) == 4) assert (len(polylines[1]) == 2) assert (polylines[0][0] == (15, 5)) assert (polylines[0][1] == (25, 5)) assert (polylines[0][2] == (25, 15)) assert (polylines[0][3] == (20, 15)) assert (polylines[1][0] == (15, 10)) assert (polylines[1][1] == (15, 5))
def draw_false_prophets(d): # A4 top_left = (0, 0) x_size = 210 y_size = 297 projection_angle=math.pi*0.2 p = perlin.PerlinNoise(scale=400, octaves=2) polylines = d.make_surface(top_left, x_size, int(y_size / math.cos(projection_angle)), p.calc2d, projection_angle=projection_angle) # clip to margin around edge of paper topleft = (20, 20) shapes = [d.make_rect(topleft, x_size - 2 * topleft[0], y_size - 2 * topleft[1])] sf = ShapeFiller(shapes) polylines = sf.clip(polylines, inverse=True) # medallion medallion_centre = (int(x_size/2), int(y_size/2)) shapes = [d.make_circle(medallion_centre, 29, x_scale = 0.7), d.make_circle(medallion_centre, 27, x_scale = 0.7)] sf = ShapeFiller(shapes) polylines = sf.clip(polylines, union=True) new_lines = sf.get_paths(d.pen_type.pen_width / 5) for line in new_lines: polylines.append(line) image_path = d.make_image_spiral_single('burroughs.jpg', medallion_centre, 25, x_scale = 0.7) polylines.append(image_path) family='CNC Vector' # family = 'HersheyScript1smooth' family = 'Arial' family = 'Caslon Antique' header_pos = (int(x_size/2), 40) fontsize = 36 text = "False Prophets Of The New Millenium." ext = d.text_bound(text, fontsize, family) position = (header_pos[0] - ext.width/2, header_pos[1]) text_paths = d.make_text(text, position, fontsize=fontsize, family=family) rect_width = 0.5 rect1 = d.make_rect((position[0] - 2, position[1] + ext.y_bearing - 2), ext.width + 4, ext.height + 4) rect2 = d.make_rect((position[0] - (2+rect_width), position[1] + ext.y_bearing - (2+rect_width)), ext.width + (4+2*rect_width), ext.height + (4+2*rect_width)) sf = ShapeFiller([rect1, rect2]) polylines = sf.clip(polylines, union=True) rect_paths = sf.get_paths(d.pen_type.pen_width / 5) for p in rect_paths: polylines.append(p) sf = ShapeFiller(text_paths) filled_text_paths = sf.get_paths(d.pen_type.pen_width / 5) for p in filled_text_paths: polylines.append(p) for text_path in text_paths: polylines.append(text_path) # legend family='CNC Vector' # family = 'HersheyScript1smooth' family = 'Caslon Antique' fontsize = 24 text = "WAKEFIELD" ext = d.text_bound(text, fontsize, family) position = (medallion_centre[0] - ext.width/2, medallion_centre[1]+30+4+ext.height) text_paths = d.make_text(text, position, fontsize=fontsize, family=family) sf = ShapeFiller(text_paths) filled_text_paths = sf.get_paths(d.pen_type.pen_width / 5) rect_width = 0.5 rect1 = d.make_rect((position[0] - 2, position[1] + ext.y_bearing - 2), ext.width + 4, ext.height + 4) rect2 = d.make_rect((position[0] - (2+rect_width), position[1] + ext.y_bearing - (2+rect_width)), ext.width + (4+2*rect_width), ext.height + (4+2*rect_width)) sf = ShapeFiller([rect1, rect2]) polylines = sf.clip(polylines, union=True) rect_paths = sf.get_paths(d.pen_type.pen_width / 5) for p in rect_paths: polylines.append(p) for text_path in filled_text_paths: polylines.append(text_path) polylines2 = [] family = 'Aquifer' family = 'Caslon Antique' fontsize = 48 row_ext = d.text_bound("Op", fontsize, family) header_pos = (int(x_size/2), 80) text = "False Prophets Of" ext = d.text_bound(text, fontsize, family) position = (header_pos[0] - ext.width/2, header_pos[1]) text_paths = d.make_text(text, position, fontsize=fontsize, family=family) sf = ShapeFiller(text_paths) filled_text_paths = sf.get_paths(d.pen_type.pen_width / 5) for p in filled_text_paths: polylines2.append(p) header_pos = (header_pos[0], header_pos[1] + row_ext.height + 2) text = "The New Millenium" ext = d.text_bound(text, fontsize, family) position = (header_pos[0] - ext.width/2, header_pos[1]) text_paths = d.make_text(text, position, fontsize=fontsize, family=family) sf = ShapeFiller(text_paths) filled_text_paths = sf.get_paths(d.pen_type.pen_width / 5) for p in filled_text_paths: polylines2.append(p) d.add_polylines(polylines)
def draw_shape_clips3(d): # Try developing a shade fill class that we can put in here # Can use for more general area fill art paper_centre = Point(102.5, 148) paper_size = Point(192, 276) all_shape_polylines = [] all_fill_polyline_lists = [] shapes = [] max_size = 30 for i in range(0, 50): cx = paper_centre.x + (random.random() - 0.5) * (paper_size.x - (max_size + 20)) cy = paper_centre.y + (random.random() - 0.5) * (paper_size.y - (max_size + 20)) r = random.random() size = max_size * (0.5 + 0.5 * r) r = random.random() if r < 0.333: tl = Point(cx - size / 2, cy - size / 2) line = [ Point(1, 0), Point(2, 0), Point(2, 1), Point(3, 1), Point(3, 2), Point(2, 2), Point(2, 3), Point(1, 3), Point(1, 2), Point(0, 2), Point(0, 1), Point(1, 1) ] shape = [tl + pt * (size / 3) for pt in line] elif r < 0.666: shape = d.make_square(Point(cx - size / 2, cy - size / 2), size) else: tl = Point(cx - size / 2, cy - size / 2) line = [Point(0, 0), Point(3, 0), Point(1.5, 3 * math.sqrt(3) / 2)] shape = [tl + pt * (size / 3) for pt in line] fill_lines = [] r = random.random() if r < 10.5: sf = ShapeFiller([shape]) w = d.pen_type.pen_width * 0.8 y = cy - size / 2 + w fill_lines = [] while y < cy + size / 2: fill_lines.append( [Point(cx - size / 2, y), Point(cx + size / 2, y)]) y += w fill_lines = sf.clip(fill_lines, inverse=True) a = random.random() * math.pi * 2 fill_lines = [[ StandardDrawing.rotate_about(pt, (cx, cy), a) for pt in line ] for line in fill_lines] shape = [StandardDrawing.rotate_about(pt, (cx, cy), a) for pt in shape] shape_polyline = [x for x in shape] shape_polyline.append(shape_polyline[0]) if len(shapes) == 0: all_shape_polylines.extend([shape_polyline]) shapes.append(shape) clipped_fill_polylines = [[fill_line] for fill_line in fill_lines] else: sf = ShapeFiller(shapes) clipped_shape_polylines = sf.clip([shape_polyline], union=True) all_shape_polylines.extend(clipped_shape_polylines) # A list of polylines (= list of points) clipped_fill_polylines = [ sf.clip([fill_line], union=True) for fill_line in fill_lines ] shapes.append(shape) ix = 0 for clipped_fill_polyline in clipped_fill_polylines: if (len(clipped_fill_polyline) > 0): all_fill_polyline_lists.append(clipped_fill_polyline) ix += 1 d.add_polylines(all_shape_polylines) sub_lists = [[], [], [], []] mins = paper_centre - paper_size / 2 maxs = paper_centre + paper_size / 2 for polyline_list in all_fill_polyline_lists: pts = [pt for polyline in polyline_list for pt in polyline] avg = Point(sum(pt.x for pt in pts), sum(pt.y for pt in pts)) / len(pts) cx = min(1, max(0, (avg.x - mins.x) / (maxs.x - mins.x))) cy = min(1, max(0, (avg.y - mins.x) / (maxs.y - mins.y))) r0 = cx r1 = 1 - cx r2 = cy r3 = 1 - cy rtot = r0 + r1 + r2 + r3 # + 2 r = random.random() if r < r0 / rtot: sub_lists[0].extend(polyline_list) elif r < (r0 + r1) / rtot: sub_lists[1].extend(polyline_list) elif r < (r0 + r1 + r2) / rtot: sub_lists[2].extend(polyline_list) elif r < (r0 + r1 + r2 + r3) / rtot: sub_lists[3].extend(polyline_list) #d.add_polylines(sub_lists[0], container=d.add_layer("1-xxx"), stroke=svgwrite.rgb(100, 100, 50, '%')) #d.add_polylines(sub_lists[1], container=d.add_layer("2-xxx"), stroke=svgwrite.rgb(100, 50, 100, '%')) #d.add_polylines(sub_lists[2], container=d.add_layer("3-xxx"), stroke=svgwrite.rgb(100, 0, 0, '%')) #d.add_polylines(sub_lists[3], container=d.add_layer("4-xxx"), stroke=svgwrite.rgb(50, 50, 100, '%')) d.add_polylines(sub_lists[0], container=d.add_layer("1-xxx"), stroke=svgwrite.rgb(50, 50, 100, '%')) d.add_polylines(sub_lists[1], container=d.add_layer("2-xxx"), stroke=svgwrite.rgb(50, 100, 50, '%')) d.add_polylines(sub_lists[2], container=d.add_layer("3-xxx"), stroke=svgwrite.rgb(50, 100, 100, '%')) d.add_polylines(sub_lists[3], container=d.add_layer("4-xxx"), stroke=svgwrite.rgb(0, 50, 50, '%'))