Turn a rough circle drawing into a clean shape, with fitted vector geometry ready to
snap to. Built
for PencilKit-style "smart shapes": draw, pause, and the rough stroke becomes a
crisp shape. The model is tiny (200KB Core ML, 1.3MB LiteRT) and
runs in a few milliseconds on device.
1npm i @desert-ant-labs/shapes @litertjs/core # browser2npm i @desert-ant-labs/shapes # Node, prebuilt native core
Files
File
Format
Size
Contents
shapes.tflite
LiteRT / TFLite (fp32)
1.3MB
Fixed [1,256,3] features + [1,256] mask window; runs on Android, Linux, Node, and the web (bundled by default in the Kotlin SDK; downloaded on demand by the JavaScript SDK)
shapes.mlmodelc
Compiled Core ML
200KB
4-bit-palettized classifier, ready to load on Apple platforms (used by the Swift SDK)
shapes_meta.json
JSON
tiny
classes, preprocessing constants, model dims, and snap gates
shapes.safetensors
safetensors
200KB
packed portable weights (reference)
model.pt
PyTorch checkpoint
1.5MB
trained weights (for export / fine-tuning)
config.json
JSON
tiny
class list, preprocessing constants, and per-class snap gates
Older revisions (tag v0.1.0) carry shapes.onnx for SDK versions that predate the LiteRT migration.
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 none to 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.