def add_spline( self, fit_points: Iterable["Vertex"] = None, control_points: Iterable["Vertex"] = None, knot_values: Iterable[float] = None, weights: Iterable[float] = None, degree: int = 3, periodic: int = 0, start_tangent: "Vertex" = None, end_tangent: "Vertex" = None, ) -> "SplineEdge": """Add a :class:`SplineEdge`. Args: fit_points: points through which the spline must go, at least 3 fit points are required. list of (x, y)-tuples control_points: affects the shape of the spline, mandatory and AutoCAD crashes on invalid data. list of (x, y)-tuples knot_values: (knot vector) mandatory and AutoCAD crashes on invalid data. list of floats; `ezdxf` provides two tool functions to calculate valid knot values: :func:`ezdxf.math.uniform_knot_vector`, :func:`ezdxf.math.open_uniform_knot_vector` (default if ``None``) weights: weight of control point, not mandatory, list of floats. degree: degree of spline (int) periodic: 1 for periodic spline, 0 for none periodic spline start_tangent: start_tangent as 2d vector, optional end_tangent: end_tangent as 2d vector, optional .. warning:: Unlike for the spline entity AutoCAD does not calculate the necessary `knot_values` for the spline edge itself. On the contrary, if the `knot_values` in the spline edge are missing or invalid AutoCAD **crashes**. """ spline = SplineEdge() if fit_points is not None: spline.fit_points = Vec2.list(fit_points) if control_points is not None: spline.control_points = Vec2.list(control_points) if knot_values is not None: spline.knot_values = list(knot_values) else: spline.knot_values = list( open_uniform_knot_vector(len(spline.control_points), degree + 1) ) if weights is not None: spline.weights = list(weights) spline.degree = degree spline.rational = int(bool(len(spline.weights))) spline.periodic = int(periodic) if start_tangent is not None: spline.start_tangent = Vec2(start_tangent) if end_tangent is not None: spline.end_tangent = Vec2(end_tangent) self.edges.append(spline) return spline
def spline(self): points = [(0, 0), (1, 2), (2, 4), (3, 1), (4, 2)] # by default knot values are normalized in the range [0, 1], # this creates a not normalized knot vector in the range [0, 2]: knots = open_uniform_knot_vector(count=len(points), order=4) return BSpline( [(0, 0), (1, 2), (2, 4), (3, 1), (4, 2)], knots=knots, )
def set_open_uniform(self, control_points: Sequence['Vertex'], degree: int = 3) -> None: """ Open B-spline with uniform knot vector, start and end at your first and last control points. """ self.dxf.flags = 0 self.dxf.degree = degree self.control_points = control_points self.knots = open_uniform_knot_vector(len(control_points), degree + 1)