-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
[ENH]: Natural 3D rotation with mouse #28288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
- Addresses Issue matplotlib#28288 - Introduces three-dimensional rotation by mouse using a variation on Ken Shoemake's ARCBALL - Provides a minimal Quaternion class, to avoid an additional dependency on a large package like 'numpy-quaternion'
- Addresses Issue matplotlib#28288 - Introduces three-dimensional rotation by mouse using a variation on Ken Shoemake's ARCBALL - Provides a minimal Quaternion class, to avoid an additional dependency on a large package like 'numpy-quaternion'
This what the mouse rotation looks like on the elev_azim.mov(you can see the figure sometimes rotates, when you'd think it should tilt; or it moves in the opposite direction as the mouse). arcball.mov(Now the movement is much more consistent: the figure tilts up/down, left/right if you move the mouse up/down, left/right near the center; near the edge, the mouse rotates the figure). |
- Addresses Issue matplotlib#28288 - Introduces three-dimensional rotation by mouse using a variation on Ken Shoemake's ARCBALL - Provides a minimal Quaternion class, to avoid an additional dependency on a large package like 'numpy-quaternion'
- Addresses Issue matplotlib#28288 - Introduces three-dimensional rotation by mouse using a variation on Ken Shoemake's ARCBALL - Provides a minimal Quaternion class, to avoid an additional dependency on a large package like 'numpy-quaternion'
* Natural 3D rotation with mouse - Addresses Issue #28288 - Introduces three-dimensional rotation by mouse using a variation on Ken Shoemake's ARCBALL - Provides a minimal Quaternion class, to avoid an additional dependency on a large package like 'numpy-quaternion' * Suggestions from reviewers - makes axes3d.Quaternion a private _Quaternion class - shortens as_cardan_angles() - adds two extra tests to test_axes3d::test_quaternion(): from_cardan_angles() should return a unit quaternion, and as_cardan_angles() should be insensitive to quaternion magnitude - updates "mplot3d View Angles" documentation (the mouse can control both azimuth, elevation, and roll; and matlab does have a roll angle nowadays) - put in a reference to quaternion multiplication using scalar and vector parts (wikipedia) - rename class method that constructs a quaternion from two vectors to `rotate_from_to()` - clarify docstring: "The quaternion for the shortest rotation from vector r1 to vector r2" - issue warning when vectors are anti-parallel: "shortest rotation is ambiguous" - construct a perpendicular vector for generic r2 == -r1 - add test case for anti-parallel vectors - add test for the warning - add reference to Ken Shoemake's arcball, in axes3d.py - point out that angles are in radians, not degrees, in quaternion class docstrings - in test_axes3d, add an import for axes3d._Quaternion, to avoid repetition - add Quaternion conjugate(), and tests for it - add Quaternion norm, and tests - add Quaternion normalize(), and tests - add Quaternion reciprocal(), and tests - add Quaternion division, and tests - add Quaternion rotate(vector), and a test * Update axes3d.py's arcball - change argument from 2 element numpy array to x, y - add type hints * Update doc/api/toolkits/mplot3d/view_angles.rst --------- Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
* Natural 3D rotation with mouse - Addresses Issue matplotlib#28288 - Introduces three-dimensional rotation by mouse using a variation on Ken Shoemake's ARCBALL - Provides a minimal Quaternion class, to avoid an additional dependency on a large package like 'numpy-quaternion' * Suggestions from reviewers - makes axes3d.Quaternion a private _Quaternion class - shortens as_cardan_angles() - adds two extra tests to test_axes3d::test_quaternion(): from_cardan_angles() should return a unit quaternion, and as_cardan_angles() should be insensitive to quaternion magnitude - updates "mplot3d View Angles" documentation (the mouse can control both azimuth, elevation, and roll; and matlab does have a roll angle nowadays) - put in a reference to quaternion multiplication using scalar and vector parts (wikipedia) - rename class method that constructs a quaternion from two vectors to `rotate_from_to()` - clarify docstring: "The quaternion for the shortest rotation from vector r1 to vector r2" - issue warning when vectors are anti-parallel: "shortest rotation is ambiguous" - construct a perpendicular vector for generic r2 == -r1 - add test case for anti-parallel vectors - add test for the warning - add reference to Ken Shoemake's arcball, in axes3d.py - point out that angles are in radians, not degrees, in quaternion class docstrings - in test_axes3d, add an import for axes3d._Quaternion, to avoid repetition - add Quaternion conjugate(), and tests for it - add Quaternion norm, and tests - add Quaternion normalize(), and tests - add Quaternion reciprocal(), and tests - add Quaternion division, and tests - add Quaternion rotate(vector), and a test * Update axes3d.py's arcball - change argument from 2 element numpy array to x, y - add type hints * Update doc/api/toolkits/mplot3d/view_angles.rst --------- Co-authored-by: Tim Hoffmann <2836374+timhoffm@users.noreply.github.com>
Problem
In mplot3d, the plot currently reacts differently to dragging the mouse, depending on the orientation of the axes. In the default orientation, moving the mouse left/right or up/down tilts the plot left/right or up/down correspondingly, which is quite natural and intuitive. However, when the plot is rotated so that we are looking down the z-axis, then moving the mouse up/down does not tilt the plot up/down as expected, but rotates it around the z-axis. The situation reminds of gimball lock. It is clumsy and annoying.
Additionally, the 'roll' angle currently cannot be controlled with the mouse (issue #14451 and PR #21426 mention this) - at present, the two degrees of freedom of the mouse (left-right and up-down) correspond directly to two of the rotational degrees of freedom of the plot (azimuth and elevation), whereas there are in fact three (i.e., azimuth, elevation, and roll; or heading, tilt, and bank, if you will). Rotations around three cartesian axes do look essentially different (one can turn up/down, turn left/right, or twist left/right-handed). Controlling only two limits the accessible orientations.
Proposed solution
For a natural interaction with the mouse, it is desirable that the figure reacts in the same way to mouse movements, regardless of orientation: there should be no difference between "poles" and "equator" of the figure, and no 'gimbal lock'.
Of course this problem is not new - satisfying solutions have been devised in the nineties of the last century, e.g., Ken Shoemake's 'arcball' [1]. All that is needed to implement this in
mplot3d
is a small change toaxes3d._onmove()
, together with a minimal quaternion class - this avoids an additional dependency on a large package likenumpy-quaternion
.The quaternion class can be made internal, to hide it; or it can be exposed since it can be more generally useful.
The text was updated successfully, but these errors were encountered: