This commit improves the initial guess we use for the Newton iteration
to solve the envelope equation when the best tangent we found arises
from a corner: instead of starting at (i = i0, s = 0), i.e. at the start
of the current curve in the spline, we might instead start at
(i = i0 - 1, s = 1).
This commit also improves the debug output to make it clearer which part
of the path goes forwards (little white dot above, inside fit points)
or backwards (little black dot below, inside fit points).
Different root isolation algorithms now live in separate modules,
and are all instances of the RootIsolationAlgorithm typeclass.
This separates the algorithmic code from the top-level driver code
in Math.Root.Isolation.
Based on ideas from the paper
"The Ins and Outs of Solving Quadratic Equations with Floating-Point Arithmetic"
(Frédéric Goualard, 2023)
Could still be improved further, but I think this is acceptable for now.
This commit bakes in a certain kind of representation for brush strokes:
c(t,s) = p(t) + R(theta(t)) b(t,s)
This representation allows us to cancel out some rotation terms when
computing the envelope equation, improving the efficiency of the
cusp-finding methods.
This commit makes it easier to switch between the 2-dim and 3-dim
formulations of the cusp-finding problem. This is still work in progress,
trying to improve the performance of the cusp-finding algorithms.
The code is now generic over the dimension. There is a slight performance
loss that I need to investigate; perhaps some things are not getting
specialised? Maybe it is better to be more explicit about staging and
splice in the functions with fixed dimensions.