vibespire.ai / Euclid /

how it's made

open the sandbox

Vibespire presents

How Euclid Is Made Dynamic

Two circles meet in two places. Deciding which one a construction meant — every frame, under any drag, without the answer ever jumping — is the single hardest problem in dynamic geometry, and almost everything else in this project is downstream of how it is solved.

CHOSEN THE OTHER ONE

Both figures on this page run the engine's own construction model.

The model

A figure is a dependency graph

Nothing in a construction stores a picture. It stores a list of operations — free point, line through two points, circle centred here and passing through there, intersect these two — held in topological order, so an object is always added after everything it depends on.

That ordering is doing real work. Because inputs always come first, recomputing the whole figure is a single forward pass over the list: no graph traversal, no dirty flags, no cycle detection. Drag a free point, walk the list once, and every dependent object has its new value.

There are only two kinds of point that a person can move. A free point holds its own coordinates. A free-on point holds a parameter along a parent line or circle, so it slides but cannot leave. Everything else — every intersection, every midpoint, every perpendicular — is derived, and has no coordinates of its own to be dragged.

Objects carry a role rather than a colour: given, result, area or auxiliary. The renderer maps those to Byrne's 1847 scheme — the given figure in red, equal areas in yellow, construction lines in dashed purple — which is the point of the exercise. Byrne replaced the letters in Euclid's text with coloured shapes so a proposition could be read without cross-referencing a diagram. Colour is notation, not decoration, and it costs nothing to keep it that way if the objects know what they are.

The whole model is about two hundred lines. Everything difficult about it is in one method.

The hard part

Which of the two intersections did you mean?

A line and a circle meet in two points. Two circles meet in two points. A construction has to pick one, and it has to pick the same one as the figure moves — including through the moments where the two swap places.

The naive answer is an index: take candidate zero of a stably-ordered pair. It is fine until the ordering key stops being invariant. The figure beside this offers a policy called topmost — pick whichever candidate has the larger world y — which is exactly that mistake made visible. Drag B above A so the base turns over, and the apex pops to the reflected point. The construction is still correct; it is just no longer the construction you were looking at.

The policy the engine actually uses for authored figures is orient: pick the candidate on a chosen signed side of a directed reference line. For the equilateral triangle on AB, that is “the apex above A→B”, where “above” means the sign of the cross product rather than a screen direction. Rotate the base as far as you like and the apex comes with it, because the rule is stated in terms the rotation preserves.

Three more policies exist for cases orient cannot express. near takes the candidate closest to this object's previous value, which is the right answer for free-hand dragging and the wrong one for anything that has to be reproducible. other takes the candidate that is not some already-known point, which is what you want when two circles share a point by construction. sameDir takes the one lying along a given ray.

Any policy that remembers a previous value can be outrun. So dragging subdivides its own motion into micro-steps and recomputes at each one, which is what stops a fast flick from leaping across a tangency where two candidates briefly coincide.

policy

The engine's own Construction and Byrne renderer. Drag A or B.

Hands on

Try it

A right triangle with a square on each side, and the randomized checker's verdict underneath. Drag any corner: the squares follow, and the checker re-runs two hundred jittered right-angled configurations every time you let go.

show

The actual Construction, Byrne renderer and runChecks, imported by this page.

The checker

Evidence, and the careful word for it

The badges in this project that say a proposition holds are produced by a randomized property checker, and the source is unusually blunt about what that means: it does not prove anything.

What it does is stress-test a predicate across many random configurations — two hundred by default — and report how many passed and how far the worst one was off. The predicates are the obvious ones, each returning a pass and a relative error rather than a boolean: equal lengths, equal areas, collinearity, perpendicularity, and a² + b² against c².

Every tolerance is relative, scaled by the magnitude of what is being compared, because an absolute epsilon that works for a unit triangle is nonsense for one ten times the size. And the checker is deliberately kept off the render frame: it runs on drag-end or a throttled tick with a fixed sample budget, never hundreds of re-solves per frame.

Calling that evidence rather than proof is the honest description, and it is the one the code uses. A construction that survives two hundred random configurations to within a thousandth is very probably right, and “very probably right” is a different thing from what Euclid was doing.

It is also the only module in the project that touches a random number generator. Everything else is deterministic, which is what makes a figure a shareable URL.

Compilation

A construction is a string

Because the model is an ordered list of operations, the operations serialise. A construction compiles to a short step list — F for a free point, C for a circle, X for an intersection — which round-trips through a URL.

That is what makes the sandbox shareable and the chapter demos reproducible: a figure is not an image or a save file, it is the recipe that built it, and replaying the recipe on a different screen produces the same figure. The player that steps through a proposition one operation at a time is reading the same list.

The other consequence is that macros are just functions. The equilateral apex, the perpendicular bisector, the midpoint, a dropped perpendicular, a reflection — each is a handful of calls to the same model, tagging its scaffolding as auxiliary so the renderer dashes it in purple and the reader can see which lines are the argument and which are the working.

Euclid's propositions build on earlier propositions. So does this: I.10 is the perpendicular bisector, which is two circles and their two intersections, which is I.1 twice.

The bill

What this approach costs

A live construction model buys figures that move and stay true. It gives up the thing Euclid was actually doing, and a few smaller things besides.

Nothing here is a proof. The engine constructs and it measures. It does not reason, does not chain propositions into deductions, and cannot tell you why a result holds — only that it kept holding across a couple of hundred tries. The Elements is a book of arguments; this is a book of demonstrations.

Branch policies are authored, not inferred. Every intersection in every figure carries a hand-chosen policy and, for orient, a hand-chosen reference and side. Get one wrong and the figure looks perfect until somebody drags it somewhere you did not try.

Continuity can still be broken. Micro-stepping a drag makes the nearest-to-previous policies robust, not correct: a sufficiently fast pointer, or a construction dragged through an exact tangency where the two candidates coincide, has no continuous answer to give.

Floating point is the ground truth. Collinearity is a cross product under a tolerance; a right angle is a dot product under a tolerance. Degenerate configurations — three points nearly on a line, a circle nearly tangent — are decided by an epsilon rather than by a fact.

Colour-as-notation needs a legend. Byrne's scheme is beautiful and it is not self-explanatory; a reader who does not know that red is the given figure and dashed purple is scaffolding sees a pretty diagram rather than a sentence.

The colour scheme is Oliver Byrne's, from his 1847 edition of the first six books of the Elements; the randomized-checking idea follows Cinderella's approach to dynamic geometry, in a much simpler form.

Two hundred lines of model, one method that decides which of two points you meant, and a renderer that treats colour as grammar. Everything else on the page is those three things applied to a proposition.

Open the sandbox ↗

Marcin — creator of vibespire.ai

About

Hi, I'm Marcin.

I build these experiments whenever something sparks my curiosity — a paper, a game, the way grass bends in the wind, the smallest everyday things. Inspiration shows up, and I chase it into a little living world you can open in a browser.

vibespire is where those experiments live. Poke at them, break them, read how they're made — and if something sparks an idea for you too, say hello.