Skip to content

Fix non-deterministic axis for 180-deg rotations (#366) - #372

Open
TabishShahMohsin wants to merge 2 commits into
dfki-ric:mainfrom
TabishShahMohsin:fix-180-deg-axis-deterministic
Open

Fix non-deterministic axis for 180-deg rotations (#366)#372
TabishShahMohsin wants to merge 2 commits into
dfki-ric:mainfrom
TabishShahMohsin:fix-180-deg-axis-deterministic

Conversation

@TabishShahMohsin

Copy link
Copy Markdown

Ensure norm_axis_angle and norm_axis_angles always return a deterministic rotation axis for angles of exactly pi by flipping negative leading non-zero vector components. Adds unit tests.

Fixes #366

Ensure norm_axis_angle and norm_axis_angles always return a deterministic rotation axis for angles of exactly pi by flipping negative leading non-zero vector components. Adds unit tests.
Copilot AI lite review requested due to automatic review settings August 14, 2026 11:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses Issue #366 by making norm_axis_angle and norm_axis_angles return a deterministic axis for 180° (π rad) rotations, removing the sign ambiguity between axis and -axis at π. It also adds unit tests to validate the deterministic behavior in both scalar and batch APIs.

Changes:

  • Canonicalize the rotation axis sign at angle π so the first non-zero component is positive.
  • Add scalar and batch unit tests covering negative-axis inputs at π.
  • Update normalization behavior documentation/tests for the deterministic π-axis rule.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
pytransform3d/rotations/_axis_angle.py Adds deterministic axis sign normalization for π rotations in norm_axis_angle.
pytransform3d/batch_rotations/_axis_angle.py Adds deterministic axis sign normalization for π rotations in norm_axis_angles.
pytransform3d/rotations/test/test_axis_angle.py Adds unit test for deterministic axis output at π in scalar normalization.
pytransform3d/batch_rotations/test/test_batch_rotations.py Adds unit test for deterministic axis output at π in batch normalization.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +97 to +107
# Issue #366: Make axis deterministic for 180 degree rotations
# the first non-zero component of axis should be positive.
if np.isclose(angle, np.pi):
is_zero = np.isclose(res[:3], 0.0)

non_zero_indices = np.where(~is_zero)[0]

if len(non_zero_indices) > 0:
first_non_zero_val = res[non_zero_indices[0]]
if first_non_zero_val < 0.0:
res[:3] *= -1.0
Comment on lines +97 to +99
# Issue #366: Make axis deterministic for 180 degree rotations
# the first non-zero component of axis should be positive.
if np.isclose(angle, np.pi):

# Issue #366: Make axis deterministic for 180 degree rotations
# the first non-zero component of axis should be positive.
pi_mask = np.isclose(res[..., 3], np.pi) & rot_mask
Comment on lines +289 to +298
def test_norm_axis_angle_180_degrees_deterministic():
a1 = np.array([-1.0, 0.0, 0.0, np.pi])
res1 = pr.norm_axis_angle(a1)
np.testing.assert_array_almost_equal(res1[:3], [1.0, 0.0, 0.0])
a2 = np.array([0.0, -1.0, 0.0, np.pi])
res2 = pr.norm_axis_angle(a2)
np.testing.assert_array_almost_equal(res2[:3], [0.0, 1.0, 0.0])
a3 = np.array([0.0, 0.0, -1.0, np.pi])
res3 = pr.norm_axis_angle(a3)
np.testing.assert_array_almost_equal(res3[:3], [0.0, 0.0, 1.0])
Comment thread pytransform3d/batch_rotations/test/test_batch_rotations.py Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

norm_axis_angles and norm_axis_angle should produce deterministic axis for 180 degree rotations

2 participants