Experimentation and some preliminary results (
@DeepSOIC @abdullah ) on scaling up the angle constraints to size constraints
So far:
- "modernized" a bit of the code (using hypot instead of sqrt(x^2, y^2), introducing lerp - based on std::fma - instead on linCombi, ...)
- filled-in what I saw as some gaps in the DeriVector2 - added crossProd, rotateCCW_D, rotate CW_D and some other minor thingies
- converted most of the non-trivial constraints to the use of DeriVector2 maths (I used the errorgrad(double* err, double* grad, double* param) pattern). Still have a few (e.g. I converted PointOnEllipseand some others but not yet PointOnHyperbola, I'll need to sweep again for others). I guess they worked fine before and they would not have needed the DeriVector2 arithmetic, but the amount of lines of code dropped and the readability jumped)
No hard promise, but I'll likely round all up next weekend and send a pull request for you to review and maybe merge.
================
Now, about those angle constraints, I used the
DeriVector2 arithmetic to transform
ConstraintL2LAngle and
ConstraintP2PAngle from radians to size/dimensions errors - the constraints for which one has info about the element of size without residing on hacks.
The good news is that my modification work - my additions to the DeriVector2 arithmetic are correctly coded.
Performance-wise, the results are... underwhelming, at least as perceived from using the UI. The "UI dragging" on the...
- line elements involved in constraints - unchanged
- points that define those line - slightly choppier/jumpier
This seems to suggest that whatever potential improvements of "radians->size" one the solver convergence rate the "bring everything on a uniform OoM scale" are negated by extra convergence steps required to get everything under the 1Å tolerance.
(My apologies in advance if I'm stating the obvious in what's following, I'm still getting my head adjusted to the specifics of the geometric constraints solving)
If the "express everything in dimension units" is to be still pursued, for squeezing some extra performance, one will need to use the approach of
- scale down everything at some reasonable dimensions. Use power-of-two scaling factors, so that the scaling will have an effect only on the exponent of the IEEE754 and lets their mantissa unaffected (not that the sqrt(sum(square_distances)) cares much about linear FP errors, but anyway why make matters worse?)
- solve
- restore the initial scale
One needs to note that the above is actually equivalent to
using a relative tolerance. Because if I'm asking
1e-10 tolerance but I'm scaling everything down before using a
1e-3 factor, after going through the steps above one will get a solution that's good within a
1e-7 tolerance.
It may still worth pursuing
for sketches > 100m sizes and/or if one is willing to sacrifice
some precision to the altar of performance gods.