nurbspy.jax.nurbs_curve module#

class nurbspy.jax.nurbs_curve.NurbsCurve(control_points=None, weights=None, degree=None, knots=None)[source]#

Bases: Module

Create a NURBS (Non-Uniform Rational Basis Spline) curve object

Parameters:
control_pointsndarray with shape (ndim, n+1)

Array containing the coordinates of the control points The first dimension of P spans the coordinates of the control points (any number of dimensions) The second dimension of P spans the u-direction control points (0,1,…,n)

weightsndarray with shape (n+1,)

Array containing the weight of the control points

degreeint

Degree of the basis polynomials

knotsndarray with shape (r+1=n+p+2,)

The knot vector in the u-direction Set the multiplicity of the first and last entries equal to p+1 to obtain a clamped NURBS

Methods

get_arclength([u1, u2, tol])

Compute the arc length of the NURBS curve over the parameter interval [u₁, u₂] by numerically integrating the local curve speed as an ordinary differential equation (ODE).

get_arclength_quad([u1, u2, n_points])

Compute the arc length of the NURBS curve over the parameter interval [u₁, u₂] using fixed-point numerical quadrature.

get_binormal(u)

Evaluate the unit binormal vector along the curve for the given u-parameterization.

get_curvature(u)

Evaluate the curvature of the curve for the input u-parametrization

get_derivative(u, order)

Evaluate the derivative of the curve for the input u-parametrization

get_normal(u)

Evaluate the unit normal vector along the curve for the given u-parameterization.

get_tangent(u)

Evaluate the unit tangent vector along the curve for the given u-parameterization.

get_torsion(u)

Evaluate the torsion of the curve for the input u-parametrization

get_value(u)

Evaluate the coordinates of the curve for the input u parametrization

plot([fig, ax, curve, control_points, ...])

Create a plot and return the figure and axes handles

plot_control_points(fig, ax[, linewidth, ...])

Plot the control points of the NURBS curve

plot_curve(fig, ax[, linewidth, linestyle, ...])

Plot the coordinates of the NURBS curve

plot_frenet_serret(fig, ax[, frame_number, ...])

Plot some Frenet-Serret reference frames along the NURBS curve

project_points(Q_all[, tol])

Vectorized projection of multiple points onto the NURBS curve.

reparametrize_by_arclength([tol])

Construct a callable function that reparametrizes the NURBS curve by arc length, returning the corresponding parameter values u(s) for prescribed arc-length positions s.

reparametrize_by_coordinate([dim, tol])

Construct a callable function that reparametrizes the NURBS curve by one of its coordinate components, returning the corresponding parameter values u(x).

rescale_plot(fig, ax)

Adjust the aspect ratio of the figure

plot_curvature

plot_torsion

Notes

This class includes methods to compute:

  • Curve coordinates for any number of dimensions

  • Analytic curve derivatives of any order and number of dimensions

  • The unitary tangent, normal and binormal vectors (Frenet-Serret reference frame) in 2D and 3D

  • The analytic curvature and torsion in 2D and 3D

  • The arc length of the curve in any number of dimensions.

    The arc length is compute by numerical quadrature using analytic derivative information

The class can be used to represent polynomial and rational Bézier, B-Spline and NURBS curves The type of curve depends on the initialization arguments

  • Polymnomial Bézier: Provide the array of control points

  • Rational Bézier: Provide the arrays of control points and weights

  • B-Spline: Provide the array of control points, degree and knot vector

  • NURBS: Provide the arrays of control points and weights, degree and knot vector

In addition, this class supports operations with real and complex numbers The data type used for the computations is detected from the data type of the arguments Using complex numbers can be useful to compute the derivative of the shape using the complex step method

References

The NURBS Book. See references to equations and algorithms throughout the code L. Piegl and W. Tiller Springer, second edition

Curves and Surfaces for CADGD. See references to equations the source code G. Farin Morgan Kaufmann Publishers, fifth edition

All references correspond to The NURBS book unless it is explicitly stated that they come from Farin’s book

