MCPcopy Index your code
hub / github.com/dorianprill/stroke

github.com/dorianprill/stroke @v0.3.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.3.0 ↗ · + Follow
313 symbols 869 edges 23 files 186 documented · 59% updated 5mo agov0.3.0 · 2026-01-22★ 511 open issues

Browse by type

Functions 296 Types & classes 17
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

stroke

Rust crates.io

A Cubic Bézier Curve with Bounding Box and Convex Hull rendered by plotters.rs

made with plotters.rs

A zero-allocation library providing const-generic implementations of Bézier curves, B-Spline curves and specialized implementations of up to cubic Bézier curves in N-dimensional euclidean space. It is intended for general/embedded/wasm use supporting #![no_std] environments written in 100% safe Rust with minimal dependencies.

The library makes heavy use of const-generics and generic_const_exprs, so the nightly compiler is required.
This repo uses nightly via rust-toolchain.
It comes with a const-generic N-dimensional Point type so you can use the library without any other dependencies.
PointN<T, N> uses your chosen scalar T (typically f32/f64) and keeps the dimension at compile time.
Should you want to integrate with types provided by another library, implement the small Point trait. Optional extension traits (PointIndex, PointDot, PointNorm) unlock component access and geometric helpers when needed.

Right now, the generic versions don't implement all methods that the specialized versions do (as the algorithms get a bit more complicated) but should reach parity eventually.

Integration features

  • nalgebra: implements Point for nalgebra::SVector<T, D> (no_std + libm). Requires T: nalgebra::RealField + num_traits::Float (typically f32 or f64).

Example:

use nalgebra::SVector;
use stroke::Bezier;

let curve = Bezier::<SVector<f32, 2>, 3>::new([
    SVector::<f32, 2>::new(0.0, 0.0),
    SVector::<f32, 2>::new(1.0, 0.0),
    SVector::<f32, 2>::new(1.0, 1.0),
]);

let mid = curve.eval(0.5);

Enable with:

stroke = { version = "0.3.0", features = ["nalgebra"] }
nalgebra = { version = "0.32", default-features = false, features = ["libm"] }

Goals

  • Provide generic Bézier curves and B-Splines. Due to their frequent usage, further provide lines, quadratic and cubic Bézier curves
  • Support no-std for all targets
  • Extensive unit testing and code coverage
  • Integration tests for other generic math libraries (TBD - maybe optimath, aljabar, micromath, nalgebra) since Point types are replicated in many libraries

Non-Goals

  • Focus on use for rendering or highest performance (no GPU)

Features

These are the main supported features. Some further utility methods are exposed where useful.

Quadratic and Cubic Bézier Curves

  • [x] evaluation (De Casteljau, direct)
  • [x] split
  • [x] derivative
  • [x] tangent (unit)
  • [x] normal (principal)
  • [x] curvature (magnitude)
  • [x] arc length (linear approx.)
  • [ ] arc length (Legendre-Gauss)
  • [ ] Frenet-Serret frame / torsion
  • [x] bounding box
  • [ ] tight box

Generic Bézier Curves

  • [x] evaluation (De Casteljau)
  • [x] split
  • [x] derivative
  • [x] tangent (unit)
  • [x] normal (principal)
  • [x] curvature (magnitude)
  • [x] arc length (linear approx.)
  • [ ] arc length (Legendre-Gauss)
  • [ ] Frenet-Serret frame / torsion
  • [x] bounding box
  • [ ] tight box

Generic B-Splines

  • [x] evaluation (De Boor)
  • [x] split
  • [x] derivative
  • [x] basis functions (and derivatives)
  • [x] tangent (unit)
  • [x] normal (principal)
  • [x] curvature (magnitude)
  • [x] arc length (linear approx.; returns Result on eval errors)
  • [ ] arc length (Legendre-Gauss)
  • [ ] Frenet-Serret frame / torsion
  • [x] bounding box
  • [ ] tight box

Approximation Notes

  • arclen and distance_to_point* use sampling-based approximations; increase steps for accuracy.
  • BSpline::arclen returns Result because evaluation is fallible outside the knot domain.

Examples

  • bezier_path: mixed Bezier path segments; run cargo run --example bezier_path.
  • bspline_path: basic B-spline path evaluation; run cargo run --example bspline_path.
  • bspline_signal_1d: 1D signal interpolation with a cubic B-spline; run cargo run --example bspline_signal_1d.
  • bezier_quarter_circle: cubic Bezier quarter-circle approximation; run cargo run --example bezier_quarter_circle.
  • arc_length_sampling: equal-arc-length sampling along a Bezier curve; run cargo run --example arc_length_sampling.
  • tangent_normal_curvature: sample tangent/normal/curvature; run cargo run --example tangent_normal_curvature.
  • plotters_cubic_bezier: render a cubic Bezier with plotters; run cargo run --example plotters_cubic_bezier.
  • nalgebra_basic: Bezier with nalgebra SVector; run cargo run --example nalgebra_basic --features nalgebra.

Related

If you're looking for a published crate for rendering with gpu support you should check out Lyon from which I draw some inspiration, it's really good. It features lines, quadratic and cubic Béziers, in addition to arcs, triangles, and other geometric objects but no general Bézier curves or B-Splines. It also does seem to support wasm.

Also, there's Twinklebear/bspline which is a very clean and useful library for just bsplines. However, it depends on std and its simple Interpolate trait defines no way to access the individual dimensions of the points and hence implements no derivatives in the library.

This clear online book A Primer on Bézier Curves helped me with a lot of the algorithms involved.

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Method 218
Function 78
Class 8
Interface 5
Enum 4

Languages

Rust100%

Modules by API surface

src/bspline.rs63 symbols
src/bezier.rs45 symbols
src/quadratic_bezier.rs37 symbols
src/cubic_bezier.rs36 symbols
src/path.rs29 symbols
src/bspline_path.rs27 symbols
src/line.rs23 symbols
src/bezier_segment.rs19 symbols
src/point_generic.rs10 symbols
src/point.rs6 symbols
examples/bspline_signal_1d.rs5 symbols
examples/tangent_normal_curvature.rs3 symbols

For agents

$ claude mcp add stroke \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page