3D 3D Vector Rotation Direction

Binsk

Member
Howdy!

So I have implemented a brute-force solution for this and I am hoping someone may know of a more efficient method of doing this.

I am implementing a script that calculates a quaternion I can use to rotate a vector from its orientation to some other specified orientation. The issue of optimization comes down to determining the rotation direction required to accomplish this since rotating around a cross-product-based axis changes direction depending on the order of the cross-product (due to the direction of the axis).

What my code is doing (assume all vectors are normalized):
1. Calculate cross between v1 and v2 to find v3 to rotate around
2. Calculate arccos(dot(v1, v2)) to find amount to rotate
3. Calculate cross between v3 and v1 to get v4
4. Calculate dot(v2, v4) to determine if I should rotate clock or counterclock
5. Generate quaternion from v3 and rotation (or negated rotation) value

This works flawlessly, but steps 3 and 4 were a brute-force method of determining which direction to rotate. I hate the idea of performing a whole extra cross-product just to determine this, especially since this script will be used extremely frequently. I have looked online and I can't seem to find what I need regarding this.

Is there some math concept or intelligent way of determining the direction to rotate around the axis in 3D that I am missing? Any help would be appreciated.

EDIT: While I use a lot of custom scripts, here is my code so people can at least get a visual:
Code:
var _v1 = argument0, // From vector
    _v2 = argument1; // To vector
var _dot = vector_dot(_v1, _v2);
if (_dot < 1){ // If not equal, we need to rotate:
    var _axis;
    if (_dot <= -1) // If opposites we grab a random perp vector to rotate around:
        _axis = vector_get_perpendicular(_v1); // Get arbitrary perp vector
    else // Otherwise, calculate rotation vector:
        _axis = vector_cross(_v1, _v2);

    var _angle = arccos(_dot); // Actual rotation angle
        // Check the direction to rotate,
        // This is the part I feel is inefficient:
    var _back_cross = vector_cross(_axis, _v1);
    if (vector_dot(_back_cross, _v1) < 1) // If not equal, we assume it is opposite:
        _angle = -_angle;

        // Generate rotation quat:
    return quat_from_axis(_axis, _angle);
}

// If we didn't need to rotate, return identity quat:
return [0, 0, 0, 1];
 
Last edited:

FrostyCat

Redemption Seeker
Why not just skip steps 3 and 4 altogether, always rotate in the positive direction, and let the orientation of the cross product take its course? If the direction of the cross product inverts, it's because the correct positive direction to rotate in is the other way around. Clockwise relative to an axis is equivalent to counter-clockwise relative to an axis pointing the other way.
 

Binsk

Member
Thank you FrostyCat. You made me realize that the problem was elsewhere. Turns out that I was goofing up the order of my quaternion rotations which I was using to calculate the initial v1 vector. This was making the direction of that vector flip-flop which, just by chance, was fixed by what I was doing.

Ugh.
 
Top