Primitive
Study
Working question: what can a photograph become when it is rebuilt from simple geometric decisions?
The thing is a vector abstraction process based on stacked shapes and hill climbing. It is a way to study image reduction rather than only image conversion.
The current page explains the implementation. The study note still needs the observation layer: what kinds of images survive abstraction, where the process lies, and how this relates to Vectorize, Generative Art, and plotting.
Primitive is a Java port of Michael Fogleman’s primitive. It rebuilds photographs as abstract vector images by stacking many semi-transparent geometric shapes.
Source: github.com/utrost/Primitive · License: AGPL-3.0 · Original: Michael Fogleman, MIT
Blind painting
The algorithm behaves like a painter who cannot see the canvas, only measure error.
Pick a random shape. Put it somewhere. Ask whether the image is now closer to the target. If yes, keep it. If no, throw it away and try again. Repeat this many times.
That is hill climbing. No model. No training data. Just trial and error, scored against the target image.
The look comes from the process: translucent fragments stacking until a portrait, still life, or landscape begins to appear.
How it works
Each shape is added in four steps.
- Generate a random shape: triangle, Bézier curve, ellipse, rotated rectangle, polyline, or combo.
- Mutate it many times by nudging points, shifting control handles, or changing width.
- Score each mutation with RMSE against the target image.
- Commit the best shape and move to the next one.
The color is not guessed. For a given shape outline, the optimizer can calculate the RGBA value that minimizes error against the target region.
Speed notes
The original is written in Go. This port is tuned for the JVM.
The hot path avoids allocation. Candidate shapes are rasterized into reusable primitive arrays instead of short-lived objects, so the garbage collector stays out of the inner loop.
Shape search runs in parallel. Each worker tries its own candidates on thread-local buffers. The main thread only collects the best result.
The RMSE calculation uses the Java Vector API, so the hottest pixel loop can use AVX or AVX-512 where available.
Shape modes
The mode changes the character of the output.
- Triangle: soft and painterly.
- Thick line: harsher, closer to a woodcut.
- Quadratic Bézier: smooth curves.
- Rotated rectangle: architectural, almost Mondrian-like.
- Polyline: sketchy and hand-drawn.
- Ellipse: soft focus, sometimes pointillist.
- Combo: all modes compete and the optimizer keeps whatever scores best.
The same photograph rendered as 200 triangles and 200 Bézier curves becomes two different images.
Plotter problem
Every run produces a PNG preview and an SVG. The SVG scales cleanly, but plotting it is not straightforward.
Primitive relies on transparent filled shapes. A pen plotter draws opaque lines. It cannot reproduce alpha blending directly.
One useful direction is to convert filled shapes into hatch patterns. Dense hatching could stand in for dark or opaque regions; sparse lines for lighter ones. That would turn Primitive’s layered transparency into something a pen can draw.
GUI
The Swing interface shows the optimization while it runs. Drop in an image, choose a shape mode, start the run, and watch the image appear shape by shape. A live log shows score and timing.
See also: Generative Art, Gantry, PPCT, CityPlot, Vectorize, From Pixel to Pen, SVGToolBox, VHS