def plot_data(self, column_pos, max_value, min_value): for item in self.data: gene = item[0] sample_name = item[1] real_value = item[2] if self.log_graph: value = log10(real_value) if real_value < 1: continue else: value = real_value colour = self.legend[sample_name]['colour'] cirlce_obj = Circle( center=(column_pos[gene], self.margin_top + self.plottable_y - self.scale_y(value, max_value, min_value)), r=3, stroke_width=0.1, stroke_linecap='round', stroke_opacity=1, fill=colour, fill_opacity=0.6) # set to 0.2 if you want to show clear. cirlce_obj.set_desc( f"{sample_name} - {self.legend[sample_name]['category']} - {round(real_value)}" ) self.plot.add(cirlce_obj)
def _define_one_symbol(self): dot = Symbol(id="dot") dot.add(Circle(center=(0, 0), r=self.dimens.stroke_width * 0.4, fill="black", stroke="none")) self.dwg.defs.add(dot) one = Symbol(id="one", class_="bit-1", stroke_width=1, stroke="black") one.add(Circle(center=(0, 0), r=self.dimens.bit_radius, fill="none", stroke="none")) empty_face_symbol = Symbol(id="empty_face") light_face_symbol = Symbol(id="light_face") dense_face_symbol = Symbol(id="dense_face") points = ["{} {}".format( self.dimens.bit_radius * math.sin(2 * math.pi * v / self.poly.num_vertices), self.dimens.bit_radius * math.cos(2 * math.pi * v / self.poly.num_vertices) ) for v in range(0, 3)] data = ['M', "0 0 L", *points, 'Z'] path = Path(data, fill="none", stroke_linejoin="bevel") empty_face_symbol.add(path) light_face_symbol.add(path) dense_face_symbol.add(path) x0 = 0 x1 = self.dimens.bit_radius * math.sin(2 * math.pi * 2 / self.poly.num_vertices) y0 = self.dimens.bit_radius * math.cos(2 * math.pi * 2 / self.poly.num_vertices) y1 = self.poly.outer_circle_radius * self.dimens.bit_radius w = x1 - x0 h = y1 - y0 h_rect = y1 num_dense = 200 num_light = int(num_dense / 2) points = np.apply_along_axis( lambda p: np.array([p[0] * w, p[1] * h_rect + p[0] * y0]), 1, np.clip( i4_sobol_generate(2, num_dense) + np.random.rand(num_dense, 2) / h, 0, 1 )) for p in points[:num_light]: light_face_symbol.add(Use(dot.get_iri(), (p[0], p[1]))) dense_face_symbol.add(Use(dot.get_iri(), (p[0], p[1]))) for p in points[num_light:]: dense_face_symbol.add(Use(dot.get_iri(), (p[0], p[1]))) self.dwg.defs.add(empty_face_symbol) self.dwg.defs.add(light_face_symbol) self.dwg.defs.add(dense_face_symbol) f1 = Use(empty_face_symbol.get_iri()) one.add(f1) f2 = Use(dense_face_symbol.get_iri()) f2.rotate(120) one.add(f2) f3 = Use(light_face_symbol.get_iri()) f3.rotate(240) one.add(f3) self.dwg.defs.add(one)
def _draw_grid(self, drw, board_size, stone_size): #todo: уметь рисовать переданный фон from_grid_to_edge = stone_size / 2 + self._margin grid = drw.add(drw.g(id='grid', stroke=svgwrite.rgb(0, 0, 0))) for i in range(board_size): grid.add( drw.line( start=((from_grid_to_edge - self._line_width / 2) * self.unit, (i * stone_size + from_grid_to_edge) * self.unit), end=((SvgDiagramBuilder.picture_size - from_grid_to_edge + self._line_width / 2) * self.unit, (i * stone_size + from_grid_to_edge) * self.unit), stroke_width=self._line_width * self.unit)) grid.add( drw.line( start=((i * stone_size + from_grid_to_edge) * self.unit, (from_grid_to_edge - self._line_width / 2) * self.unit), end=((i * stone_size + from_grid_to_edge) * self.unit, (SvgDiagramBuilder.picture_size - from_grid_to_edge + self._line_width / 2) * self.unit), stroke_width=self._line_width * self.unit)) for point in self._get_dot_points(board_size): grid.add( Circle((((point[0] - 1) * stone_size + from_grid_to_edge) * self.unit, ((point[1] - 1) * stone_size + from_grid_to_edge) * self.unit), self._line_width * 2.5 * self.unit, fill=svgwrite.rgb(0, 0, 0)))
def _define_zero_symbol(self): zero = Symbol(id="zero", class_="bit-0", stroke_width=1, stroke="black", fill="none") zero.add(Circle(center=(0, 0), r=self.dimens.bit_radius, fill="none", stroke="none")) r = 0.75 n = self.poly.num_vertices for i in range(n): vertex = Point( self.dimens.bit_radius * math.sin(2 * math.pi * i / n), self.dimens.bit_radius * math.cos(2 * math.pi * i / n)) previous_vertex = Point( self.dimens.bit_radius * math.sin(2 * math.pi * (i + n - 1) / n), self.dimens.bit_radius * math.cos(2 * math.pi * (i + n - 1) / n)) start_point = Point( (1 - r) * previous_vertex.x + r * vertex.x, (1 - r) * previous_vertex.y + r * vertex.y ) next_vertex = Point( self.dimens.bit_radius * math.sin(2 * math.pi * (i + n + 1) / n), self.dimens.bit_radius * math.cos(2 * math.pi * (i + n + 1) / n)) end_point = Point( (1 - r) * next_vertex.x + r * vertex.x, (1 - r) * next_vertex.y + r * vertex.y ) line = Polyline([start_point, vertex, end_point], stroke_linejoin="bevel") zero.add(line) self.dwg.defs.add(zero)
def _put_stone(self, cell, x, y, stone, stone_size): #todo: уметь рисовать камни переданные изображениеми fill = "white" if stone == Stone.White else "black" cell.add( Circle((x * self.unit, y * self.unit), stone_size / 2 * self.unit, stroke="black", fill=fill, stroke_width=self._line_width / 5))
def get_runner_end(self, line, is_out): x, y = self.get_line_end(line) if is_out: g = Group() g['class'] = 'out' g.add(Line((x - X_SIZE, y - X_SIZE), (x + X_SIZE, y + X_SIZE))) g.add(Line((x - X_SIZE, y + X_SIZE), (x + X_SIZE, y - X_SIZE))) return g else: return Circle((x, y), CIRCLE_R)
def render(self): # Semicircles computation visited = {0} for multiple in range(2, self.circles): origin_x = 0 target_x = multiple color = 'black' while target_x <= self.iterations: if origin_x == 0 and target_x not in visited : direction = '-' color = 'red' else: direction = '+' semicircle = Semicircle((origin_x, 0), (target_x, 0), angle_dir=direction) semicircle.stroke(color, width=.6, opacity=.25) semicircle.fill('none') self.add(semicircle) visited.add(target_x) origin_x += multiple target_x += multiple # Number line for i in range(self.iterations + 1): circle = Circle((i, 0), .25) circle.stroke('black', width=.1) circle.fill('white') self.add(circle) self.stretch() self.save()
def hole(self, end, drillSize): if self.enable: if self.svg is not None: self.path.push('L', self.scaleOffset(end)) # dprt("svg line %7.4f %7.4f" % self.scaleOffset(end)) self.svg.add(Circle(self.scaleOffset(end), \ (drillSize / 2) * self.pScale, \ stroke='black', stroke_width=.5, \ fill="none")) if self.d is not None: self.d.add(dxf.line(self.last, end, layer=self.lPath)) self.d.add(dxf.circle(drillSize / 2, end, layer=self.lHole)) self.last = end
def draw_background(drawing): rad = RadialGradient(center=("50%", "50%"), r="50%", focal=("50%", "50%")) rad.add_stop_color(offset="0%", color="rgb(170,170,170)", opacity="1") rad.add_stop_color(offset="90%", color="rgb(0,0,0)", opacity="1") drawing.defs.add(rad) size = max(WIDTH, HEIGHT) / 1.25 c = Circle(center=(WIDTH / 2, HEIGHT / 2), r=size, fill=rad.get_paint_server()) drawing.add(c)
def generate_straight_stroke(self, paths): # sort the paths by the distance to the upper right corner bbox = overall_bbox(paths) write_debug( "stroke_travel", [(Path(*paths), "none", (0, 0, 0)), (Circle(center=(bbox[0], bbox[2]), r=1, fill=rgb( 255, 0, 0)), "none", "none")]) # discretize the paths points = [] for i, path in enumerate(paths): if path.length() == 0: continue points.append(path.start * self.scale) num_segments = ceil(path.length() / MINIMUM_STITCH_LENGTH) for seg_i in range(int(num_segments + 1)): points.append(path.point(seg_i / num_segments) * self.scale) # if the next stitch doesn't start at the end of this stitch, add that one as # well end_stitch = path.end * self.scale if i != len(paths) - 1: if path.end != paths[i + 1].start: points.append(end_stitch) else: points.append(end_stitch) if len(points) == 0: return # find the point closest to the last stitch if not self.last_stitch: last_stitch = points[0] else: last_stitch = self.last_stitch.x + self.last_stitch.y * 1j closest = sorted([i for i in range(len(points))], key=lambda dist: abs(points[i] - last_stitch))[0] points = points[closest:] + points[:closest] for point in points: to = Stitch(["STITCH"], point.real, point.imag, color=self.stroke_color) self.stitches.append(to)
def markup_measure_octave(staff_prop: StaffProperties, octave_text, staff_measure_point): x = staff_measure_point.x + 25 y = staff_measure_point.y + staff_prop.staff_height - staff_prop.staff_line_offset r = staff_prop.staff_line_offset * 0.8 font_size = staff_prop.staff_line_offset * 1.43 return [ Circle(center=(x, y), r=r, fill="rgb(255,255,255)", stroke="rgb(0,0,0)", stroke_width=0.5), Text( octave_text, insert=(x, y + font_size * 0.36), fill="rgb(0,0,0)", text_anchor="middle", style=f"font-size:{font_size}; font-family:Arial", ) ]
def tool_template(name, width_in): g = Group( stroke="black", stroke_width=0.5, font_family="Arial, Helvetica", ) # Border g.add(Rect( (0, 0), (width_in * inch, width_in * inch), fill="none", )) # Lanyard punch g.add( Circle( (0.4 * inch, (width_in - 0.4) * inch), 3.5 * mm, fill="none", )) # plast-karto! g.add( Text( "https://plast-karto.readthedocs.io", ((width_in / 2) * inch, (width_in - 0.3) * inch), text_anchor="middle", font_size=2 * mm, )) g.add( Text( name, ((0.75) * inch, (width_in - 0.75) * inch), text_anchor="middle", font_size=4 * mm, )) g.add(square_rose(width_in)) return g
def build(self): """assembles the data in the scatterplot, adding the points as circles.""" if self.autoscale: self.max_min() for row in self.data: x_value = row[0] y_value = row[1] if self.x_min <= x_value <= self.x_max and self.y_min <= y_value <= self.y_max: x_plot = self.x_to_printx(x_value) y_plot = self.y_to_printy(y_value) self.plot.add(Circle(center=(x_plot, y_plot), r=2, stroke_width=0.1, stroke_linecap='round', stroke_opacity=0.5, fill="dodgerblue", fill_opacity=0.5)) self.data = None
def corner_ruler(scale, length, major_interval, minor_per_major): g = Group(stroke="black", stroke_width=0.4) ruler_length_mm = (length / scale) * 1000 # Horizontal Ruler g.add(Line((-ruler_length_mm * mm, 0 * mm), ((3) * mm, 0 * mm))) r = ruler(scale=scale, length=length, major_interval=major_interval, minor_per_major=minor_per_major, reverse=True, vertical=False) g.add(r) # Vertical Ruler g.add(Line((0 * mm, -3 * mm), (0 * mm, (ruler_length_mm) * mm))) r = ruler(scale=scale, length=length, major_interval=major_interval, minor_per_major=minor_per_major, reverse=False, vertical=True) g.add(r) g.add(Circle((0, 0), r=0.5 * mm, fill="white")) # Scale label g.add( Text( f"1:{scale}", x=[(-ruler_length_mm / 2) * mm], y=[-1 * mm], text_anchor="middle", font_size=2 * mm, font_weight="bold", )) return g
def get_circles_and_texts(self): circles: List[Circle] = [] texts: List[Text] = [] for item in self.chord.items: x = (item.col - 1) * self.cell_width + self.circle_radius y = item.row * self.cell_height - self.cell_height // 2 circle = Circle(center=(x, y), fill=self.circle_color, r=self.circle_radius) text = Text( item.num, insert=(circle.attribs['cx'] - self.circle_radius / 3, circle.attribs['cy'] + self.circle_radius / 2.3), fill="white", style=f"font-size: {self.width // 10}") texts.append(text) circles.append(circle) return [circles, texts]
def test_numbers(self): circle = Circle(center=(0,0), r=2) self.assertEqual(circle.tostring(), '<circle cx="0" cy="0" r="2" />')
def test_coordinates(self): circle = Circle(center=('1cm','1cm'), r='2mm') self.assertEqual(circle.tostring(), '<circle cx="1cm" cy="1cm" r="2mm" />')
def plot_data(self): if not self.show_legend: self.plot.add( Line(start=(self.margin_left, self.margin_top), end=(self.width - self.margin_right, self.margin_top), stroke_width=1, stroke="black")) self.max_value = max( [x['score'] for x in self.annotated_scores.values()]) if not self.min_value: self.min_value = min( [x['score'] for x in self.annotated_scores.values()]) if not self.show_legend: self.plot.add( Text("Fibroblasts", insert=(self.margin_left, self.margin_top - 5), fill="black", font_size="15")) self.plot.add( Text("Cardiomyocytes", insert=(self.width - self.margin_right - 100, self.margin_top - 5), fill="black", font_size="15")) delta = self.max_value - self.min_value plottable = self.width - (self.margin_left + self.margin_right) spacing = { "Fibroblasts": INIT_GAP, "Cardiomyocytes": INIT_GAP, "Experimental": INIT_GAP, "other": INIT_GAP } for sample, sample_details in self.annotated_scores.items(): position = self.margin_left + ( (sample_details['score'] - self.min_value) / delta * plottable) # colour = "grey" if "category" in sample_details: sample_type = sample_details["category"] if sample_type == "Fibroblasts": colour = "green" elif sample_type == "Cardiomyocytes": colour = "blue" elif sample_type == "Experimental": colour = "red" else: continue # sample_type = "other" else: continue # sample_type = "other" circle_obj = Circle( center=(position, self.margin_top + spacing[sample_type] + 5), r=3, stroke_width=0.1, stroke_linecap='round', stroke_opacity=1, fill=colour, fill_opacity=0.6) # set to 0.2 if you want to show clear. circle_obj.set_desc('{} - {} - {}'.format( sample, sample_type, sample_details["score"] if "description" not in sample_details else sample_details["description"])) self.plot.add(circle_obj) if sample_type == "other": spacing[sample_type] += 3 else: spacing[sample_type] += 6
def make_svg(self, data): layers = data["layers"] _PROPORTION = 10 _SHIFT_PROP = _PROPORTION / 1.5 for f in self.forms: structures = [None] * len(f.id.split("_")) linkers = [] centers = {} order = {} maxW, maxH = 0, 0 for cx, x in enumerate(f.id.split("_")): order[x] = cx for cl, l in enumerate(layers): for cs, s in enumerate(l): name = f.id + "__" + s["id"] if s["type"] == "H": color = "cornflowerblue" if "ref" not in s else "gainsboro" shape = Circle( center = (s["shift_x"] * _SHIFT_PROP, s["shift_z"] * _SHIFT_PROP), r = 2.3 * _PROPORTION, id = name, fill = color, stroke="black", stroke_width = "2") elif s["type"] == "E": color = "indianred" if "ref" not in s else "salmon" rotate = f.get_ss_by_id(s["id"]).struc.goes_down() shape = Triangle(center = (s["shift_x"] * _SHIFT_PROP, s["shift_z"] * _SHIFT_PROP), rc = 2.3 * _PROPORTION, id = name, fill=color, stroke = "black", stroke_width = "2", rotate = rotate) else: color = "darkgreen" if "ref" not in s else "lightgreen" shape = Cross(center = (s["shift_x"] * _SHIFT_PROP, s["shift_z"] * _SHIFT_PROP), r = 2.3 * _PROPORTION, fill=color, stroke="black", stroke_width = "2", id = name) structures[order[s["id"]]] = shape centers[s["id"]] = [s["shift_x"] * _SHIFT_PROP, s["shift_z"] * _SHIFT_PROP] if s["shift_x"] * _SHIFT_PROP > maxW: maxW = s["shift_x"] * _SHIFT_PROP if s["shift_z"] * _SHIFT_PROP > maxH: maxH = s["shift_z"] * _SHIFT_PROP for cx, x in enumerate(f.id.split("_")): if cx == 0 or cx == len(f.id.split("_")) - 1: init = [0, 0] if (ord(x[0]) - 64) <= len(layers) / 2: init[1] = centers[x][1] - (2.3 * _PROPORTION * 2) else: init[1] = centers[x][1] + (2.3 * _PROPORTION * 2) if int(re.search("(\d+)", x).group(1)) <= len(layers[ord(x[0]) - 65]) / 2: init[0] = centers[x][0] - (2.3 * _PROPORTION * 2) else: init[0] = centers[x][0] + (2.3 * _PROPORTION * 2) if cx == 0: shape = Line(init, centers[x], stroke="darkblue", stroke_width = "4") elif cx == len(f.id.split("_")) - 1: shape = Line(centers[x], init, stroke="darkred", stroke_width = "4") linkers.append(shape) for cy, y in enumerate(f.id.split("_")): if cy == cx + 1: shape = Line(centers[x], centers[y], stroke="black", stroke_width = "4") linkers.append(shape) # Intercalate toplink = [] dowlink = [] if f.sslist[0].struc.goes_up(): dowlink = linkers[0:][::2] toplink = linkers[1:][::2] else: dowlink = linkers[1:][::2] toplink = linkers[0:][::2] g = Group() for x in dowlink: g.add(x) for x in structures: g.add(x) for x in toplink: g.add(x) g.translate(2.3 * _PROPORTION * 3, 2.3 * _PROPORTION * 3) d = Drawing(size = (maxW + ((2.3 * _PROPORTION * 3) * 2), maxH + ((2.3 * _PROPORTION * 3) * 2)), id = f.id + "__image") d.add(g) for x in data["forms"]: if x["id"] == f.id: x["svg"] = d.tostring()
def test_add_subelement(self): mask = Mask(debug=True, profile='full') mask.add(Circle((50, 60), 70)) self.assertEqual(mask.tostring(), '<mask><circle cx="50" cy="60" r="70" /></mask>')
def square_rose(width_in=2.5): major_tick_in = 0.13 middle_tick_in = 0.1 minor_tick_in = 0.07 g = Group(stroke="black", stroke_width=0.4) for deg in range(360): rad = math.pi * deg / 180 stroke_width = 0.4 if deg % 10 == 0: stroke_width = 0.6 tick_len = major_tick_in elif deg % 45 == 0: tick_len = middle_tick_in * 1.25 elif deg % 5 == 0: tick_len = middle_tick_in else: tick_len = minor_tick_in if deg > 315 or deg <= 45: y1 = width_in / 2 x1 = math.tan(rad) * y1 y2 = width_in / 2 - tick_len x2 = math.tan(rad) * y2 elif 45 < deg <= 135: x1 = width_in / 2 y1 = x1 / math.tan(rad) x2 = width_in / 2 - tick_len y2 = x2 / math.tan(rad) elif 135 < deg <= 225: y1 = -width_in / 2 x1 = math.tan(rad) * y1 y2 = -width_in / 2 + tick_len x2 = math.tan(rad) * y2 elif 225 < deg <= 315: x1 = -width_in / 2 y1 = x1 / math.tan(rad) x2 = -width_in / 2 + tick_len y2 = x2 / math.tan(rad) # flip coordinates and center y1 = width_in / 2 - y1 y2 = width_in / 2 - y2 x1 += width_in / 2 x2 += width_in / 2 g.add( Line( (x1 * inch, y1 * inch), (x2 * inch, y2 * inch), stroke_width=stroke_width, )) if (deg % 10 == 0) or (deg % 45 == 0): if deg > 315 or deg < 45: rotate = 0 xt = x2 yt = y2 + 0.06 elif deg == 45: rotate = 45 xt = x2 - 0.04 yt = y2 + 0.04 elif 45 < deg < 135: rotate = 90 xt = x2 - 0.06 yt = y2 elif deg == 135: rotate = -45 xt = x2 - 0.02 yt = y2 - 0.02 elif 135 < deg < 225: rotate = 0 xt = x2 yt = y2 - 0.02 elif deg == 225: rotate = 45 xt = x2 + 0.02 yt = y2 - 0.02 elif 225 < deg < 315: rotate = -90 xt = x2 + 0.06 yt = y2 elif deg == 315: rotate = -45 xt = x2 + 0.04 yt = y2 + 0.04 t = Text( deg, (xt * inch, yt * inch), text_anchor="middle", font_size=1.5 * mm, ) t.rotate(rotate, (xt * 72, yt * 72)) g.add(t) # Center reticle g.add( Line( ((width_in / 2) * inch, (width_in / 2 - 0.1) * inch), ((width_in / 2) * inch, (width_in / 2 + 0.1) * inch), )) g.add( Line( ((width_in / 2 - 0.1) * inch, (width_in / 2) * inch), ((width_in / 2 + 0.1) * inch, (width_in / 2) * inch), )) g.add( Circle(((width_in / 2) * inch, (width_in / 2) * inch), r=0.5 * mm, fill="white")) return g
def draw(self, builder): color = builder.authors[self] circle = Circle(builder.position(self.date, builder.y), 5, fill=color) circle.add(Title(str(self))) return [circle]
def test_add_subelement(self): clip_path = ClipPath(debug=True, profile='full') clip_path.add(Circle((50,60), 70)) self.assertEqual(clip_path.tostring(), '<clipPath><circle cx="50" cy="60" r="70" /></clipPath>')
def debug_point(point): x, y = point return Circle(center=(x, y), r=10)
def draw_graph(graph): # Draws the graph by creating a document, loading css & images, and inserting edges and nodes # # Create a document drawing = svgwrite.Drawing(filename="res.svg", size=('%dmm' % WIDTH_IN_MM, '%dmm' % HEIGHT_IN_MM)) # Load styling load_styling(drawing, "assets/css/svg.css") load_font_css(drawing, "assets/css/got-font.css") draw_background(drawing) drawing.add( Text("Game of Thrones", insert=(WIDTH / 2 + 50, 300), class_="headline")) # Load arrow marker for directed edges arrow_marker = create_arrow_marker(drawing) # Load cross for dead characters death_symbol = load_death_symbol(drawing) # load background images for nodes character_images = prepare_character_images(drawing) # draw edges for e in graph.edges: start = (OFFSET_X + e.sourceNode.x, OFFSET_Y + e.sourceNode.y) end = (OFFSET_X + e.targetNode.x, OFFSET_Y + e.targetNode.y) single_edge_nodes = graph.get_single_edge_nodes() if e.sourceNode in single_edge_nodes or e.targetNode in single_edge_nodes: line = Line(start=start, end=end) hasattr(e, "relation") relation = e.get("relation") if relation is not None: line["class"] = relation if e.directed: line["marker-end"] = arrow_marker.get_funciri() drawing.add(line) else: # use a bezier center_x = WIDTH / 2 center_y = HEIGHT / 2 # calculates the avg position of the center of the graph, start and end point avg_x = int((center_x + start[0] + end[0]) / 3) avg_y = int((center_y + start[1] + end[1]) / 3) p1 = avg_x p2 = avg_y if e.get("relation") == "father" or e.get("relation") == "mother": if NO_PARENTS: continue # trying to get sibling relations edges to the outer of the circle... if e.get("relation") == "sibling" or e.get( "relation") == "father" or e.get("relation") == "mother": if NO_SIBLINGS: continue node_distance = calc.real_distance(start, end) if node_distance < (500 * POS_SCALE): # this is a distance threshold (p1, p2) = calc.calc_outer_bezier_focus( (center_x, center_y), (start[0], start[1]), (end[0], end[1])) path_string = "M {} {} Q {} {} {} {}".format( start[0], start[1], p1, p2, end[0], end[1]) path = Path(d=path_string) relation = e.get("relation") if relation is not None: path["class"] = relation if e.score_relevance(graph.max_edge_count, graph.median_edge_count) > 0: path["class"] = path["class"] + " HiRel" if e.directed: path["marker-end"] = arrow_marker.get_funciri() drawing.add(path) # draw nodes for n in graph.nodes: x = OFFSET_X + n.x # * POS_SCALE y = OFFSET_Y + n.y # * POS_SCALE f = character_images.get(n.id) if f is not None: c = Circle(center=(x, y), r=NODE_RADIUS, fill=f.get_paint_server()) else: c = Circle(center=(x, y), r=NODE_RADIUS, fill="green") # , fill_opacity="0.4") drawing.add(c) draw_death(drawing, x, y, n, death_symbol) draw_name(drawing, x, y, n) draw_house(drawing, x, y, n) # save the svg file drawing.save()
def markup_note(staff_prop: StaffProperties, staff_start_position, staff_octave, horizontal_note_position, chord_offset, note, chords_notes): not_chord_note = note.id not in chords_notes chord_note = note.id in chords_notes last_chord_note = chord_note and chords_notes.get(note.id, {}).last objects = [] note_offset = get_note_position(staff_prop, staff_octave, note.pitch) vertical_note_position = staff_start_position + note_offset note_sign = get_note_sign(note) objects += [ markup_note_body( note_sign, Point(horizontal_note_position + chord_offset, vertical_note_position)) ] if note.dot: addition = ( note_offset - 0.5 ) % staff_prop.staff_line_offset - staff_prop.staff_line_offset / 2 objects += [ Circle(center=(horizontal_note_position + 35 + chord_offset, vertical_note_position + addition), r=4) ] if note.time_modification: objects += [ Text( str(note.time_modification['actual-notes']), insert=(horizontal_note_position, staff_start_position - staff_prop.staff_offset // 2), fill="rgb(110,110,110)", style="font-size:15px; font-family:Arial", ) ] objects += [] flag = { 'whole': (0, 0), 'half': (0.83, 0), 'quarter': (0.83, 0), 'eighth': (0.9, 1), '16th': (1, 2), '32nd': (1.2, 3), } stem_length_multiplier, beam_count = flag[note.type] if stem_length_multiplier: half_note_offset = 18.2 stem_width = 3 stem_lenght = 85 * stem_length_multiplier stem_offset = -0.5 objects += [ Polyline(points=[(horizontal_note_position + half_note_offset, vertical_note_position + stem_offset), (horizontal_note_position + half_note_offset, vertical_note_position - stem_lenght + stem_offset)]).stroke( color=svgwrite.rgb(0, 0, 0), width=stem_width, linejoin='bevel', linecap="round", ) ] # TODO extract beam|stemm drawing into note groups drawing # logger.debug(f'{not_chord_note=} {last_chord_note=} {first_chord_note=}') if not_chord_note or last_chord_note: assert beam_count <= 3, f'max 32nd note, {beam_count=} given' beam = hooks[beam_count] if beam: beam_length = 13 beam_offset = -0.5 objects += [ Path(d=moved_path( beam, horizontal_note_position + half_note_offset - stem_width / 2, vertical_note_position - stem_lenght + beam_offset)) ] return objects
def scan_lines(paths, current_y=None): bbox = overall_bbox(paths) lines = [] fudge_factor = 0.01 orientation = abs(bbox[3]-bbox[2]) > abs(bbox[1]-bbox[0]) if not current_y: current_y = bbox[2] if orientation else bbox[0] max_pos = bbox[3] if orientation else bbox[1] debug_shapes = [[paths, "none", "gray"]] while current_y < max_pos: current_y += MINIMUM_STITCH_DISTANCE if orientation: left = min(bbox[0], bbox[1]) right = max(bbox[0], bbox[1]) if left < 0: left *= 1.0 + fudge_factor else: left *= 1.0 - fudge_factor if right < 0: right *= 1.0 - fudge_factor else: right *= 1.0 + fudge_factor test_line = Line(start=current_y*1j+left, end=current_y*1j+right) else: up = min(bbox[2], bbox[3]) down = max(bbox[2], bbox[3]) if up < 0: up *= 1.0 + fudge_factor else: up *= 1.0 - fudge_factor if down < 0: down *= 1.0 - fudge_factor else: down *= 1.0 + fudge_factor test_line = Line(start=current_y + up*1j, end=current_y + down *1j) squash_intersections = [] for path in paths: if path.start == path.end: continue intersections = path.intersect(test_line) if len(intersections) > 0: squash_intersections += [test_line.point(p[1]) for p in intersections] if len(squash_intersections) == 0: continue intersections = sorted(squash_intersections, key=lambda x: abs(x-test_line.start)) if len(squash_intersections) < 2: continue debug_shapes.append([test_line, "none", "black"]) for i in range(0, 2*int(len(intersections)/2), 2): def format_center(ind): return (intersections[ind].real, intersections[ind].imag) debug_shapes.append([Circle(center=format_center(i), r=1, fill="red")]) debug_shapes.append([Circle(center=format_center(i+1), r=1, fill="blue")]) line = Line(start=intersections[i], end=intersections[i+1]) debug_shapes.append([line, "none", "green"]) if line.length() > MAXIMUM_STITCH: num_segments = ceil(line.length() / MAXIMUM_STITCH) for seg_i in range(int(num_segments)): lines.append(Line(start=line.point(seg_i/num_segments), end=line.point((seg_i+1)/num_segments))) else: lines.append(line) write_debug("fillscan", debug_shapes) return lines
def _put_circle(self, cell, x, y, fill, stone_size): radius = stone_size / 4 cell.add( Circle((x * self.unit, y * self.unit), radius * self.unit, fill=fill))
def test_add_classes(self): circle = Circle(center=(0, 0), r=2, class_='class1 class2') assert circle['class'] == 'class1 class2'