Skip to content

cuttlefisch/hobby-spline

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hobby-spline

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.

demo screenshot

Installation

pip install .

With demo dependencies (FastAPI frontend):

pip install .[demo]

With dev dependencies (pytest):

pip install .[dev]

Quick Usage

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.

Parameters

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

Running the Demo

The easiest way to start the demo server:

make serve

Or manually:

pip install .[demo]
uvicorn api.main:app --reload

Open 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.

Matplotlib Example

pip install matplotlib numpy
python examples/demo_matplotlib.py

Development

make test    # run pytest
make serve   # start the demo server

Algorithm

Hobby's algorithm solves for control point positions that produce a cubic Bézier spline with the following properties:

  1. The curve passes through all input points (knots)
  2. Curvature varies smoothly along the curve
  3. 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.

References

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

License

GPLv3 — see LICENSE.

About

Implement Hobby's algorithm for fitting a cubic bezier curve in 2 and 3 dimensions

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors