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-linePKCanvasView.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:
- 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
noneto reject scribbles). - 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