def test_local_cubic_bspline_interpolation_from_tangents(): points = Vec3.list(POINTS1) tangents = estimate_tangents(points) control_points, knots = local_cubic_bspline_interpolation_from_tangents( points, tangents) assert len(control_points) == 8 assert len(knots) == 8 + 4 # count + order
def test_estimate_tangents_5p(): tangents = estimate_tangents(Vec3.list(POINTS1), method="5-points") assert len(tangents) == 4
# Reference curve as fine approximation msp.add_lwpolyline(sine_wave(count=800, scale=2.0), dxfattribs={ 'color': 1, 'layer': 'Reference curve (LWPolyline)' }) # AutoCAD/BricsCAD interpolation msp.add_spline(data, dxfattribs={'layer': 'BricsCAD B-spline', 'color': 2}) # tangent estimation method METHOD = '5-p' # create not normalized tangents (default is normalized) tangents = estimate_tangents(data, METHOD, normalize=False) # show tangents for p, t in zip(data, tangents): msp.add_line(p, p + t, dxfattribs={ 'color': 5, 'layer': f'Estimated tangents ({METHOD})' }) # local interpolation: a normalized tangent vector for each data point is required, s = local_cubic_bspline_interpolation( data, tangents=[t.normalize() for t in tangents]) # or set argument 'method' for automatic tangent estimation, default method is '5-points' interpolation # s = local_cubic_bspline_interpolation(data, method=METHOD)
dxfattribs={ 'layer': 'BricsCAD B-spline', 'color': 2 }) spline.dxf.start_tangent = Vec3.from_deg_angle(100) spline.dxf.end_tangent = Vec3.from_deg_angle(-100) zoom.extents(msp) doc.saveas(DIR / 'concept-1-fit-points-and-tangents.dxf') # 3. Need control vertices to render the B-spline but start- and # end tangents are not stored in the DXF file like in scenario 1. # Estimation of start- and end tangents is required, best result by: # "5 Point Interpolation" from "The NURBS Book", Piegl & Tiller doc, msp = setup() tangents = estimate_tangents(points, method='5-points') # Estimated tangent angles: (108.43494882292201, -108.43494882292201) degree m1, m2 = estimate_end_tangent_magnitude(points, method='chord') start_tangent = tangents[0].normalize(m1) end_tangent = tangents[-1].normalize(m2) # Interpolate control vertices from fit points and end derivatives as constraints s = global_bspline_interpolation(points, degree=3, tangents=(start_tangent, end_tangent)) msp.add_spline(dxfattribs={ 'color': 4, 'layer': 'Global Interpolation' }).apply_construction_tool(s) # Result does not matches the BricsCAD interpolation # tangents angle: (101.0035408517495, -101.0035408517495) degree msp.add_spline(points,
# tangents are stored explicit in the DXF file. spline = msp.add_spline( points, degree=3, dxfattribs={"layer": "BricsCAD B-spline", "color": 2} ) spline.dxf.start_tangent = Vec3.from_deg_angle(100) spline.dxf.end_tangent = Vec3.from_deg_angle(-100) zoom.extents(msp) doc.saveas(DIR / "concept-1-fit-points-and-tangents.dxf") # 3. Need control vertices to render the B-spline but start- and # end tangents are not stored in the DXF file like in scenario 1. # Estimation of start- and end tangents is required, best result by: # "5 Point Interpolation" from "The NURBS Book", Piegl & Tiller doc, msp = setup() tangents = estimate_tangents(points, method="5-points") # Estimated tangent angles: (108.43494882292201, -108.43494882292201) degree m1, m2 = estimate_end_tangent_magnitude(points, method="chord") start_tangent = tangents[0].normalize(m1) end_tangent = tangents[-1].normalize(m2) # Interpolate control vertices from fit points and end derivatives as constraints s = global_bspline_interpolation( points, degree=3, tangents=(start_tangent, end_tangent) ) msp.add_spline( dxfattribs={"color": 4, "layer": "Global Interpolation"} ).apply_construction_tool(s) # Result does not matches the BricsCAD interpolation # tangents angle: (101.0035408517495, -101.0035408517495) degree msp.add_spline( points, degree=3, dxfattribs={"layer": "BricsCAD B-spline", "color": 2}
def test_estimate_tangents_5p(): tangents = estimate_tangents(Vector.list(POINTS1), method='5-points') assert len(tangents) == 4
def test_estimate_tangents_3p(): tangents = estimate_tangents(Vec3.list(POINTS1), method='3-points') assert len(tangents) == 4