P: Array#
U: Array#
W: Array#
curve_type: str#
get_arclength(u1=0.0, u2=1.0, tol=1e-06)[source]#

Compute the arc length of the NURBS curve over the parameter interval [u₁, u₂] by numerically integrating the local curve speed as an ordinary differential equation (ODE).

The arc length of a parametric curve C(u) = [x(u), y(u), z(u)]ᵀ is defined as

L(u₁, u₂) = ∫ ‖C’(u)‖ du,

where C’(u) = dC/du and ‖C’(u)‖ = √(x’(u)² + y’(u)² + z’(u)²) is the instantaneous curve speed. This equation can be expressed as an initial-value problem:

ds/du = ‖C’(u)‖, s(u₁) = 0,

which is solved numerically over [u₁, u₂] to obtain the cumulative arc length L = s(u₂).

The ODE is integrated using a fifth-order Dormand-Prince (Dopri5) adaptive solver with a PID stepsize controller. The integration tolerances (relative and absolute) are both set to tol, which ensures consistent accuracy across varying cspeeds and curvatures.

Parameters:
u1float, optional

Lower limit of integration for the arc length computation (default: 0.0).

u2float, optional

Upper limit of integration for the arc length computation (default: 1.0).

tolfloat, optional

Relative and absolute tolerance for the adaptive ODE solver (default: 1e-6).

Returns:
Lfloat

Arc length of the curve segment C(u) for u ∈ [u₁, u₂].

get_arclength_quad(u1=0.0, u2=1.0, n_points=41)[source]#

Compute the arc length of the NURBS curve over the parameter interval [u₁, u₂] using fixed-point numerical quadrature.

The arc length of a parametric curve C(u) = [x(u), y(u), z(u)]ᵀ is defined as

L(u₁, u₂) = ∫‖C’(u)‖ du,

where C’(u) = dC/du and ‖C’(u)‖ = √(x’(u)² + y’(u)² + z’(u)²) is the local curve speed.

This function evaluates the integral in Eq. (1) using a Clenshaw-Curtis quadrature rule with a prescribed number of nodes n_points. The integrand is evaluated at fixed quadrature points, making this method computationally cheaper than adaptive ODE integration but generally less accurate for rational B-splines.

Parameters:
u1float, optional

Lower bound of the parameter domain (default: 0.0).

u2float, optional

Upper bound of the parameter domain (default: 1.0).

n_pointsint, optional

Number of quadrature points used in the Clenshaw-Curtis rule (default: 41).

Returns:
Lfloat

Arc length of the curve segment C(u) for u ∈ [u₁, u₂].

get_binormal(u)[source]#

Evaluate the unit binormal vector along the curve for the given u-parameterization.

The binormal is defined as:

b(u) = (C’(u) x C’’(u)) / ||C’(u) x C’’(u)||

Parameters:
uscalar or ndarray (N,)

Parametric coordinates.

Returns:
binormalndarray (ndim, N)

Unit binormal vectors.

get_curvature(u)[source]#

Evaluate the curvature of the curve for the input u-parametrization

The definition of the curvature is given by equation 10.7 (Farin’s textbook)

Parameters:
uscalar or ndarray with shape (N,)

Scalar or array containing the u-parameter used to evaluate the curvature

Returns:
curvaturescalar or ndarray with shape (N, )

Scalar or array containing the curvature of the curve

get_derivative(u, order)[source]#

Evaluate the derivative of the curve for the input u-parametrization

Parameters:
uscalar or ndarray with shape (N,)

Scalar or array containing the u-parameter used to evaluate the curve

orderinteger

Order of the derivative

Returns:
dCndarray with shape (ndim, N)

Array containing the derivative of the desired order The first dimension of dC spans the (x,y,z) coordinates The second dimension of dC spans the u parametrization sample points

get_normal(u)[source]#

Evaluate the unit normal vector along the curve for the given u-parameterization.

