All studies

Moving least squares

Moving least squares

Anchor a ginkgo leaf’s stem and pull its fan-shaped blade. Local transformations bend the existing image around the points you control.

JavaScript · Canvas · Web Workers · Moving least squares

View source on GitHub

Try it

Runs locally in your browser. Uploaded images stay on your device.

Selected pin
Image uploads are resized to a 384px preview.

Drag a pin to deform the image. Double-click to add one. The selected pin also has keyboard-accessible position controls.

Source image
Source image
Precomputed Moving least squares example
Example · update to make your own

Ready when you are.

Worker processing · local inputs · downloadable output

How it works

Drag a pin to deform the image. Double-click to add one. The selected pin also has keyboard-accessible position controls.

Control points anchor the stem and fan of the leaf. Moving one point changes a continuous field of local transformations, bending the existing pixels while the other pins hold their positions. No missing content is synthesized.

  1. Give nearby control points more influence than distant ones.
  2. Solve a weighted rigid, similarity, or affine transformation separately at each mesh vertex.
  3. Warp a triangle mesh forward and resample its pixels, keeping control points interpolated.

Read the original research
Schaefer, McPhail & Warren · 2006

Computed examples

Outputs from the same implementation used in the playground.

Ginkgo leaf photograph · generated input
Deformed leaf · stem anchored, one point on the blade moved

Source photographs were generated for these studies. The displayed results were computed by the algorithms; they are not generated illustrations of an expected result. Published previews are compressed for the web.

Implementation and limits

The continuous deformation is approximated by a triangulated image mesh. The fixed-border option anchors the image edge; free borders can reveal transparent regions. Extreme crossed pins can still fold the mesh.

Interactive settings are bounded to keep the experiment practical in a browser. Higher detail can cost more processing time without guaranteeing a better result. The implementation and its tests are available in the source repository.