Quaternion basic questions

Hi monkeys,

I’m mathematically challenged…

A) If I have a known rotation, how can I obtain the rotation needed to get back to no rotation?
if q1 is a quaternion, what is q2 so that q2.mult(q1) gives me an identity quaternion?
I found a way to get my results (been using that for a looong while), but my way seemed inefficient and may contain errors on some axis. There’s a negate and an inverse method on quaternions, but not sure what they do.

B) Could someone with a functioning brain check my math methods to see if they are incorrect please? They seem to work for what I use them for, but at the same time, I’m wondering if some strange data I’m getting couldn’t be linked to an error there (could also be inefficient).

public class MathUtil {

    public static Quaternion inverseAnglesLocal(Quaternion quaternion) {
        float[] angles = new float[3];
        quaternion.toAngles(angles);
        angles[0] = -1 * angles[0];
        angles[1] = -1 * angles[1];
        angles[2] = -1 * angles[2];

        quaternion.fromAngles(angles);
        return quaternion;
    }

    public static Quaternion inverseAngles(Quaternion quaternion) {
        Quaternion q = new Quaternion();
        float[] angles = new float[3];
        quaternion.toAngles(angles);
        angles[0] = -1 * angles[0];
        angles[1] = -1 * angles[1];
        angles[2] = -1 * angles[2];

        q.fromAngles(angles);
        return q;
    }
    
    //input needs to be normalized
    public static Quaternion rotationBetween(Vector3f normalizedStart, Vector3f normalizedEnd) {
        float angle = normalizedStart.angleBetween(normalizedEnd);
        Vector3f normal = normalizedStart.cross(normalizedEnd);
        return new Quaternion().fromAngleAxis(angle, normal);
    }
    
    public static Quaternion rotationBetween(Quaternion normalizedFrom, Quaternion normalizedTo){
        Quaternion from_ = normalizedFrom.clone();
        inverseAnglesLocal(from_);
        return from_.multLocal(normalizedTo);
    }
    
}

q2 = q1.inverse();

…which gives you the… inverse… of the rotation.

I think the problem you will have with your inverseAngles() is that the order of the angles is not inverted… so you may have some edge cases that produce bad results. (Besides which, the regular inverse of a quaternion is truly trivial math but especially in comparison.)

As said, inverse does the inverse… which is exactly what you expect based on your similar naming.

Negate, negates the quaternion… same as Vector2f.negate(), Vector3f.negate(), and so on… multiplies all components by -1… which in the case of a rotation produces the same exact rotation. When quaternions represent rotation, the negate() is the only other quaternion in existence that represents the same rotation. (As opposed to Euler angles where there is an infinite number of redundant angle sets.)

I don’t know what you are using theses for so I can’t comment if it works in all cases or if there is a better way. I have never needed anything like it, though.

2 Likes

Thanks A LOT pspeed! This helps a ton!

A while (years?) ago, I tested that inverse method, but was even more clueless than now, so probably botched it’s testing and tried to find a “logical” way of getting beyond that problem and that’s where rotationBetween appeared.

Well, me naming a method doesn’t make it behave accordingly to it’s name haha.

Also, tons of thanks for the explanation about negate.

As an interesting fact, while it is true in our 3d game world, it gets more complex in particle physics :wink: Particle needs to turn 720 degrees to get into same state and positive/negative quaternion can be used to show difference between those two 360 rotation states.

http://www.euclideanspace.com/maths/discrete/groups/lie/spinor/index.htm

2 Likes

http://blog.devonschreiner.com/wp-content/uploads/2011/09/lib-head-explode.jpg

1 Like


It seems to be the only way that those colored tentacles will not cut each other and get back to its initial state, the 720 degrees is required.
I still cant see a practical use in a game for this, but I feel it is probably something very interesting!
Any idea what could it be?