For 2D or 3D curves, the normal is defined as:
  • 2D: n(u) = (-t_y, t_x)

  • 3D: n(u) = (C’(u) x (C’’(u) x C’(u))) / ||C’(u) x (C’’(u) x C’(u))||

Parameters:
uscalar or ndarray (N,)

Parametric coordinates.

Returns:
normalndarray (ndim, N)

Unit normal vectors.

get_tangent(u)[source]#

Evaluate the unit tangent vector along the curve for the given u-parameterization.

The tangent is defined as:

t(u) = C’(u) / ||C’(u)||

Parameters:
uscalar or ndarray (N,)

Parametric coordinates.

Returns:
tangentndarray (ndim, N)

Unit tangent vectors.

get_torsion(u)[source]#

Evaluate the torsion of the curve for the input u-parametrization

The definition of the torsion is given by equation 10.8 (Farin’s textbook)

Parameters:
uscalar or ndarray with shape (N,)

Scalar or array containing the u-parameter used to evaluate the torsion

Returns:
torsionscalar or ndarray with shape (N, )

Scalar or array containing the torsion of the curve

get_value(u)[source]#

Evaluate the coordinates of the curve for the input u parametrization

Parameters:
uscalar or ndarray with shape (N,)

Parameter used to evaluate the curve

Returns:
Cndarray with shape (ndim, N)

Array containing the coordinates of the curve The first dimension of C spans the (x,y,z) coordinates The second dimension of C spans the u parametrization sample points

ndim: int#
p: int#
plot(fig=None, ax=None, curve=True, control_points=True, frenet_serret=False, axis_off=False, ticks_off=False, rescale=True)[source]#

Create a plot and return the figure and axes handles

plot_control_points(fig, ax, linewidth=1.25, linestyle='-.', color='red', markersize=5, markerstyle='o')[source]#

Plot the control points of the NURBS curve

plot_curvature(fig=None, ax=None, color='black', linestyle='-')[source]#
plot_curve(fig, ax, linewidth=1.5, linestyle='-', color='black', u1=0.0, u2=1.0)[source]#

Plot the coordinates of the NURBS curve

plot_frenet_serret(fig, ax, frame_number=5, frame_scale=0.1)[source]#

Plot some Frenet-Serret reference frames along the NURBS curve

plot_torsion(fig=None, ax=None, color='black', linestyle='-')[source]#
project_points(Q_all, tol=1e-06)[source]#

Vectorized projection of multiple points onto the NURBS curve.

The projection point C(u*) minimizes the squared Euclidean distance to Q:

f(u) = ||C(u) - Q||²

The stationary condition is obtained from:

f’(u) = 2 (C(u) - Q) · C’(u) = 0

which ensures that the vector from the curve to the point is orthogonal to the tangent of the curve at the projection point.

The nonlinear equation is solved with a bounded Newton method (optimistix.Newton), ensuring that u_star remains within [0, 1].

The initial guess is determined heuristically from the properties of the knot vector and control polygon

Parameters:
Q_allarray_like, shape (ndim, n_points)

Points to project onto the curve.

tolfloat, optional

Relative and absolute tolerance for the Newton solver (default: 1e-9).

Returns:
u_allndarray, shape (n_points,)

Parameter values of the orthogonal projections.

reparametrize_by_arclength(tol=1e-06)[source]#

Construct a callable function that reparametrizes the NURBS curve by arc length, returning the corresponding parameter values u(s) for prescribed arc-length positions s.

Let the parametric curve be

C(u) = [x(u), y(u), z(u)]ᵀ, u ∈ [0, 1].

The arc length of a parametric curve C(u) = [x(u), y(u), z(u)]ᵀ is defined as

s(u₁, u₂) = ∫ ‖C’(u)‖ du,

where C’(u) = dC/du and ‖C’(u)‖ = √(x’(u)² + y’(u)² + z’(u)²) is the instantaneous curve speed. This equation can be expressed as an initial-value problem:

ds/du = ‖C’(u)‖, with s(0) = 0,

