fix(assembly): fix planar half-space correction causing drag flip with cylindrical joints #331

Closed
forbes wants to merge 0 commits from fix/planar-halfspace-drag-flip into main
Owner

Problem

When dragging a body connected by a Cylindrical joint + Distance=0 PlanePlane constraint, every drag step is rejected as 'flipped orientation' (>91 degrees). The solver converges fine but the C++ validator rejects the result, making the part appear frozen during drag.

Root Cause

In mods/solver/kindred_solver/preference.py, the _planar_half_space() function builds a half-space tracker for PlanarConstraint. When distance=0 (point already on the plane), it uses dot(z_i, z_j) as its indicator and provides a correction function that reflects the body through the plane.

When the body rotates about the cylindrical axis, its planar face normal rotates with it. After ~90 degrees of legitimate rotation, the dot product crosses zero, triggering the correction which teleports the body to the opposite side of the plane — a massive orientation change that the 91-degree threshold rightfully rejects.

Fix

Return a tracking-only HalfSpace (no correction_fn) when the point is already on the plane. This matches the pattern used by Cylindrical, Revolute, and Concentric half-space trackers. The cross-product residuals in PlanarConstraint already enforce normal alignment via the solver, so the correction is redundant and harmful during drag.

Testing

All 286 solver tests pass.

See: kindred/solver#38

## Problem When dragging a body connected by a **Cylindrical joint** + **Distance=0 PlanePlane constraint**, every drag step is rejected as 'flipped orientation' (>91 degrees). The solver converges fine but the C++ validator rejects the result, making the part appear frozen during drag. ## Root Cause In `mods/solver/kindred_solver/preference.py`, the `_planar_half_space()` function builds a half-space tracker for PlanarConstraint. When distance=0 (point already on the plane), it uses `dot(z_i, z_j)` as its indicator **and provides a correction function** that reflects the body through the plane. When the body rotates about the cylindrical axis, its planar face normal rotates with it. After ~90 degrees of legitimate rotation, the dot product crosses zero, triggering the correction which teleports the body to the opposite side of the plane — a massive orientation change that the 91-degree threshold rightfully rejects. ## Fix Return a **tracking-only HalfSpace** (no correction_fn) when the point is already on the plane. This matches the pattern used by Cylindrical, Revolute, and Concentric half-space trackers. The cross-product residuals in PlanarConstraint already enforce normal alignment via the solver, so the correction is redundant and harmful during drag. ## Testing All 286 solver tests pass. See: kindred/solver#38
forbes added 1 commit 2026-02-26 13:46:54 +00:00
fix(assembly): update solver submodule — fix planar half-space drag flip
All checks were successful
Build and Test / build (pull_request) Successful in 29m44s
d5af9804ec
Updates mods/solver to include fix for the planar half-space correction
that caused 'flipped orientation' rejections when dragging a body
connected by a Cylindrical joint + distance=0 Planar constraint.

The solver's PlanarConstraint half-space tracker was reflecting the body
through the plane when the face normal dot product crossed zero during
legitimate rotation about the cylindrical axis. Now returns a tracking-
only HalfSpace (no correction) for on-plane constraints, matching the
pattern used by Cylindrical/Revolute/Concentric trackers.

See: kindred/solver#38
forbes force-pushed fix/planar-halfspace-drag-flip from d5af9804ec to 559a240799 2026-02-26 15:04:35 +00:00 Compare
Author
Owner

Not a valid solution to constraint failure problem.

Not a valid solution to constraint failure problem.
forbes closed this pull request 2026-02-26 16:33:16 +00:00
Some checks failed
Build and Test / build (pull_request) Has been cancelled

Pull request closed

Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kindred/create#331