fix(solver): enforce quaternion continuity on dragged parts during drag (#338) #40
Reference in New Issue
Block a user
Delete Branch "fix/drag-quat-continuity"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
During interactive drag with Cylindrical + Planar constraints, the solver converges to valid but distinct quaternion branches on certain drag angles. The C++
validateNewPlacements()then sees a >91° rotation from the baseline and rejects the step, freezing the drag.The root cause:
_enforce_quat_continuityskipped dragged parts (if body.part_id in dragged_ids: continue). In a 2-body assembly (grounded + dragged bar), this meant the function did nothing. Newton re-solves the dragged part's free parameters to satisfy constraints and can land on a different constraint branch.Fix
Two-level correction in
_enforce_quat_continuity, applied to all non-grounded bodies including dragged parts:Hemisphere check (existing): if
dot(q_prev, q_solved) < 0, negateq_solved. Catches simpleqvs-qsign flips.Rotation angle check (new): compute the relative quaternion angle using the same formula as the C++ validator (
2*acos(w)). If it exceeds 91°, reset to the previous step's quaternion. This catches deeper branch jumps where the solver finds a geometrically different but constraint-satisfying orientation (e.g. Cylindrical + Planar with 180° ambiguity).Verification
Test
See solver#39 for the console test that reproduces this failure.
Refs: kindred/create#338