Fit aesthetic cubic Bézier curves in 2D and 3D using Hobby's algorithm — the same approach used in METAFONT and METAPOST for producing smooth, visually pleasing splines through a set of points.
pip install .With demo dependencies (FastAPI frontend):
pip install .[demo]With dev dependencies (pytest):
pip install .[dev]from euclid3 import Point3
from hobby_spline import hobby_points
knots = [Point3(0, 0), Point3(1, 2), Point3(3, 3), Point3(4, 1)]
spline = hobby_points(knots, omega=0.5, tension=1.5)
# spline is a flat list of Point3: [knot, ctrl1, ctrl2, knot, ctrl1, ctrl2, knot, ...]
# Each group of (knot, ctrl1, ctrl2, next_knot) defines one cubic Bézier segment.| Parameter | Type | Default | Description |
|---|---|---|---|
points |
list of points | — | Input knot points (2D tuples or Point3 objects) |
omega |
float | 0 | Endpoint curl, range [0, 1] |
close_loop |
bool | False | Connect last point back to first |
tension |
float | 1.0 | Curve tightness (≥ 0.75); higher = tighter |
The easiest way to start the demo server:
make serveOr manually:
pip install .[demo]
uvicorn api.main:app --reloadOpen http://localhost:8000 in your browser. The demo has two tabs:
- 2D Curves — click to add points, drag to move, right-click to delete. Adjust tension and omega with sliders.
- 3D Curves — visualize Hobby curves as tube geometry with orbit controls. Tension and omega sliders auto-update the 3D view.
pip install matplotlib numpy
python examples/demo_matplotlib.pymake test # run pytest
make serve # start the demo serverHobby's algorithm solves for control point positions that produce a cubic Bézier spline with the following properties:
- The curve passes through all input points (knots)
- Curvature varies smoothly along the curve
- The curve has no unnecessary inflection points
It works by setting up a tridiagonal system of linear equations relating the turning angles between successive chords, then solving for the angles between each chord and its adjacent control-point handles using the Thomas algorithm.
This implementation is based on Jake Low's blog post and JavaScript source, adapted to Python and extended to 3D.
- J.D. Hobby, "Smooth, Easy to Compute Interpolating Splines", Discrete and Computational Geometry 1, 1986. PDF
- B. Jackowski, "Typographers, programmers and mathematicians", TUGboat 34(2), 2013. PDF
GPLv3 — see LICENSE.
