def draw_line_with_colours(start_x, start_y, stop_x, stop_y, drawing: Drawing, colours): number_of_colours = len(colours) initial_offset = number_of_colours / 2 counter = 0 for colour in colours: x_diff = stop_x - start_x y_diff = stop_y - start_y offset = initial_offset - counter counter += 1 if x_diff == 0: drawing.append(draw.Line(start_x + offset, start_y, stop_x + offset, stop_y, stroke=colour, stroke_width=1)) else: y2 = 1 y1 = -(y_diff/x_diff) length = np.sqrt(y1 * y1 + y2) y1_norm = y1 / length y2_norm = y2 / length drawing.append(draw.Line(start_x + y1_norm * offset, start_y + y2_norm * offset, stop_x + y1_norm * offset, stop_y + y2_norm * offset, stroke=colour, stroke_width=1))
def drawFret(self, d: dsvg.Drawing, x: float, y: float, strings: int) -> float: fs = self.fretStyle fretBoardHeight = (strings - 1) * fs.fretHeight d.append( dsvg.Line(x, y, x, y - fretBoardHeight, stroke_width=stringWidth, stroke=stringColor)) return fs.fretWidth
def drawFretNumber(self, d: dsvg.Drawing, x: float, y: float) -> float: fs = self.fretStyle textY = y - fs.fontSize / 4.0 d.append( dsvg.Text(str(self.fretIndex), fs.fontSize, x + fs.circleX, textY, fill=fs.circleStrokeColor, center=False, text_anchor='middle')) return fs.fretWidth
def drawString(self, d: dsvg.Drawing, lowerFret: int, upperFret: int, x: float, y: float) -> float: fs = self.frets[0].fretStyle fretWidth = fs.fretWidth stringLength = (upperFret - lowerFret + 1) * fretWidth d.append( dsvg.Line(x, y, x + stringLength, y, stroke_width=stringWidth * pow(1.1, self.stringIndex), stroke=stringColor)) return fs.fretHeight
def test_scaled_arrow(svg_differ): expected_svg = Drawing(100, 35, origin=(0, 0)) expected_svg.append(Line(0, 10, 93, 10, stroke='black')) expected_svg.append(Circle(50, 20, 10, stroke='black', fill='ivory')) expected_svg.append( Text('2.3', 11, 50, 20, text_anchor='middle', dy="0.35em")) expected_svg.append( Lines(100, 10, 93, 13.5, 93, 6.5, 100, 10, fill='black')) f = Figure() f.add(Arrow(0, 200, h=20, elevation=-1, label='2.3')) svg = f.show(w=100) svg_differ.assert_equal(svg, expected_svg, 'test_arrow')
def drawHeading(self, d: dsvg.Drawing, baseNote: str, x: float, y: float) -> float: scaleName = self.subscribers[0].comboBoxScales.currentText() modeName = self.subscribers[0].comboBoxModes.currentText() heading = f"{baseNote} {scaleName}, Mode {modeName}" d.append( dsvg.Text(heading, headingFontSize, x, y, fill=headingColor, center=False, text_anchor='left')) return headingFontSize
def groove(drawing: draw.Drawing, group: np.ndarray, former_radius: float, inner_radius: float, wire_radius: float, style='normal') -> None: """ drawing: a drawSVG drawing object group: array representing wires in a single bundle former_radius: radius of coil former inner_radius: turn radius of innermost wire wire_radius: radius of a single wire, 32 AWG, etc... style: style of which to draw the grooves 'normal' denotes a square groove with rounding where the wires meet the coil former 'chamfer' denotes the same groove with a 60 degree chamfer on the upper edge for ease of 3d modeling Append a groove drawing to the canvas """ first_wire = group[0] # first wire in bundle r_ex = 0.05 # extra groove spacing n = len(group) p = draw.Path(stroke_width=0.01, stroke='black', fill='none') p.m(former_radius + r_ex, first_wire - wire_radius - r_ex) # starting point p.h(inner_radius - former_radius - r_ex) # horizontal line from starting point to lower-left of first wire if style == 'normal': if n == 1: p.arc(inner_radius, first_wire, wire_radius + r_ex, 270, 90, cw=True, includeM=False) # 180 degree arc around first wire else: p.arc(inner_radius, first_wire, wire_radius + r_ex, 270, 180, cw=True, includeM=False) # 90 degree arc around first wire p.v(2*(n-1)*wire_radius) # vertical line between wires of group p.arc(inner_radius, first_wire+2*(n-1)*wire_radius, wire_radius + r_ex, 180, 90, cw=True, includeM=False) # 90 degree arc around last wire p.h(former_radius + r_ex - inner_radius) # horizontal line from top-left of last wire to coil former if style == 'chamfer': if n == 1: p.arc(inner_radius, first_wire, wire_radius + r_ex, 270, 120, cw=True, includeM=False) p.l(former_radius + r_ex - inner_radius - (wire_radius + r_ex)*np.cos(2*np.pi/3), (former_radius + r_ex - inner_radius - (wire_radius + r_ex)*np.cos(2*np.pi/3))*np.tan(np.pi/6)) else: p.arc(inner_radius, first_wire, wire_radius + r_ex, 270, 180, cw=True, includeM=False) p.v(2*(n-1)*wire_radius) p.arc(inner_radius, first_wire+2*(n-1)*wire_radius, wire_radius + r_ex, 180, 120, cw=True, includeM=False) p.l(former_radius + r_ex - inner_radius - (wire_radius + r_ex)*np.cos(2*np.pi/3), (former_radius + r_ex - inner_radius - (wire_radius + r_ex)*np.cos(2*np.pi/3))*np.tan(np.pi/6)) p.Z() # connect last point to starting point, should always be a vertical line drawing.append(p)
def __init__(self, vertex_1: Vertex, vertex_2: Vertex, vertex_3: Vertex): self._vertices = {} self._edges = {} self._tiles = {} self._edges_to_tiles = {} self._tiles_to_colours = {} self._vertices_to_colours = {} self._boundary = [vertex_1, vertex_2, vertex_3] self._colour_values = ["#eeeeee", "#111111", "#bb9977", "#99bb77"] self._drawing = Drawing(2, 2, origin='center') self._drawing.setRenderSize(4096) self._populate_data()
def test_tiny_arrow_at_edge(svg_differ): expected_svg = Drawing(210, 35, origin=(0, 0)) expected_svg.append(Circle(197.5, 20, 10, stroke='black', fill='ivory')) expected_svg.append( Text('2.3', 11, 197.5, 20, text_anchor='middle', dy="0.35em")) expected_svg.append( Lines(200, 10, 195, 13.5, 195, 6.5, 200, 10, fill='black')) f = Figure() f.add(ArrowGroup([Arrow(195, 200, h=20, elevation=-1, label='2.3')])) svg = f.show() svg_differ.assert_equal(svg, expected_svg, 'test_arrow')
def drawNote(self, d: dsvg.Drawing, x: float, y: float) -> float: fs = self.fretStyle if self.individualMarked: textY = y - fs.fontSize / 4.0 d.append( dsvg.Circle(x + fs.circleX, y, fs.radius, fill=fs.circleFillColor, stroke_width=2, stroke=fs.circleStrokeColor)) d.append( dsvg.Text(self.noteName, fs.fontSize, x + fs.circleX, textY, fill=fs.circleStrokeColor, center=False, text_anchor='middle')) return fs.fretWidth
def start_drawing(width, height): expected_svg = Drawing(width, height, origin=(0, 0)) expected_svg.append( Rectangle(0, height - 15, 200, 10, stroke='lightgrey', fill='lightgrey')) expected_svg.append( Text('Header', 10, width / 2, height - 15, font_family='monospace', text_anchor='middle')) f = Figure() f.add(Track(0, width, label='Header')) return f, expected_svg
theta1, theta2 = math.pi * 2 / p1, math.pi * 2 / p2 phiSum = math.pi * 2 / q r1 = triangleSideForAngles(theta1 / 2, phiSum / 2, theta2 / 2) r2 = triangleSideForAngles(theta2 / 2, phiSum / 2, theta1 / 2) tGen1 = htiles.TileGen.makeRegular(p1, hr=r1, skip=1) tGen2 = htiles.TileGen.makeRegular(p2, hr=r2, skip=1) decorator1 = TileDecoratorFish(p1, p2, q) tLayout = TileLayoutFish() tLayout.addGenerator(tGen1, ((0, 1) * 10)[:p1], decorator1) tLayout.addGenerator(tGen2, ((0, 1, 2) * 10)[:p2], htiles.TileDecoratorNull()) startTile = tLayout.startTile(code=0, rotateDeg=rotate) tiles = tLayout.tilePlane(startTile, depth=depth) d = Drawing(2, 2, origin='center') d.draw(euclid.shapes.Circle(0, 0, 1), fill='silver') for tile in tiles: d.draw(tile, layer=0) for tile in tiles: d.draw(tile, layer=1) for tile in tiles: d.draw(tile, layer=2) d.setRenderSize(w=400) d.saveSvg('Tess02.svg') #Rest of code I already commented in Tess01
def drawing_to_image(drawing: Drawing) -> Image: png = drawing.rasterize() png_bytes = BytesIO(png.pngData) image = Image.open(png_bytes) return image
class Tiling: def __init__(self, vertex_1: Vertex, vertex_2: Vertex, vertex_3: Vertex): self._vertices = {} self._edges = {} self._tiles = {} self._edges_to_tiles = {} self._tiles_to_colours = {} self._vertices_to_colours = {} self._boundary = [vertex_1, vertex_2, vertex_3] self._colour_values = ["#eeeeee", "#111111", "#bb9977", "#99bb77"] self._drawing = Drawing(2, 2, origin='center') self._drawing.setRenderSize(4096) self._populate_data() def _populate_data(self): for index, vertex in enumerate(self._boundary): self._vertices[vertex] = vertex edge = Edge(*tuple(set(self._boundary) - {vertex})) self._edges[edge] = edge self._vertices_to_colours[vertex] = index + 1 tile = Tile(*self._boundary) self._tiles[tile] = tile self._tiles_to_colours[tile] = 0 for edge in self._edges: self._edges_to_tiles[edge] = {tile} self._drawing.draw( tile, fill=self._colour_values[self._tiles_to_colours[tile]]) def _build_new_tile(self, vertex_1: Vertex, vertex_2: Vertex) -> Vertex: edge = self._edges[Edge(vertex_1, vertex_2)] #assert len(self._edges_to_tiles[edge]) == 1 inner_tile = tuple(self._edges_to_tiles[edge])[0] inner_vertex = tuple(inner_tile.vertices - {vertex_1, vertex_2})[0] reflected_vertex = Line.from_points(vertex_1, vertex_2).reflection(inner_vertex) reflected_vertex = self._add_vertex(reflected_vertex) self._add_edge(Edge(vertex_1, reflected_vertex)) self._add_edge(Edge(vertex_2, reflected_vertex)) new_tile = self._add_tile(Tile(vertex_1, reflected_vertex, vertex_2)) self._vertices_to_colours[ reflected_vertex] = self._vertices_to_colours[inner_vertex] self._tiles_to_colours[new_tile] = self._vertices_to_colours[ inner_vertex] ^ self._tiles_to_colours[inner_tile] self._drawing.draw( new_tile, fill=self._colour_values[self._tiles_to_colours[new_tile]]) return reflected_vertex def _add_vertex(self, vertex: Vertex) -> Vertex: if vertex not in self._vertices: self._vertices[vertex] = vertex return self._vertices[vertex] def _add_edge(self, edge: Edge): if edge not in self._edges: self._edges[edge] = edge self._edges_to_tiles[edge] = set() def _add_tile(self, tile: Tile): if tile not in self._tiles: self._tiles[tile] = tile tile = self._tiles[tile] edge_1 = self._edges[Edge(tile.vertex_2, tile.vertex_3)] edge_2 = self._edges[Edge(tile.vertex_3, tile.vertex_1)] edge_3 = self._edges[Edge(tile.vertex_1, tile.vertex_2)] self._edges_to_tiles[edge_1].add(tile) self._edges_to_tiles[edge_2].add(tile) self._edges_to_tiles[edge_3].add(tile) return tile def _draw(self, depth: int): with open('images/logo-depth-{}-data.json'.format(depth), 'w') as f: json.dump([path.args for path in self._drawing.elements], f, indent=2) self._drawing.saveSvg('images/logo-depth-{}.svg'.format(depth)) def create_tiles(self, depth: int): if depth == 0: self._draw(depth) return self.create_tiles(depth=depth - 1) print(f"Populating depth {depth}...") new_boundary = [ self._build_new_tile(self._boundary[0], self._boundary[-1]) ] index = 0 counter = 0 num_tiles = (3 * sqrt(3) * ((2 + sqrt(3))**depth - (2 - sqrt(3))**depth)).as_int() while True: new_vertex = self._build_new_tile(new_boundary[-1], self._boundary[index]) counter += 1 print(f"created {counter} / {num_tiles} tiles...", end="\r") if new_vertex in self._boundary: index += 1 elif new_vertex in new_boundary: break else: new_boundary.append(new_vertex) self._boundary = new_boundary self._draw(depth) print(f"Populated, found {len(self._tiles)} tiles")
print("Channels: %d"%(channels)) except IndexError: channels = 1 print("Channels: 1") # if outfile is directory, write frames, else one big stripe if os.path.isdir(args.outfile): for n, b in enumerate(chunks(data, blocksize)): padded = "{0:06d}".format(n) if len(b) < blocksize: b = np.lib.pad(b, ((blocksize-len(b)) // 2), 'constant') if args.multichannel and channels > 1: reflect = [(1,1), (-1,1), (1,-1), (-1,-1)] for i in range(channels - 1): drawing = Drawing(args.width, args.height) drawing = drawSamples(drawing, b.T[i], args.width, args.height) else: if channels > 1: b = b.T[0] drawing = Drawing(args.width, args.height) drawing = drawSamples(drawing, b, args.width, args.height) sys.stdout.write('frame: %s' % padded) sys.stdout.flush() sys.stdout.write("\b" * 13) drawing.saveSvg( os.path.join("%s/%s.svg" % (args.outfile, padded)) ) else: if args.multichannel and channels > 1:
path.Z() return path def render(self, drawing=None, thickness=1.0): drawing = drawing or Drawing(self.width, self.height, origin=(0, 0)) drawing.append(self.render_path(thickness)) return drawing if __name__ == '__main__': try: nodes = int(sys.argv[1]) except (ValueError, IndexError): nodes = 23 flash = Flash() flashes = [flash] current = 0 for _ in range(nodes): if flash.current_point().within_perimeter(flash.end, 10): flash = Flash() flashes.append(flash) current += 1 flash.random_walk() drawing = Drawing(500, 500, origin=(0, 0)) for flash in flashes: drawing.append(flash.render_path()) drawing.saveSvg('/tmp/flash.svg')
def draw_schedule(g, model, filename): zeta, chi, duration, label = model TOP = 30 BOTTOM = 30 LEFT = 100 RIGHT = 30 WIDTH = 800 HEIGHT = 800 ROW_OFFSET = 20 TEXT_OFFSET = 40 FONTSIZE = 30 d = Drawing(WIDTH, HEIGHT) d.append(Rectangle(0, 0, WIDTH, HEIGHT, fill='white')) N_tasks = g.num_vertices() N_rounds = len(zeta) - N_tasks min_t = min(zeta[:N_tasks] - g.vertex_properties['durations'].get_array()) max_t = max(zeta) quantum = (WIDTH - RIGHT - LEFT) / (max_t - min_t) block_height = (HEIGHT - TOP - BOTTOM - ROW_OFFSET * (N_tasks)) / (N_tasks + 1) for i in range(N_tasks): color = list(Color('red').range_to('green', 1000))[max( 0, int(g.vertex_properties['soft'][i] * 999))] d.append( Rectangle(quantum * abs(min_t) + LEFT + quantum * (zeta[i] - g.vertex_properties['durations'][i]), HEIGHT - TOP - ROW_OFFSET * i - block_height * (i + 1), quantum * g.vertex_properties['durations'][i], block_height, fill=color.get_hex_l(), stroke_width=2, stroke='black')) if g.vertex_properties['deadlines'][i] >= 0: x = quantum * abs(min_t) + LEFT + quantum * ( g.vertex_properties['deadlines'][i]) d.append( Line(x, HEIGHT - TOP - ROW_OFFSET * i - block_height * (i + 1), x, HEIGHT - TOP - ROW_OFFSET * i - block_height * i, stroke_width=4, stroke='purple')) d.append( Text(str(i), FONTSIZE, TEXT_OFFSET, HEIGHT - TOP - ROW_OFFSET * i - block_height * (i + 1) + block_height / 2, center=True, fill='black')) for i in range(N_rounds): if duration[i] == 0: continue d.append( Rectangle(quantum * abs(min_t) + LEFT + quantum * (zeta[N_tasks + i] - duration[i]), HEIGHT - TOP - ROW_OFFSET * N_tasks - block_height * (N_tasks + 1), quantum * duration[i], block_height, fill='gray', stroke_width=2, stroke='black')) d.append( Text('LWB', FONTSIZE, TEXT_OFFSET, HEIGHT - TOP - ROW_OFFSET * N_tasks - block_height * (N_tasks + 1) + block_height / 2, center=True, fill='black')) d.savePng(filename)
for tile in tiles: d.draw(tile, hwidth=0.2, fill="white") for tile in tiles: d.draw(tile, drawVerts=True, hradius=0.3, hwidth=0.2, fill="black", opacity=0.6) t1 = 4 t2 = 3 s = 3 theta1, theta2 = math.pi*2/t1, math.pi*2/t2 phiSum = math.pi*2/s r1 = triangleSideForAngles((1/2)*(theta1, phiSum, theta2) r2 = triangleSideForAngles((1/2)*(theta2, phiSum, theta1) tile_generator1 = htiles.TileGen.makeRegular(t1, hr=r1, skip=1) tile_generator2 = htiles.TileGen.makeRegular(t2, hr=r2, skip=1) tile_layout = htiles.TileLayout() tile_layout.addGenerator(tile_generator1, (1,)*t1) tile_layout.addGenerator(tile_generator2, (0,)*t2) starting_tile = tile_layout.defaultStartTile(rotateDeg=45) tiles = tile_layout.tilePlane(starting_tile, depth=5) d = Drawing(4, 4, origin='center') d.draw(euclid.shapes.Circle(0,0,4), fill='blue') drawTiles(d, tiles) d.setRenderSize=(w=400) d.saveSvg('images/tileTriangleSquare.svg')
def assert_equal(self, svg_actual: Drawing, svg_expected: Drawing, name: str): png_actual = drawing_to_image(svg_actual) png_expected = drawing_to_image(svg_expected) w = max(png_actual.width, png_expected.width) h = max(png_actual.height, png_expected.height) png_actual_padded = Image.new(png_actual.mode, (w, h)) png_expected_padded = Image.new(png_expected.mode, (w, h)) png_actual_padded.paste(png_actual) png_expected_padded.paste(png_expected) png_diff = Image.new(png_actual.mode, (w, h)) self.mismatch_found = False png_diff.putdata([ self.diff_pixel(actual_pixel, expected_pixel) for actual_pixel, expected_pixel in zip( png_actual_padded.getdata(), png_expected_padded.getdata()) ]) # Display image when in live turtle mode. display_image = getattr(Turtle, 'display_image', None) if display_image is not None: t = Turtle() try: # noinspection PyUnresolvedReferences w = t.screen.cv.cget('width') # noinspection PyUnresolvedReferences h = t.screen.cv.cget('height') ox, oy = w / 2, h / 2 text_height = 20 t.penup() t.goto(-ox, oy) t.right(90) t.forward(text_height) t.write(f'Actual') display_image(ox + t.xcor(), oy - t.ycor(), image=encode_image(png_actual)) t.forward(png_actual.height) t.forward(text_height) t.write(f'Diff') display_image(ox + t.xcor(), oy - t.ycor(), image=encode_image(png_diff)) t.forward(png_diff.height) t.forward(text_height) t.write('Expected') display_image(ox + t.xcor(), oy - t.ycor(), image=encode_image(png_expected)) t.forward(png_expected.height) except Exception as ex: t.write(str(ex)) if not self.mismatch_found: return text_actual = svg_actual.asSvg() (self.work_dir / (name + '_actual.svg')).write_text(text_actual) text_expected = svg_expected.asSvg() (self.work_dir / (name + '_expected.svg')).write_text(text_expected) with (self.work_dir / (name + '_diff.png')) as f: png_diff.save(f) assert text_actual == text_expected
meta, data = loadwav(args.soundfile) print("Samplerate: %d" % meta.rate) print("Channels: %d" % meta.channels) print("Length: %d samples, %d seconds" % (meta.samples, meta.seconds)) blocksize = meta.rate // args.fps blocks = meta.samples // blocksize print("%d Frames at %d samples" % (blocks, blocksize)) N = blocksize T = 1.0 / blocksize * 1.25 for n, b in enumerate(audio_chunks(data, blocksize)): padded = "{0:03d}".format(n) drawing = Drawing(args.width, args.height, origin=(0, 0)) if args.multichannel and meta.channels > 1: reflect = [(1, 1), (-1, 1), (1, -1), (-1, -1)] for i in range(meta.channels - 1): scene = render_frame(drawing, spectrum(b.T[i]), plotter='osci', width=args.width, height=args.height) else: if meta.channels > 1: b = b.T[0] scene = render_frame(drawing, spectrum(b), plotter='osci', width=args.width,
def drawBagel(text: str, text2: str, fontSize: int = 13, textColor: str = '#FFF', leftColor: str = '#555', rightColor: str = '#08C', spacing: int = 10, height: int = 20, fontName: str = None) -> str: spacing = max(spacing, 3) height = max(20, height) fontSize = max(round(height * 0.5), max(round(height * 0.75), fontSize)) s = settings() s.ReadSettings() if fontName is None: fontName = s.defaultSvgFont fontFamily = 'sans-serif' else: fontFamily = fontName t1w = textwidth(text, fontSize, fontName) t2w = textwidth(text2, fontSize, fontName) zw = 4 * spacing + t1w + t2w d = Drawing(zw, height) if fontForgeSupported and 'sans-serif' != fontFamily: css = generateFontCSS(fontName, text + text2, genFlags=ASCII_SUPPORT) if css is not None: d.append(Style(css)) m = Mask(id="m") d.append(m) rx = round(height * 0.15) m.append(Rectangle(0, 0, zw, height, fill='#FFF', rx=rx, ry=rx)) g1 = Group(mask="url(#m)") g1.append(Rectangle(0, 0, 2 * spacing + t1w, height, fill=leftColor)) g1.append(Rectangle(2 * spacing + t1w, 0, zw, height, fill=rightColor)) d.append(g1) g2 = Group(aria_hidden="true", fill=textColor, text_anchor='start', font_family=fontFamily) g2.append(Text(text, fontSize, spacing, height - fontSize, textLength=t1w)) g2.append( Text(text2, fontSize, 3 * spacing + t1w, height - fontSize, textLength=t2w)) d.append(g2) return d.asSvg().replace('\n', '')
def render(self, drawing=None, thickness=1.0): drawing = drawing or Drawing(self.width, self.height, origin=(0, 0)) drawing.append(self.render_path(thickness)) return drawing
edges = [] for i, point in enumerate(points): v1 = vertices[i] v2 = vertices[(i + 1) % p1] edge = Hypercycle.fromPoints(*v1, *v2, *point, segment=True, excludeMid=True) edges.append(edge) decoratePoly = Polygon(edges=edges, vertices=vertices) decorator1 = htiles.TileDecoratorPolygons(decoratePoly) tLayout.setDecorator(decorator1, 0) startTile = tLayout.defaultStartTile(rotateDeg=rotate) tiles = tLayout.tilePlane(startTile, depth=6) d = Drawing(2, 2, origin='center') #d.draw(euclid.shapes.Circle(0, 0, 1), fill='silver') for tile in tiles: d.draw(tile, hwidth=0.05, fill='green') tiles[0].decorator = None d.draw(Hypercycle.fromPoints(*tiles[0].vertices[0], *tiles[0].vertices[1], *pointBase), hwidth=0.05, fill='black') d.setRenderSize(w=300) d.saveSvg('Tess03.svg') d