Skip to content

Do not rebuild the rotation matrices after every arithmetic operation on quaternion#481

Open
Rombur wants to merge 1 commit into
adamantine-sim:masterfrom
Rombur:rotation_matrix
Open

Do not rebuild the rotation matrices after every arithmetic operation on quaternion#481
Rombur wants to merge 1 commit into
adamantine-sim:masterfrom
Rombur:rotation_matrix

Conversation

@Rombur

@Rombur Rombur commented Jun 2, 2026

Copy link
Copy Markdown
Member

Currently we are rebuilding the rotation matrices after every arithmetic operation on quaternion. This was fine because we were doing very few arithmetic operations. This changed with #479, where we do lots of operations. With this PR, we have to explicitly build the matrices which is done at most once every time step.

Drive-by change: remove ScanPath::rotate. There is already a function to rotate a Point when the quaternion is known and so, this is basically a duplicate.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request refactors rotation handling by removing the ScanPath::rotate method and making Quaternion::build_rotation_matrices a public method that is called explicitly after interpolation in ScanPath::get_quaternion, rather than automatically inside every arithmetic operation. The feedback suggests optimizing performance by refactoring Quaternion::operator/= to avoid redundant matrix building, caching the last computed quaternion in ScanPath to prevent duplicate Slerp interpolations, and adding a validity assertion in build_rotation_matrices for safety.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread source/ScanPath.cc
@@ -337,6 +324,7 @@ Quaternion ScanPath::get_quaternion(double const time) const
interpolated_rotation /= segment_start_rotation;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Note that Quaternion::operator/= currently constructs a temporary Quaternion for the inverse, which internally calls build_rotation_matrices(). Since this temporary's rotation matrices are never used, this results in an unnecessary matrix build during the Slerp interpolation.

Consider refactoring Quaternion::operator/= in source/Quaternion.cc to perform the division directly (by negating the imaginary components of the divisor and performing the Hamilton product) without creating a temporary Quaternion object. This will avoid the redundant matrix building overhead.

Comment thread source/ScanPath.cc
return get_quaternion(time).rotate(point);
}

Quaternion ScanPath::get_quaternion(double const time) const

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Since get_quaternion(time) is called both in update_time and get_bounding_box for the same time step, the expensive Slerp interpolation and matrix building are performed twice per time step.

Consider caching the last computed quaternion and its corresponding time using mutable member variables in ScanPath (e.g., mutable double _cached_quaternion_time and mutable Quaternion _cached_quaternion). If time == _cached_quaternion_time, you can return the cached quaternion directly, avoiding redundant computations.

Comment thread source/Quaternion.cc
build_rotation_matrices();
}

void Quaternion::build_rotation_matrices()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Since build_rotation_matrices() is now a public method, it can be called on uninitialized or invalid Quaternion instances.

Consider adding ASSERT(_is_valid, "Quaternion is not valid."); at the beginning of build_rotation_matrices() to enforce defensive programming and catch potential bugs early.

@Rombur Rombur force-pushed the rotation_matrix branch from fe062aa to 3860b7d Compare June 4, 2026 17:53
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.

1 participant