Exact: values written as the kernel holds them — every enclosure’s
two bounds, to the bit — and read back the same, for what is kept to be
read again: a cache of what a file was made into
(geop_core_program::cache).
Vectors in plain numbers, [f64; N]: for what is only ever a free
choice or a picture — a section placed along a spline, a sample to draw,
a point to suggest — never for a result the kernel reasons about, which
is a crate::vector::Vector of scalars.
Generic 2-D polygon area, containment and triangulation — no topology
or rendering dependency, so it
lives here rather than in geop-core-rasterize: geop-core-topology’s
own edit code (splice_edge_into_face’s loop-orientation check) needs
it too, and topology sits below rasterize in the dependency order.
The kernel’s number: an interval [lo, hi] of f64, every operation
rounded outward, so that a value encloses every real it could be and
comparisons are three-valued (could_be_equal, definitely_greater).
Number is what a residual of the constraint solvers is written in:
a Scalar, or a crate::dual::Dual of one carrying derivatives.
Like format!, but for WithContext::with_context: builds a
ContextSource that formats its message lazily, only if the result is
actually an Err — .with_context(with_context!("failed at i={i}"))
costs nothing on the success path, unlike .with_context(&format!(...))
(eagerly formats every time, even when nothing is wrong).