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 render(self, size, start_a=0): stack = [] pos = Point(0, 0) all_lines = [] current_line = [pos] a = start_a for instruction in self.instructions: if instruction[0] == "F": radians = a / 360 * 2 * math.pi pos = pos + Point(math.cos(radians), math.sin(radians)) * size current_line.append(pos) elif instruction[0] == "A": a += instruction[1] elif instruction[0] == "PUSH": stack.append((pos, a)) elif instruction[0] == "POP": if len(current_line) > 1: all_lines.append(current_line) (pos, a) = stack.pop() current_line = [pos] else: print(self.instructions) raise Exception(f'Unknown code: {instruction[0]}') if len(current_line) > 1: all_lines.append(current_line) return all_lines
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 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 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 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 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 test_sort(): n = 100 unsorted = [[Point(0, i), Point(10, i)] for i in range(0, n)] sorted = StandardDrawing.sort_polylines_new(unsorted) print("hi") print(sorted) assert (False)
def draw_hash(d): side = 20 gap = 2 draw_hash_squares(d, Point(30, 30), side, gap, 1) draw_hash_squares(d, Point(30, 80), side, gap, 2) draw_hash_squares(d, Point(30, 130), side, gap, 3) draw_hash_squares(d, Point(30, 180), side, gap, 4) draw_hash_squares(d, Point(30, 230), side, gap, 5)
def draw_hash3(d): side = 20 gap = 2 draw_hash_squares3(d, Point(30, 30), side, gap, 0.4) draw_hash_squares3(d, Point(30, 80), side, gap, 0.55) draw_hash_squares3(d, Point(30, 130), side, gap, 0.7) draw_hash_squares3(d, Point(30, 180), side, gap, 0.85) draw_hash_squares3(d, Point(30, 230), side, gap, 1.0)
def draw_hash2(d): side = 20 gap = 2 draw_hash_squares2(d, Point(30, 30), side, gap, 0.5) draw_hash_squares2(d, Point(30, 80), side, gap, 0.75) draw_hash_squares2(d, Point(30, 130), side, gap, 1) draw_hash_squares2(d, Point(30, 180), side, gap, 1.25) draw_hash_squares2(d, Point(30, 230), side, gap, 1.5)
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 test_bounds(d): paper_centre = Point(102.5, 148) paper_size = Point(192, 270) topleft = paper_centre - paper_size / 2 polyline = [ topleft, topleft + Point(0, paper_size.y), topleft + paper_size, topleft + Point(paper_size.x, 0), topleft ] d.add_polyline(polyline)
def get_face_draw_edge(t, face3d): proj_face_lines = [] line_count = 10 origin = face3d[0] endx = face3d[1] endy = face3d[3] diffx = (endx[0] - origin[0], endx[1] - origin[1], endx[2] - origin[2]) diffy = (endy[0] - origin[0], endy[1] - origin[1], endy[2] - origin[2]) line1 = [] line2 = [] line3 = [] # surround = [Point(0, 0), Point(0, 1), Point(1, 1), Point(1, 0), Point(0, 0)] surround = [ Point(0, 0.05), Point(0, 0.95), Point(0.05, 1), Point(0.95, 1), Point(1, 0.95), Point(1, 0.05), Point(0.95, 0), Point(0.05, 0), Point(0, 0.05) ] lines = [surround] # lines.append(surround) face_lines = [[(origin[0] + diffx[0] * p.x + diffy[0] * p.y, origin[1] + diffx[1] * p.x + diffy[1] * p.y, origin[2] + diffx[2] * p.x + diffy[2] * p.y, 1.0) for p in line] for line in lines] for face_line in face_lines: proj_face_line = t.project(face_line) proj_face_lines.append(proj_face_line) return proj_face_lines
def test_point_dist(): pt1 = Point(0, 1) assert (1 == pt1.dist()) pt2 = Point(1, 0) assert (1 == pt2.dist()) pt3 = Point(3, 4) assert (5 == pt3.dist())
def createtiles_semi(drawing, tile_size): circumference = tile_size * math.pi * 2 sections = circumference / drawing.pen_type.pen_width n = int(sections / 4) path0 = [] path1 = [] for i in range(0, n+1): a = math.pi * i / (2*n) path0.append(Point(math.cos(a), math.sin(a)) * tile_size / 2) path1.append(Point(tile_size, tile_size) - Point(math.cos(a), math.sin(a)) * tile_size / 2) return [[path0, path1]]
def draw_riley_backoff_test(drawing): nslice = 40 polylines = [] centre = Point(22.5, 18) scale = 1 for i in [3,4]: # range(3, 10): # 0, nslice): b = CircleBlock(centre + Point(5, 5)*scale, 38*scale, 0.06, centre + Point(-6, 2)*scale, 22*scale, -0.04, 2 * nslice, i * 2 + 1) path = drawing.fill_in_paths(b.path_gen_f) drawing.add_polyline(path[::-1])
def spiral_moire2(drawing): centre = Point(102.5, 148) scale = 80 factor = 3 side = 2 h = side * 0.5 * math.sqrt(3) base_width = drawing.pen_type.pen_width drawing.add_spiral(centre + Point(0, 0), scale, r_per_circle = (factor*1.00) * base_width) drawing.add_spiral(centre + Point(0, 5), scale, r_per_circle = (factor*1.09) * base_width)
def createtiles_truchet(drawing, tile_size, nlines=None): circumference = tile_size * math.pi * 2 sections = circumference / drawing.pen_type.pen_width n = int(sections / 4) nlines = 5 if nlines is None else nlines tile_paths0 = [] for i in range(0, nlines+1): path = [Point(tile_size * i / nlines, 0), Point(tile_size * i / nlines, tile_size)] tile_paths0.append(path) tiles_roundonly = createtiles_truchet_roundonly(drawing, tile_size, nlines) return [tile_paths0, tiles_roundonly[0]]
def spirograph2(drawing): paper_centre = Point(102.5, 148) r = [80, 25, 2, 1] s = [1, -1, 1, -1] add_spirograph(drawing, paper_centre, r, s, scale=0.35) add_spirograph(drawing, paper_centre, r, s, scale=1)
def spirograph5(drawing): paper_centre = Point(102.5, 148) r = [70, 3, 2, 1] s = [1, -1, 1, -1] add_spirograph(drawing, paper_centre, r, s, scale=1, stroke=svgwrite.rgb(100, 0, 0, '%'), container=drawing.add_layer("1")) r = [60, 22, 3, 1] s = [1, -1, 1, -1] add_spirograph(drawing, paper_centre, r, s, scale=1, stroke=svgwrite.rgb(0, 0, 0, '%'), container=drawing.add_layer("2")) r = [13, 7, 1, 0] s = [1, -1, 1, -1] add_spirograph(drawing, paper_centre, r, s, scale=1, stroke=svgwrite.rgb(50, 0, 0, '%'), container=drawing.add_layer("3"))
def spirograph10(drawing): paper_centre = Point(102.5, 148) strokes = [ svgwrite.rgb(100, 100, 0, '%'), svgwrite.rgb(0, 100, 100, '%'), svgwrite.rgb(100, 0, 100, '%') ] layers = [ drawing.add_layer("1"), drawing.add_layer("2"), drawing.add_layer("3") ] n = 0 for outer in range(10, 75): n += 1 n = n % 3 r = [outer, 3, 0, 0] s = [1, 1, -1, 1] add_spirograph(drawing, paper_centre, r, s, scale=1, stroke=strokes[n], container=layers[n])
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 add_spirograph(drawing, centre, r, s, scale, container=None, stroke=None): def gcd(a, b): """Compute the greatest common divisor of a and b""" while b > 0: a, b = b, a % b return a def lcm(a, b): """Compute the lowest common multiple of a and b""" return a * b / gcd(a, b) a = [0 for _ in r] a_inc = drawing.pen_type.pen_width / r[0] path = [] # need enough incr so both have whole # of rotations x = [max(rx, 1) for rx in r] n1 = lcm(lcm(lcm(x[0], x[1]), x[2]), x[3]) / r[0] circ1 = math.pi * 2 / a_inc limit = int(n1 * circ1) + 10 for i in range(0, limit): a[0] += s[0] * a_inc * r[0] / x[0] a[1] += s[1] * a_inc * r[0] / x[1] a[2] += s[2] * a_inc * r[0] / x[2] a[3] += s[3] * a_inc * r[0] / x[3] p = centre for j in range(0, 4): pt = Point(math.cos(a[j]), math.sin(a[j])) mult = 0 for k in range(j, 4): mult += r[k] * s[k] pt = pt * mult * s[j] p = p + pt * scale path.append(p) drawing.add_polyline(path, container=container, stroke=stroke)
def spirograph1(drawing): paper_centre = Point(102.5, 148) r = [80, 35, 8, 2] s = [1, -1, 1, -1] add_spirograph(drawing, paper_centre, r, s, scale=0.2) add_spirograph(drawing, paper_centre, r, s, scale=1)
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 test_line_colour(d): base_pos = Point(20, 20) size = 14 gap = 16 diff = d.pen_type.pen_width * 0.9 layers = [d.add_layer(f"{i+1}") for i in range(0, 10)] for i in range(0, 10): for j in range(i, 10): sq_pos = base_pos + Point(i * gap, j * gap) k = 0 while diff * k < size: ix_layer = i if k % 2 == 0 else j layer = layers[ix_layer] pos = sq_pos + Point(diff * k, 0) d.add_polyline([pos, pos + Point(0, size)], container=layer) k += 1
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)