Basis polynomials#
Inputs#
This example evaluates five cubic B-spline basis functions, together with
their first and second derivatives. n=4 is the highest index, so there
are n+1=5 functions; p=3 is their degree. The knot vector has
n+p+2=9 entries:
[0, 0, 0, 0, 0.5, 1, 1, 1, 1]
Four repeated knots at each end clamp the basis. The single interior knot at \(u=0.5\) gives two spans with \(C^2\) continuity. The equations are developed in B-spline theory.
Complete script#
Run python demos/documentation/basis_polynomials.py, or
download the script.
"""Plot cubic B-spline basis functions and their first two derivatives."""
import numpy as np
import matplotlib.pyplot as plt
import nurbspy as nrb
nrb.set_plot_options()
n, p = 4, 3 # Five basis functions, each of degree three.
U = np.array([0., 0., 0., 0., 0.5, 1., 1., 1., 1.])
u = np.linspace(0., 1., 501)
N = nrb.compute_basis_polynomials(n, p, U, u)
dN = nrb.compute_basis_polynomials_derivatives(n, p, U, u, 1)
ddN = nrb.compute_basis_polynomials_derivatives(n, p, U, u, 2)
print("Basis array shape:", N.shape)
print("Basis at u=0.5:", N[:, 250])
print(f"Maximum partition-of-unity error: {np.max(np.abs(N.sum(axis=0) - 1)):.2e}")
print(f"Maximum first-derivative sum: {np.max(np.abs(dN.sum(axis=0))):.2e}")
print(f"Maximum second-derivative sum: {np.max(np.abs(ddN.sum(axis=0))):.2e}")
fig, axes = plt.subplots(1, 3, figsize=(12, 3.6), layout="constrained")
for ax, values, title in zip(axes, [N, dN, ddN],
["Basis functions", "First derivatives", "Second derivatives"]):
for i, row in enumerate(values):
ax.plot(u, row, label=f"i={i}")
ax.axvline(0.5, color="0.7", linestyle=":", linewidth=1)
ax.set(xlabel="u", ylabel="Value", title=title)
ax.grid(alpha=0.2)
axes[0].legend(fontsize=10)
plt.show()
Output#
N, dN, and ddN all have shape (5, 501). Each row holds one
basis function over the parameter samples. At the middle sample:
Basis array shape: (5, 501)
Basis at u=0.5: [0. 0.25 0.5 0.25 0. ]
The basis values sum to one. Their first and second derivatives sum to zero, up to floating-point roundoff, because they differentiate that constant sum.
Values, slopes, and second derivatives across the two knot spans.#
The first and last bases interpolate the ends. At most four cubic bases
are nonzero inside a span. To obtain Bernstein polynomials, set p=n
and use n+1 zeros followed by n+1 ones.