def test_spatial_arc_from_3p(): start_point_wcs = Vector(0, 1, 0) end_point_wcs = Vector(1, 0, 0) def_point_wcs = Vector(0, 0, 1) ucs = UCS.from_x_axis_and_point_in_xy(origin=def_point_wcs, axis=end_point_wcs - def_point_wcs, point=start_point_wcs) start_point_ucs = ucs.from_wcs(start_point_wcs) end_point_ucs = ucs.from_wcs(end_point_wcs) def_point_ucs = Vector(0, 0) arc = ConstructionArc.from_3p(start_point_ucs, end_point_ucs, def_point_ucs) dwg = ezdxf.new('R12') msp = dwg.modelspace() dxf_arc = arc.add_to_layout(msp, ucs) assert dxf_arc.dxftype() == 'ARC' assert isclose(dxf_arc.dxf.radius, 0.81649658, abs_tol=1e-9) assert isclose(dxf_arc.dxf.start_angle, -30) # ??? assert isclose(dxf_arc.dxf.end_angle, -150) # ??? assert is_close_points(dxf_arc.dxf.extrusion, (0.57735027, 0.57735027, 0.57735027), abs_tol=1e-9)
def circular_arc_3p(self, data: bytes): bs = ByteStream(data) attribs = self._build_dxf_attribs() p1 = Vec3(bs.read_vertex()) p2 = Vec3(bs.read_vertex()) p3 = Vec3(bs.read_vertex()) arc_type = bs.read_struct('L')[0] arc = ConstructionArc.from_3p(p1, p3, p2) attribs['center'] = arc.center attribs['radius'] = arc.radius attribs['start_angle'] = arc.start_angle attribs['end_angle'] = arc.end_angle return self._factory('ARC', dxfattribs=attribs)
def test_arc_from_3p(): p1 = (-15.73335, 10.98719) p2 = (-12.67722, 8.76554) p3 = (-8.00817, 12.79635) arc = ConstructionArc.from_3p(start_point=p1, end_point=p2, def_point=p3) arc_result = ConstructionArc( center=(-12.08260, 12.79635), radius=4.07443, start_angle=-153.638906, end_angle=-98.391676, ) assert arc.center.isclose(arc_result.center, abs_tol=1e-5) assert isclose(arc.radius, arc_result.radius, abs_tol=1e-5) assert isclose(arc.start_angle, arc_result.start_angle, abs_tol=1e-4) assert isclose(arc.end_angle, arc_result.end_angle, abs_tol=1e-4)
# create a 3D arc from 3 points in WCS start_point_wcs = Vec3(3, 0, 0) end_point_wcs = Vec3(0, 3, 0) def_point_wcs = Vec3(0, 0, 3) # create UCS ucs = UCS.from_x_axis_and_point_in_xy(origin=def_point_wcs, axis=start_point_wcs - def_point_wcs, point=end_point_wcs) start_point_ucs = ucs.from_wcs(start_point_wcs) end_point_ucs = ucs.from_wcs(end_point_wcs) def_point_ucs = Vec3(0, 0) # origin of UCS # create arc in the xy-plane of the UCS arc = ConstructionArc.from_3p(start_point_ucs, end_point_ucs, def_point_ucs) arc.add_to_layout(modelspace, ucs, dxfattribs={'color': 1}) # red arc arc = ConstructionArc.from_3p(end_point_ucs, start_point_ucs, def_point_ucs) arc.add_to_layout(modelspace, ucs, dxfattribs={'color': 2}) # yellow arc p1 = Vec3(0, -18) p2 = Vec3(0, +18) arc = ConstructionArc.from_2p_angle(p1, p2, 90) arc.add_to_layout(modelspace, dxfattribs={'color': 1}) arc = ConstructionArc.from_2p_angle(p1, p2, 90, ccw=False) arc.add_to_layout(modelspace, dxfattribs={'color': 2}) p1 = Vec3(20, -18) p2 = Vec3(20, +18)
spline.apply_construction_tool(bspline) # Recreate ARC from SPLINE, if you ASSUME or KNOW it is an ARC: # for spline in msp.query("SPLINE): # ... # 1. get the B-spline construction tool from the SPLINE entity bspline = spline.construction_tool() max_t = bspline.max_t # calculate 3 significant points and 2 check points of the SPLINE: start, chk1, middle, chk2, end = bspline.points([ 0, max_t * 0.25, max_t * 0.5, max_t * 0.75, max_t ]) # create an arc from 3 points: arc_tool = ConstructionArc.from_3p(start, end, middle) arc_tool.add_to_layout(msp, dxfattribs={ "layer": "recreated arc", "color": ezdxf.const.MAGENTA, }) # This only works for flat B-splines in the xy-plane, a.k.a. 2D splines! # Check the assumption: center = arc_tool.center radius = arc_tool.radius err = max(abs(radius - p.distance(center)) for p in (chk1, chk2)) print(f"max error: {err:.6f}") # Warning: this does not proof that the assumption was correct, it is always # possible to create a diverging B-spline which matches the check points: