Geometry

Triangulate

Take a photograph and rebuild it out of coloured triangles. The rule I set myself was no machine learning and no computer-vision libraries. The sphere at the top of this site is one of its runs.

View repository
  • C++
  • Python
  • No dependencies
Timeline
Public repo · Sep 2026 – present
Role
Independent developer
Scope
Barycentric rasterisation, alpha compositing, random search
Status
V1 complete · 350 triangles reach 12.2% of the starting error
The sphere from the top of this page, reconstructed from 350 coloured triangles.
0 / 0 triangles
Error now
100.0%
Candidates each
0
Dependencies
0
A real run: 350 triangles at 6,000 candidates each, ending at 12.2% of the starting error. The curve is that run's error at every step.

What it does

The canvas starts as the mean colour of the target. For each new triangle the program generates thousands of random candidates, sets each one’s colour to the mean of the target underneath it, and keeps whichever lowers the squared error most. Coverage comes from the edge function, so either winding order works without a special case.

What was hard

Recomputing the loss over the whole image is far too slow to try six thousand candidates per triangle, so scoring touches only the bounding box and accumulates a difference instead. That is fast, but it can drift. The program recomputes the error from scratch at the end and prints it beside the running total, and if the two disagree the incremental scoring is wrong somewhere.

Where it goes next

Placement is still uniformly random, when it should start where the residual is large. Colour is fitted as a plain mean, but with the canvas and the opacity held fixed the best colour has a closed form, and so does the best opacity for a fixed colour. Alternating those exact updates should beat random search on both quality and speed.

350Triangles in the reference run
12.2%Of the starting error
0Third-party dependencies

Curious about something here? Ask me about it

Next projectGeoDashML Reinforcement learning · C++ and Python