def from_arc(cls, entity: 'DXFGraphic') -> 'Spline': """ Create a new SPLINE entity from a CIRCLE, ARC or ELLIPSE entity. The new SPLINE entity has no owner, no handle, is not stored in the entity database nor assigned to any layout! """ dxftype = entity.dxftype() if dxftype == 'ELLIPSE': ellipse = cast('Ellipse', entity).construction_tool() elif dxftype == 'CIRCLE': ellipse = ConstructionEllipse.from_arc( center=entity.dxf.get('center', NULLVEC), radius=abs(entity.dxf.get('radius', 1.0)), extrusion=entity.dxf.get('extrusion', Z_AXIS), ) elif dxftype == 'ARC': ellipse = ConstructionEllipse.from_arc( center=entity.dxf.get('center', NULLVEC), radius=abs(entity.dxf.get('radius', 1.0)), extrusion=entity.dxf.get('extrusion', Z_AXIS), start_angle=entity.dxf.get('start_angle', 0), end_angle=entity.dxf.get('end_angle', 360)) else: raise TypeError('CIRCLE, ARC or ELLIPSE entity required.') spline = Spline.new(dxfattribs=entity.graphic_properties(), doc=entity.doc) s = BSpline.from_ellipse(ellipse) spline.dxf.degree = s.degree spline.dxf.flags = Spline.RATIONAL spline.control_points = s.control_points spline.knots = s.knots() spline.weights = s.weights() return spline
def test_from_arc(): ellipse = ConstructionEllipse.from_arc(center=(2, 2, 2), radius=3) assert ellipse.center == (2, 2, 2) assert ellipse.major_axis == (3, 0, 0) assert ellipse.ratio == 1 assert ellipse.start_param == 0 assert math.isclose(ellipse.end_param, math.tau)
def draw_elliptic_arc_entity_3d(self, entity: DXFGraphic) -> None: dxf, dxftype = entity.dxf, entity.dxftype() properties = self._resolve_properties(entity) if dxftype in {'CIRCLE', 'ARC'}: center = dxf.center # ocs transformation in .from_arc() radius = dxf.radius if dxftype == 'CIRCLE': start_angle = 0 end_angle = 360 else: start_angle = dxf.start_angle end_angle = dxf.end_angle e = ConstructionEllipse.from_arc(center, radius, dxf.extrusion, start_angle, end_angle) elif dxftype == 'ELLIPSE': e = cast(Ellipse, entity).construction_tool() else: raise TypeError(dxftype) # Approximate as 3D polyline segments = int((e.end_param - e.start_param) / math.tau * self.circle_approximation_count) points = list( e.vertices( linspace(e.start_param, e.end_param, max(4, segments + 1)))) self.out.start_path() for a, b in zip(points, points[1:]): self.out.draw_line(a, b, properties) self.out.end_path()
def from_circle(cls, circle: 'Circle', segments: int = 1) -> 'Path': """ Returns a :class:`Path` from a :class:`~ezdxf.entities.Circle`. """ path = cls() ellipse = ConstructionEllipse.from_arc( center=circle.dxf.center, radius=circle.dxf.radius, extrusion=circle.dxf.extrusion, ) path.add_ellipse(ellipse, segments=segments, reset=True) return path
def add_arc_edge(edge): x, y, *_ = edge.center # from_arc() requires OCS data: ellipse = ConstructionEllipse.from_arc( center=(x, y, elevation), radius=edge.radius, extrusion=extrusion, start_angle=edge.start_angle, end_angle=edge.end_angle, ) tools.add_ellipse(path, ellipse, reset=not bool(path))
def _from_circle(circle: Circle, **kwargs) -> 'Path': segments = kwargs.get('segments', 1) path = Path() radius = abs(circle.dxf.radius) if not math.isclose(radius, 0): ellipse = ConstructionEllipse.from_arc( center=circle.dxf.center, radius=radius, extrusion=circle.dxf.extrusion, ) tools.add_ellipse(path, ellipse, segments=segments, reset=True) return path
def _from_circle(circle: Circle, **kwargs) -> "Path": segments = kwargs.get("segments", 1) path = Path() radius = abs(circle.dxf.radius) if radius > 1e-12: ellipse = ConstructionEllipse.from_arc( center=circle.dxf.center, radius=radius, extrusion=circle.dxf.extrusion, ) tools.add_ellipse(path, ellipse, segments=segments, reset=True) return path
def from_arc(cls, arc: 'Arc', segments: int = 1) -> 'Path': """ Returns a :class:`Path` from an :class:`~ezdxf.entities.Arc`. """ path = cls() ellipse = ConstructionEllipse.from_arc( center=arc.dxf.center, radius=arc.dxf.radius, extrusion=arc.dxf.extrusion, start_angle=arc.dxf.start_angle, end_angle=arc.dxf.end_angle, ) path.add_ellipse(ellipse, segments=segments, reset=True) return path
def bulge_to(p1: Vec3, p2: Vec3, bulge: float): if p1.isclose(p2): return center, start_angle, end_angle, radius = bulge_to_arc(p1, p2, bulge) ellipse = ConstructionEllipse.from_arc( center, radius, Z_AXIS, math.degrees(start_angle), math.degrees(end_angle), ) curves = list(cubic_bezier_from_ellipse(ellipse)) if curves[0].control_points[0].isclose(p2): curves = _reverse_bezier_curves(curves) self.add_curves(curves)
def _from_arc(arc: Arc, **kwargs) -> 'Path': segments = kwargs.get('segments', 1) path = Path() radius = abs(arc.dxf.radius) if not math.isclose(radius, 0): ellipse = ConstructionEllipse.from_arc( center=arc.dxf.center, radius=radius, extrusion=arc.dxf.extrusion, start_angle=arc.dxf.start_angle, end_angle=arc.dxf.end_angle, ) tools.add_ellipse(path, ellipse, segments=segments, reset=True) return path
def _from_arc(arc: Arc, **kwargs) -> "Path": segments = kwargs.get("segments", 1) path = Path() radius = abs(arc.dxf.radius) if radius > 1e-12: ellipse = ConstructionEllipse.from_arc( center=arc.dxf.center, radius=radius, extrusion=arc.dxf.extrusion, start_angle=arc.dxf.start_angle, end_angle=arc.dxf.end_angle, ) tools.add_ellipse(path, ellipse, segments=segments, reset=True) return path
def from_arc(cls, entity: "DXFGraphic") -> "Spline": """Create a new SPLINE entity from a CIRCLE, ARC or ELLIPSE entity. The new SPLINE entity has no owner, no handle, is not stored in the entity database nor assigned to any layout! """ dxftype = entity.dxftype() if dxftype == "ELLIPSE": ellipse = cast("Ellipse", entity).construction_tool() elif dxftype == "CIRCLE": ellipse = ConstructionEllipse.from_arc( center=entity.dxf.get("center", NULLVEC), radius=abs(entity.dxf.get("radius", 1.0)), extrusion=entity.dxf.get("extrusion", Z_AXIS), ) elif dxftype == "ARC": ellipse = ConstructionEllipse.from_arc( center=entity.dxf.get("center", NULLVEC), radius=abs(entity.dxf.get("radius", 1.0)), extrusion=entity.dxf.get("extrusion", Z_AXIS), start_angle=entity.dxf.get("start_angle", 0), end_angle=entity.dxf.get("end_angle", 360), ) else: raise TypeError("CIRCLE, ARC or ELLIPSE entity required.") spline = Spline.new(dxfattribs=entity.graphic_properties(), doc=entity.doc) s = BSpline.from_ellipse(ellipse) spline.dxf.degree = s.degree spline.dxf.flags = Spline.RATIONAL spline.control_points = s.control_points # type: ignore spline.knots = s.knots() # type: ignore spline.weights = s.weights() # type: ignore return spline
def bulge_to(p1: Vec3, p2: Vec3, bulge: float): if p1.isclose(p2, rel_tol=IS_CLOSE_TOL, abs_tol=0): return center, start_angle, end_angle, radius = bulge_to_arc(p1, p2, bulge) ellipse = ConstructionEllipse.from_arc( center, radius, Z_AXIS, math.degrees(start_angle), math.degrees(end_angle), ) curves = list(cubic_bezier_from_ellipse(ellipse)) curve0 = curves[0] cp0 = curve0.control_points[0] if cp0.isclose(p2, rel_tol=IS_CLOSE_TOL, abs_tol=0): curves = reverse_bezier_curves(curves) add_bezier4p(path, curves)
def arc(edge: ArcEdge): x, y, *_ = edge.center # from_arc() requires OCS data: # Note: clockwise oriented arcs are converted to counter # clockwise arcs at the loading stage! # See: ezdxf.entities.boundary_paths.ArcEdge.load_tags() ellipse = ConstructionEllipse.from_arc( center=(x, y, elevation), radius=edge.radius, extrusion=extrusion, start_angle=edge.start_angle, end_angle=edge.end_angle, ) segment = Path() tools.add_ellipse(segment, ellipse, reset=True) return segment