def add_ellipse(dwg: svgwrite.Drawing, container: BaseElement, center, beta: float, rotation, size: int = 100, color: str = "blue", marker_size: int = 20, width: int = 1, ell_scale=0.8): """ Add ellipse to svg files with two arrows at outline :return group with arcs of ellipse :param dwg a Drawing class object :param container some object of subclass BasElement :param center of ellipse in pixel (2d tuple) :param size length of side square what restricted the ellipse :param beta angle of ellipticity. beta = tg(e) :param rotation contre clock wise rotation in radian :param color color of outline and arrow :param marker_size in pixels. It define side of the square where will be an arrow. :param width width of the outlines :param ell_scale coefficient of scale the size of ellipse """ # if abs(rotation) < 4*np.finfo(float).eps: # g = Group(transform=f"translate({center[0]},{center[1]})") # else: if abs(beta) < properties.EPS_D: radii = (0, 0) ell_point_x = size / 2 # - marker_size // 4 else: radii = (abs(math.cos(beta)), abs(math.sin(beta))) radii = np.multiply(radii, size / (2 * max(radii[0], radii[1]))) ell_point_x = radii[0] # print(radii) g = Group( transform= f"translate({center[0]},{center[1]}) scale(1,-1) rotate({np.rad2deg(rotation)})" ) arrow_marker: Marker = dwg.marker(refX=marker_size // 2 * (-1 if beta > 0 else 1), refY=marker_size // 2, markerUnits="strokeWidth", markerWidth=int(0.4 * marker_size), markerHeight=int(0.3 * marker_size), orient="auto") # Marker() arrow_marker.viewbox(minx=0, miny=0, width=marker_size, height=marker_size) ms = marker_size ms_2 = marker_size // 2 str_path = f"M -{ms_2}, 0 L {ms_2} {ms_2} L -{ms_2} {ms}" if beta > 0 else \ f"M {ms_2}, 0 L -{ms_2} {ms_2} L {ms_2} {ms}" arrow_head: svgwrite.path.Path = arrow_marker.add(dwg.path(d=str_path)) # beta > 0 - right cw beta < 0 - left ccw arrow_head.fill("none") arrow_head.stroke(color, 2 * width) dwg.defs.add(arrow_marker) radii = np.asarray(radii) radii = radii * ell_scale ell_point_x = ell_point_x * ell_scale # just axes g.add( dwg.path(d=f"M 50,50 l -100,0 l 0,-100 l 100,0 l 0,100", transform=f"rotate({-np.rad2deg(rotation)})")) point = g.add(dwg.path(d=f"M 0,0 L 5,0 M 0,0 L 0,3") ) # if abs(beta) > properties.EPS_D else None arc1 = g.add( dwg.path( d=f"M {ell_point_x},0 a{radii[0]},{radii[1]} 0 0,0 -{2 * ell_point_x},0" )) arc2 = g.add( dwg.path( d=f"M -{ell_point_x},0 a{radii[0]},{radii[1]} 0 0,0 {2 * ell_point_x},0" )) arc1.set_markers( (None, None, arrow_marker )) # set the end marker. start and middle markers is empty. arc2.set_markers((None, None, arrow_marker)) g.fill("none") g.stroke(color) g.stroke(color, width) return container.add(g)