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 text_in_circle(d, centre, text, radius, fontsize, family, fill, container=None): container = d.default_container(container) angle = - math.pi / 2 * 0.9 lines = [] for letter in text: ext = d.text_bound_letter(letter, fontsize, family) w = ext[0] angle_diff = w / radius * 1.2 ((w, h), text_paths) = d.make_spiral_letter(letter, fontsize, centre, radius, angle=angle, family=family) angle += angle_diff if len(text_paths) > 0: if fill: sf = ShapeFiller(text_paths) filled_text_paths = sf.get_paths(d.pen_type.pen_width / 5) lines.extend(filled_text_paths) else: lines.extend(text_paths) d.add_polylines(lines, container=container) if False: # fill: d.add_dot(centre, radius + 7.3, r_start = radius + 5.8, stroke=svgwrite.rgb(0, 0, 0, '%'), container=container) d.add_dot(centre, radius - 1.8, r_start = radius - 3.3, stroke=svgwrite.rgb(0, 0, 0, '%'), container=container) else: d.add_circle(centre, radius + 7.3) d.add_circle(centre, radius + 5.8) d.add_circle(centre, radius - 1.9) d.add_circle(centre, radius - 3.3) lines = [] lines.append(d.make_circle(centre, radius + 8.3)) lines.append(d.make_circle(centre, radius - 4.3)) return lines
def draw_big_a(d): paper_centre = Point(102.5, 148) fontsize = 96 * 8 * 0.5 family = "Arial" text = "ﷺ" ext = d.text_bound(text, fontsize=fontsize, family=family) text_place = Point(paper_centre.x - ext.width / 2, paper_centre.y + ext.height / 2) letter_paths = d.make_text(text, text_place, fontsize=fontsize, family=family) sf = ShapeFiller(letter_paths) paths = [] for path in sf.get_paths(0.4 * d.pen_type.pen_width, angle=math.pi / 2): # math.pi/2): paths.append(path) d.add_polylines(paths, container=d.add_layer("1"), stroke=svgwrite.rgb(30, 100, 30, '%')) closed_letter_paths = [] for letter_path in letter_paths: x = [_ for _ in letter_path] x.append(x[0]) closed_letter_paths.append(x) d.add_polylines(closed_letter_paths, container=d.add_layer("0"))
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_riley_movement_in_squares(drawing): paper_centre = Point(102.5, 148) size = 90 sq_size = 14 n = 12 top_y = paper_centre[1] - (n/2) * sq_size left_x = paper_centre[0] - (n/2) * sq_size right_x = paper_centre[0] + (n/2) * sq_size for r in range(0, n): y = top_y + sq_size * r x = left_x print(x,y) ix_x = 0 a = 0 x_width = sq_size while x < right_x: c = math.cos(a) x_factor = 0.06 + 0.94 * abs(math.pow(abs(c), 2.5)) new_x = x + sq_size * x_factor if new_x > right_x: new_x = right_x print(x, y, new_x, x_factor) if (ix_x + r) % 2 == 1: shape = [(x, y), (new_x, y), (new_x, y + sq_size), (x, y + sq_size)] sf = ShapeFiller([shape]) paths = sf.get_paths(drawing.pen_type.pen_width * 0.4) drawing.add_polylines(paths) x = new_x ix_x += 1 a += math.pi / 29.6
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 test_shape_filler(d): ''' yd = -45 points = [ [(50, 150+yd), (50, 160+yd), (60, 160+yd), (60, 150+yd)], [(53, 153+yd), (53, 157+yd), (57, 157+yd), (57, 153+yd)], ] ''' centre = (50, 50) star = [] n = 5 for i in range(0, 2 * n): a = 2 * math.pi * i / (2 * n) r = 7 + 11 * (i % 2) c = d.get_circle_point(centre, r, a) star.append(c) points = [star] # points = [] points.append(d.make_circle(centre, 7, int(5 * 2 * math.pi * 2))) points.append(d.make_circle(centre, 9, int(9 * 2 * math.pi * 2))) points.append(d.make_circle(centre, 11, int(11 * 2 * math.pi * 2))) points.append(d.make_circle(centre, 18, int(18 * 2 * math.pi * 2))) points.append(d.make_circle(centre, 20, int(20 * 2 * math.pi * 2))) angle = 0.45 * math.pi + (105 / 360) * 2 * math.pi # angle=0 sf = ShapeFiller(points) for path in sf.get_paths(10 * d.pen_type.pen_width / 5, angle=angle): # for path in sf.get_paths(3): d.add_polyline(path)
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 test_text_and_shape(d): letter_paths = d.make_text("TEST", (20, 80), 96, family="Arial") circle = d.make_circle((50, 70), 15) letter_paths.append(circle) sf = ShapeFiller(letter_paths) for path in sf.get_paths(4 * d.pen_type.pen_width / 5, angle=math.pi / 2): d.add_polyline(path)
def complex_fill(d): points = [] centre = (150, 50) sq = d.make_rect(centre, 20, 20) points = d.make_rotated_polyline(sq, centre, 13) sf = ShapeFiller(points) for path in sf.get_paths(4 * d.pen_type.pen_width / 5, angle=math.pi / 2): d.add_polyline(path)
def createtiles_tri(drawing, tile_size): delta = drawing.pen_type.pen_width * 1.1 # 1.5 # 0.75 diag = math.sqrt(2) shape = [Point(delta,delta), Point(delta,tile_size-delta), Point(tile_size-delta,delta)] sf = ShapeFiller([shape]) tile = sf.get_paths(row_width = drawing.pen_type.pen_width * 0.4) return [tile]
def draw_diamonds(d): paper_centre = Point(102.5, 148) paper_size = Point(192, 270) size = 10 lines = [] nr = 8 nc = 12 for r in range(0, nr): for c in range(0, nc): d_centre = paper_centre + Point(r - (nr-1)/2, c - (nc-1)/2) * size * 2 lines.append(make_diamond(d_centre, size)) line1 = make_diamond(d_centre, size/3) line2 = make_diamond(d_centre, size*2/3) sf = ShapeFiller([line1, line2]) fill = sf.get_paths(d.pen_type.pen_width * 0.4) lines.extend(fill) for r in range(0, nr-1): for c in range(0, nc-1): d_centre = paper_centre + Point(r - (nr-2)/2, c - (nc-2)/2) * size * 2 line1 = make_diamond(d_centre, size/2) line2 = make_diamond(d_centre, size*3/4) sf = ShapeFiller([line1, line2]) fill = sf.get_paths(d.pen_type.pen_width * 0.4) lines.extend(fill) line3 = make_diamond(d_centre, size/4) sf = ShapeFiller([line3]) fill = sf.get_paths(d.pen_type.pen_width * 0.4) lines.extend(fill) d.add_polylines(lines)
def fill_test(d): points = [] for j in range(0, 8): layer = d.add_layer(f'{j+1}-layer') for i in range(2, 11): tl = (20 + 20 * j, 20 + 20 * i) sq = d.make_rect(tl, 18, 18) sf = ShapeFiller([sq]) for path in sf.get_paths(i * d.pen_type.pen_width / 10): d.add_polyline(path, container=layer)
def draw_xor_circles_othello(drawing): paper_centre = Point(102.5, 148) n = 20 size = 6 all_paths = [] layer1 = drawing.add_layer("1-cyan") layer1_paths = [] for r in range(0, n+1): x = paper_centre.x + (r - n/2)*size # print(x) for c in range(0, n+1): shapes = [] y = paper_centre.y + (c - n/2)*size shapes.append(drawing.make_circle(Point(x,y), size/2)) if(random.random() > 0.5): sf = ShapeFiller(shapes) paths = sf.get_paths(drawing.pen_type.pen_width * 0.4) layer1_paths.extend(paths) square = drawing.make_square(Point(x - size/2, y - size/2), size) shapes.append(square) sf = ShapeFiller(shapes) paths = sf.get_paths(drawing.pen_type.pen_width * 0.4) all_paths.extend(paths) drawing.add_polylines(all_paths) drawing.add_polylines(layer1_paths, container=layer1, stroke=svgwrite.rgb(0, 255, 255, '%'))
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_inside_diamond(): shape = [Point(2, 1), Point(3, 2), Point(2, 3), Point(1, 2)] shapes = [shape] sf = ShapeFiller(shapes) # inside is inside assert (sf.is_inside(Point(2, 2))) # perimeter is outside assert (not sf.is_inside(Point(2, 1))) assert (not sf.is_inside(Point(3, 2))) assert (not sf.is_inside(Point(2, 4))) assert (not sf.is_inside(Point(1, 2))) # outside stuff is outside assert (not sf.is_inside(Point(0, 0))) assert (not sf.is_inside(Point(0, 4))) assert (not sf.is_inside(Point(4, 4))) assert (not sf.is_inside(Point(4, 0)))
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 test_split_edges_square(): shape = [Point(1, 1), Point(1, 3), Point(3, 3), Point(3, 1)] shapes = [shape] sf = ShapeFiller(shapes) assert (sf.split_edge_endpoints(Point(0, 1), Point( 4, 1)) == [Point(1, 1), Point(3, 1), Point(4, 1)]) assert (sf.split_edge_endpoints(Point(0, 2), Point( 4, 2)) == [Point(1, 2), Point(3, 2), Point(4, 2)]) assert (sf.split_edge_endpoints(Point(0, 3), Point( 4, 3)) == [Point(1, 3), Point(3, 3), Point(4, 3)]) assert (sf.split_edge_endpoints(Point(0, 0), Point(4, 0)) == [Point(4, 0)]) assert (sf.split_edge_endpoints(Point(0, 4), Point(4, 4)) == [Point(4, 4)])
def star_gen2(drawing): centre = Point(102.5, 148) size = 80 inner = 0 # 15 ratio = 0.7 size = (size - inner) * ratio + inner points = [(size, 0), (size, 0.5), (size, 1), (size, 1.5)] n = 5 for i in range(0, n): size = (size - inner) * ratio + inner ix = 0 while (ix < len(points)): a = points[ix] b = points[ix + 1] if ix + 1 < len(points) else (points[0], 2) new_angle = (a[1] + b[1]) / 2 new_elem = (size, new_angle) points.insert(ix + 1, new_elem) ix += 2 print(points) shape = [] sizes = [] for point in points: r = point[0] if r not in sizes: sizes.append(r) radians = math.pi * point[1] c = math.cos(radians) s = math.sin(radians) shape.append(Point(centre.x + r * c, centre.y + r * s)) shapes = [shape] sizes = sorted(sizes)[::-1] shapes.extend([drawing.make_circle(centre, size) for size in sizes[4:]]) # shapes.extend([drawing.make_circle(centre, size) for size in sizes[0:3]]) # shapes.extend([drawing.make_circle(centre, size-1) for size in sizes[0:3]]) # shapes.extend([drawing.make_circle(centre, size) for size in sizes]) # shapes.extend([drawing.make_circle(centre, size-1) for size in sizes]) r_inner = sizes[-1] - 1 while r_inner > 0: shapes.append(drawing.make_circle(centre, r_inner)) r_inner -= 1.1 sf = ShapeFiller(shapes) paths = sf.get_paths(drawing.pen_type.pen_width * 0.4) # , angle=math.pi/2) drawing.add_polylines(paths, container=drawing.add_layer("1"), stroke=svgwrite.rgb(100, 100, 0, '%')) # drawing.add_polylines([drawing.make_circle(centre, size) for size in sizes[0:3]]) layer2 = drawing.add_layer("2-dots") for point in points: r = point[0] radians = math.pi * point[1] c = math.cos(radians) s = math.sin(radians) dot_r = r / 20 centre_r = r + dot_r + 2 circle_centre = Point(centre.x + centre_r * c, centre.y + centre_r * s) if r > 15: drawing.add_dot(circle_centre, dot_r) r2 = dot_r # points[0][0] / 20 * ratio * ratio * ratio if r < points[0][0]: centre2_r = points[0][0] + r2 + 2 circle_centre2 = Point(centre.x + centre2_r * c, centre.y + centre2_r * s) drawing.add_dot(circle_centre2, r2, container=layer2) if r < points[0][0] * ratio: centre2_r = points[0][0] * ratio + r2 + 2 circle_centre2 = Point(centre.x + centre2_r * c, centre.y + centre2_r * s) drawing.add_dot(circle_centre2, r2, container=layer2) if r < points[0][0] * ratio * ratio: centre2_r = points[0][0] * ratio * ratio + r2 + 2 circle_centre2 = Point(centre.x + centre2_r * c, centre.y + centre2_r * s) drawing.add_dot(circle_centre2, r2, container=layer2)
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, '%'))
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 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 test_split_edges_diamond(): shape = [Point(8, 4), Point(12, 12), Point(8, 20), Point(4, 12)] shapes = [shape] sf = ShapeFiller(shapes) assert (sf.split_edge_endpoints(Point(0, 0), Point(16, 0)) == [Point(16, 0)]) assert (sf.split_edge_endpoints(Point(0, 4), Point(16, 4)) == [Point(8, 4), Point(16, 4)]) assert (sf.split_edge_endpoints(Point(0, 6), Point( 16, 6)) == [Point(7, 6), Point(9, 6), Point(16, 6)]) assert (sf.split_edge_endpoints(Point(0, 8), Point( 16, 8)) == [Point(6, 8), Point(10, 8), Point(16, 8)]) assert (sf.split_edge_endpoints(Point(0, 12), Point( 16, 12)) == [Point(4, 12), Point(12, 12), Point(16, 12)]) assert (sf.split_edge_endpoints(Point(0, 16), Point( 16, 16)) == [Point(6, 16), Point(10, 16), Point(16, 16)]) assert (sf.split_edge_endpoints(Point(0, 18), Point( 16, 18)) == [Point(7, 18), Point(9, 18), Point(16, 18)]) assert (sf.split_edge_endpoints(Point(0, 20), Point( 16, 20)) == [Point(8, 20), Point(16, 20)]) assert (sf.split_edge_endpoints(Point(0, 24), Point(16, 24)) == [Point(16, 24)])
def draw_3d_shade(d): cameraToWorld = numpy.identity(4) cameraToWorld[3][2] = 10 t = Transform3D(cameraToWorld, canvasWidth=2, canvasHeight=2, imageWidth=100, imageHeight=100) h = 1 s = 0.3 base_points = [(s, s, s, h), (s, -s, s, h), (-s, -s, s, h), (-s, s, s, h), (s, s, -s, h), (s, -s, -s, h), (-s, -s, -s, h), (-s, s, -s, h)] a = math.pi / 3 family = "Wingdings" letters = [x for x in "`¬!£$%&*()_+={:<>?@}~[;,./'#]"] letters = [x for x in "^_`abcdefghi"] family = 'Arial' letters = [x for x in "happy anniversary b xxx "] ix_letter = 0 for c in range(2, 7): for r in range(1, 5): scale = 0.75 dx = 0 + 25 * r dy = 0 + 25 * c a += math.pi / 30 letter = letters[ix_letter] ix_letter += 1 if ix_letter == len(letters): ix_letter = 0 # letter = "a" all_faces = [] world_points = [p for p in base_points] zc = 0 xc = 0 yc = 0 world_points = [(p[0] + xc, p[1] + yc, p[2] + zc, p[3]) for p in world_points] world_points = Transform3D.rotZ(world_points, a) world_points = Transform3D.rotX(world_points, a) world_points = [(p[0], p[1], p[2] + 8, p[3]) for p in world_points] faces3d = cube_open_faces(world_points) # should order by distance, nearest first # need to progressively clip this based upon the overall face projection # pass in the face drawing as a method? for face3d in faces3d: proj_face_points = t.project(face3d) # StandardDrawing.log(proj_face_points) if Transform3D.isForward(proj_face_points): if letter != " ": proj_face_lines = get_face_draw_text(d, t, face3d, letter, family=family) proj_face_lines = [[ (x[0] * scale + dx, x[1] * scale + dy) for x in proj_face_line ] for proj_face_line in proj_face_lines] sf = ShapeFiller(proj_face_lines) paths = sf.get_paths(d.pen_type.pen_width / 5 * 2) d.add_polylines(paths) proj_face_lines = get_face_draw_edge(t, face3d) proj_face_lines = [[(x[0] * scale + dx, x[1] * scale + dy) for x in proj_face_line] for proj_face_line in proj_face_lines] d.add_polylines(proj_face_lines)