Shapes β€” on-device shape recognition from a single stroke

Takes a single hand-drawn stroke (an ordered list of points) and recognizes it as a clean geometric shape, returning fitted vector geometry ready to snap to. Built for PencilKit-style "smart shapes": draw, pause, and the rough stroke becomes a crisp shape. The Core ML model is about 0.2 MB and runs in a few milliseconds on device.

✏️ ➜ β–­ Β· ✏️ ➜ β–³ Β· ✏️ ➜ β—― Β· ✏️ ➜ β˜…

Try it

  • Live demo: desert-ant-labs/shapes-demo β€” draw one stroke, get a fitted shape, fully in your browser.
  • iOS / macOS / visionOS: shapes-swift β€” Swift package with a one-line PKCanvasView.enableShapeSnapping() and a demo app.
  • Android / Kotlin / JVM: shapes-kotlin β€” the Kotlin SDK.
  • JavaScript / TypeScript: shapes-js β€” the npm package (Node + browser).

Files

File Format Size Contents
shapes.mlmodelc Compiled Core ML ~0.2 MB 4-bit-palettized classifier, ready to load on Apple platforms
shapes.safetensors safetensors ~0.2 MB packed 4-bit palettized portable weights for JS/Kotlin
shapes_meta.json JSON tiny classes, preprocessing constants, model dims, and snap gates for JS/Kotlin
model.pt PyTorch checkpoint ~1.5 MB trained weights (for export / fine-tuning)
config.json JSON tiny class list, preprocessing constants, and per-class snap gates

How it works

Two stages β€” the network proposes, geometry verifies:

  1. Classify β€” the stroke is resampled and fed to a compact sequence classifier (Conv1d stem β†’ small Transformer encoder β†’ masked mean-pool β†’ MLP), which predicts the shape type (or none to reject scribbles).
  2. Fit + snap β€” a classical geometric fitter produces clean vector parameters (min-area box, moment/PCA ellipse, max-area triangle, …), then regularizes them (snap to axes, circles, squares, and 15Β° rotation increments). A fit-residual gate vetoes poor fits so non-shapes stay rejected.

Inputs and outputs

  • Input: an ordered list of stroke points in canvas coordinates. Single stroke.
  • Output: a shape class plus fitted geometry β€” or nothing, if the stroke is rejected.

Classes

line, rectangle, triangle, ellipse, star β€” plus none (the reject class: scribbles, partial shapes, and other non-shape strokes). Squares and circles are covered by rectangle and ellipse (snapped when near-regular).

Limitations

  • Single stroke only; multi-stroke shapes aren't recognized.
  • Tuned for deliberate shapes; very rough or ambiguous strokes are rejected by design.

License

Released under the Desert Ant Labs Source-Available License v1.0 (see LICENSE.md).

  • Free for commercial use up to 100,000 Monthly Active Users (MAU).
  • Above 100,000 MAU a commercial license is required. Contact licensing@desertant.ai.

Citation

@software{shapes_2026,
  title  = {Shapes: on-device shape recognition from a single stroke},
  author = {Desert Ant Labs},
  year   = {2026},
  url    = {https://huggingface.co/desert-ant-labs/shapes},
}

Β© 2026 Desert Ant Labs Β· https://desertant.ai

Downloads last month
2
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Space using desert-ant-labs/shapes 1