which is solved numerically over [0, 1] to obtain the cumulative arc length s_total.

To obtain the inverse mapping u(s), this routine solves the reciprocal ODE

du/ds = 1 / ‖C’(u)‖, with u(0) = 0.

The integration of this equation yields a continuous function u(s) that relates the normalized arc-length coordinate s to the corresponding curve parameter u.

Computationally, the method proceeds in two stages:

  1. Compute the total arc length s_total by direct integration

  2. Obtain the inverse mapping u(s) by inverse integration

The method returns the total arc length s_total and a compiled, vectorized function handle u(s), built from a dense interpolation of the ODE solution, for efficient and differentiable evaluation of the inverse mapping.

Parameters:
tolfloat, optional

Relative and absolute tolerance for the adaptive ODE solver (default: 1e-6).

Returns:
u_of_scallable

A JAX-compiled, vectorized function u(s) constructed from a dense interpolation of the ODE solution. Evaluating u_of_s(s) returns the corresponding curve parameter(s) for prescribed arc-length position(s) s ∈ [0, s_total].

s_totalfloat

The total cumulative arc length of the curve over the parameter interval [0, 1].

reparametrize_by_coordinate(dim=0, tol=1e-09)[source]#

Construct a callable function that reparametrizes the NURBS curve by one of its coordinate components, returning the corresponding parameter values u(x).

Let the curve be defined parametrically as

C(u) = [C₀(u), C₁(u), …, Cₙ₋₁(u)]ᵀ, u ∈ [0, 1].

This function reparametrizes the curve using the coordinate C_dim(u) as the independent variable. For a given coordinate value x*, the corresponding parameter u* is obtained by solving

R(u) = C_dim(u) - x* = 0.

This equation is solved using a bounded Newton iteration implemented through optimistix.root_find, ensuring u* ∈ [0, 1]. The process is vectorized and JIT-compiled under JAX for efficient batch evaluation.

The resulting callable maps coordinate values x → u(x), providing the inverse parameterization where one coordinate (e.g. x) serves as the independent variable. The actual curve points can subsequently be obtained as C(u(x)) if desired.

The mapping is well-defined only if C_dim(u) is monotonic over [0, 1].

Parameters:
dimint, optional

Index of the coordinate used as independent variable. Default is 0 (the first coordinate component, typically x).

tolfloat, optional

Relative and absolute tolerance for the Newton solver (default: 1e-9).

Returns:
callable

A JAX-compiled, vectorized function handle u(x) that returns the parameter values corresponding to the specified coordinate values x, i.e.

u(x) = C_i⁻¹(x),

where C_i⁻¹ denotes the inverse mapping of the coordinate function C_i(u) over the domain [0, 1].

rescale_plot(fig, ax)[source]#

Adjust the aspect ratio of the figure

nurbspy.jax.nurbs_curve.binomial_coeff(n, k)[source]#

JAX-compatible binomial coefficient C(n, k) using the gamma function.

nurbspy.jax.nurbs_curve.compute_all_bspline_derivatives(P, p, U, u, up_to_order)[source]#

Compute all analytic derivatives of a polynomial B-spline curve up to a specified order.

This function evaluates the curve and its parametric derivatives using the analytic derivatives of the B-spline basis functions. For each derivative order k, the derivative of the curve is given by

C^(k)(u) = Σ_i P_i * d^k N_{i,p}(u) / du^k

Parameters:
Pndarray (ndim, n+1)

Control point coordinates.

pint

Degree of the B-spline.

Undarray (n+p+2,)

Knot vector.

undarray (Nu,)

Parametric evaluation points.

up_to_orderint

Maximum derivative order to compute (0 ≤ order ≤ p).

Returns:
bspline_derivativesndarray (up_to_order+1, ndim, Nu)

Derivatives of the B-spline curve, where bspline_derivatives[k, :, :] = d^k C(u) / du^k.

nurbspy.jax.nurbs_curve.compute_all_nurbs_derivatives(P, W, p, U, u, up_to_order)[source]#

Compute all analytic derivatives of a NURBS curve up to a specified order.

This function extends the polynomial B-spline derivative computation to rational NURBS curves by applying the quotient rule recursively, following Algorithm A4.2 from The NURBS Book (Piegl & Tiller, 2nd ed.):

Parameters:
Pndarray (ndim, n+1)

Control point coordinates.

Wndarray (n+1,)

Control point weights.

pint

Degree of the NURBS.

Undarray (n+p+2,)

Knot vector.

undarray (Nu,)

Parametric evaluation points.

up_to_orderint

Maximum derivative order to compute (0 ≤ order ≤ p).

Returns:
nurbs_derivativesndarray (up_to_order+1, ndim, Nu)

Derivatives of the NURBS curve

nurbspy.jax.nurbs_curve.compute_bspline_coordinates(P, p, U, u)[source]#

Evaluate the coordinates of a B-spline curve for a given parameter u.

This function computes the coordinates of a polynomial B-spline curve using the standard basis expansion (Equation 3.1 in The NURBS Book). The implementation corresponds to Algorithm A3.1.

Parameters:
Pndarray (ndim, n+1)

Array of control point coordinates. The first dimension spans spatial coordinates (x, y, z, …), and the second spans the control points along the curve (0, 1, …, n).

pint

Degree of the B-spline basis functions.

Undarray (r+1 = n + p + 2,)

Knot vector in the u-direction. The first and last entries typically have multiplicity p + 1 for a clamped spline.

uscalar or ndarray (N,)

Parametric coordinate(s) at which to evaluate the curve.

Returns:
Cndarray (ndim, N)

Coordinates of the evaluated B-spline curve points. The first dimension spans the spatial coordinates, and the second spans the parametric evaluation points u.

Notes

  • The computation is vectorized and uses matrix multiplication for efficiency.

  • For rational curves (NURBS), use compute_nurbs_coordinates instead.

nurbspy.jax.nurbs_curve.compute_nurbs_coordinates(P, W, p, U, u)[source]#

Evaluate the coordinates of a NURBS (Non-Uniform Rational B-Spline) curve for a given parameter u.

This function computes the coordinates of the NURBS curve in homogeneous space using the standard B-spline basis and the control point weights (Equation 4.5 in The NURBS Book), and then maps them back to ordinary space via the rational perspective division (Equation 1.16). The implementation corresponds to Algorithm A4.1 from The NURBS Book.

Parameters:
Pndarray (ndim, n+1)

Array of control point coordinates. The first dimension spans spatial coordinates (x, y, z, …), and the second spans the control points along the curve (0, 1, …, n).

Wndarray (n+1,)

Weights associated with each control point.

pint

Degree of the B-spline basis functions.

Undarray (r+1 = n + p + 2,)

Knot vector in the u-direction. The first and last entries typically have multiplicity p + 1 for a clamped spline.

uscalar or ndarray (N,)

Parametric coordinate(s) at which to evaluate the curve.

Returns:
Cndarray (ndim, N)

Coordinates of the evaluated curve points. The first dimension spans the spatial coordinates, and the second spans the parametric evaluation points u.

Notes

  • The computation is fully vectorized and uses matrix multiplication for efficiency.

  • The function supports arbitrary spatial dimensions.

nurbspy.jax.nurbs_curve.merge_nurbs_curves(nurbs_list)[source]#

Merge multiple NURBS curves into a single continuous curve with C⁰ continuity.

Parameters:
nurbs_listlist of NurbsCurve

List of NURBS curve instances to merge. All must have the same polynomial degree.

Returns:
mergedNurbsCurve

A new NURBS curve representing the concatenation of all input curves.

Notes

  • Each curve is mapped to a subinterval of [0, 1] with equal length.

  • Adjacent curves are connected with multiplicity p + 1 (C⁰ continuity).

  • A small epsilon offset is applied at internal joins to avoid Gmsh issues related to repeated knots with multiplicity exactly equal to degree.