0

Hi I have an arbitrary rotation quaternion, which is constructed from a series of operations done by the user (they select the object, rotate it around the plane constructed from the camera view direction, then maybe rotate it from another angle etc).

I then need to decompose this rotation object down into a rotation around the X, Y and Z axes. Note that it doesn't have to be that order. The user interface allows a user to attach rotation blocks together in any order, so they could chain them up like this:

enter image description here

In code, I then loop through each block and do:

finalRotation *= Quaternion.CreateFromAxisAngle(blockAxis, toRadians(blockAngle))

So how could I convert an arbitrary quaternion back to this block representation? I've tried projecting the quaternion onto the X, Y and Z planes as per this answer:

Component of a quaternion rotation around an axis

and then connecting up the blocks in an [X][Y][Z] order, but so far the results seem to come out incorrectly. Would someone be able to explain how I should approach this problem? Note I am restricted to rotating around one axis at a time, per block.

Edit: To clarify I am using the MonoGame framework, not Unity.

FLX
  • 2,626
  • 4
  • 26
  • 57
LynchDev
  • 793
  • 1
  • 12
  • 27
  • Did you try [`Quaternion.eulerAngles`](https://docs.unity3d.com/ScriptReference/Quaternion-eulerAngles.html) and [`Quaternion.ToAngleAxis`](https://docs.unity3d.com/ScriptReference/Quaternion.ToAngleAxis.html) ? One of them should work for you. – Programmer Aug 07 '17 at 21:32
  • Sorry not using the Unity Engine, made an edit – LynchDev Aug 07 '17 at 21:33
  • 1
    The Quaternion implementation in the Monogame framework appears to be a copy of that from the `System.Numerics` namespace, both for which I cannot seem to find any method to convert to Euler angles either. Have a look at [my implementation](https://github.com/tswanepoel/pilotgadgetry/blob/master/Biscuits.Core/Quaternion.cs) if you want to use the same logic. – Biscuits Aug 07 '17 at 22:15
  • @Biscuits In this case I re-apply each angle of rotation as a quaternion, not all at once in a YawPitchRoll method. Anyway I looked at your code, and just want to point out that your `ToEulerAngles()` function doesn't account for gimbal lock so won't work for all angles, and your `GetAxis()` function doesn't account for singularity cases either so you'll have problems when angle = 0/180. – LynchDev Aug 08 '17 at 13:39
  • I know you don't have unity, but can't you load up the Unity framework so you have their library on your dev machine, and then reflect the `Quaternion.eulerAngles` method to see the code behind it and learn how its done? – Steve H Aug 09 '17 at 01:11
  • That does not matter, because the return values from these methods represent only a final end-state that is never used for the purposes of calculating rotations. Every rotation here is calculated exclusively through multiplication of singularity-free quaternions which, from what I gather, you're doing incorrectly. The correct method is `p' = qpq*`. See [Quaternions and spatial rotation](https://en.m.wikipedia.org/wiki/Quaternions_and_spatial_rotation). – Biscuits Aug 10 '17 at 00:46
  • I don't know enough about quaternion magic to be sure, but it seems that user wants to take a quaternion that was a result of multiple rotations, and extract those rotations from it. I have a feeling this might not be possible. How about storing the rotations alongside and using them like that whenever needed? – htmlcoderexe Aug 14 '17 at 21:48

0 Answers0