Skip to content

Instantly share code, notes, and snippets.

@GeorgiyRyaposov
Last active January 18, 2023 06:44
Show Gist options
  • Save GeorgiyRyaposov/e42397cd76a524573ba12ab762890d1f to your computer and use it in GitHub Desktop.
Save GeorgiyRyaposov/e42397cd76a524573ba12ab762890d1f to your computer and use it in GitHub Desktop.
//To get the difference C between quaternions A and B you do this:
C = A * Quaternion.Inverse(B);
//To add the difference to D you do this:
D = C * D;
/////////////////
//World vs local
//An easy way to keep track of the order of operations for quaternions is to think of it in terms of world and local rotations.
//When multiplying a quaternion the world rotation is on the left, and the local rotation is on the right, like this:
finalRotation = worldRotation * localRotation;
//For example if you took the global rotation of an object and then multiplied it by the localRotation of a child of that object you
//would get the global rotation of that child object:
childRotation = parentTransform.rotation * childTransform.localRotation;
//You can also use this to add an offset to a rotation, for instance if you wanted to rotate an object around it’s local z axis
//you would just do something like this:
tranform.rotation = targetRotation * Quaternion.Euler(0, 0, 90);
//Of course this also applies to global rotations, if you want to rotate an object in global space you would just do this:
tranform.rotation = Quaternion.Euler(0, 0, 90) * transform.rotation;
///////////////
//Adding and Subtracting
//To subtract one rotation from another you are going to need to get it’s inverse like so:
inverseRotation = Quaternion.Inverse(rotation);
//One of the main uses for this is getting the rotation between two rotations.
//For example if you wanted to know the Quaternion that would get you from rotationA to rotationB you would do something like this:
FromAtoB = Quaternion.Inverse(rotationA) * rotationB
//You would then get the rotation between them, this is most useful when you want to copy the offset of one thing to another thing
//For example maybe you want to make two levers mirror each other and refuse to use local rotations for whatever reason.
offset = Quaternion.Inverse(lever1BaseRotation) * lever1Rotation
lever2Rotation = lever2BaseRotation * offset
//Multiple rotations at once
//So maybe you’re completely insane and you want to do multiple rotations at once in the same equation,
//maybe you’re storing local rotations with an offset or something in a scriptable object for and auto hand poser or something.
//The trick is to always keep the order of operations. So if you did something like this to store rotation3:
rotation3Offset = Quaternion.Inverse(rotation1) * Quaternion.Inverse(rotation2) * rotation3
//to get back to rotation3 you would need to do this:
rotation3 = rotation1 * rotation2 * rotation3Offset
//This can even work with predefined local offsets if you’re carful:
storedRotation = Quaternion.Inverse(parentRotation) * rotationToStore * Quaternion.Inverse(offset)
rotationToStore = parentRotation * storedRotation * offset
//Sorry if none of that made sense, but I hope it helps someone. If I’m just crazy please send help.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment