Skip to content
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

slerp issues #29

Closed
mbj2011 opened this issue Mar 1, 2014 · 2 comments
Closed

slerp issues #29

mbj2011 opened this issue Mar 1, 2014 · 2 comments

Comments

@mbj2011
Copy link

mbj2011 commented Mar 1, 2014

I have absolutely no idea why this is happening, but apprantly there are certain magical quaternions that cannot be interpolated between.

    quat a = quat.yrotation(-1.238796f);
    quat b = quat.yrotation(-1.238796f);    
    quat bad = slerp(a, b, 0.5);    
    quat a2 = quat.yrotation(-1.23879f);
    quat b2 = quat.yrotation(-1.23879f);    
    quat good = slerp(a2, b2, 0.5); 
    writeln(a, " ", b, " ", bad, " ", good, ".");

Having done a bit of research on slerp it turns out that its "bad practice" anyway:
http://physicsforgames.blogspot.com/2010/02/quaternions.html
http://number-none.com/product/Understanding%20Slerp,%20Then%20Not%20Using%20It/

If it is not too much trouble, I'd like to see nlerp along with a fixed version of slerp in the interpolate module.
My version looks like this:

quat nlerp(quat a, quat b, float t) {
    float dot = a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z;      
    quat result;
    if(dot < 0) {   // Determine the "shortest route"...
        result = a - (b + a) * t;   // use -b instead of b
    } else {
        result = a + (b - a) * t;
    }
    result.normalize();
    return result;
}

, but I guarrantee nothing as the bug above is completely blowing my mind.

@Dav1dde
Copy link
Owner

Dav1dde commented Mar 1, 2014

This looks another Dlang bug to me...

        writefln("---------> %s | %s", a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z, acos(a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z));
        real theta = acos(a.w * b.w + a.x * b.x + a.y * b.y + a.z * b.z);
        writefln("---------> %s", theta);

produces:

---------> 1 | -nan
---------> -nan

Which should obviously be 0 not -nan. No matter what I change, the outcome doesn't change!

Your version looks fine, I added it to the interpolation-module, thanks!

Dav1dde added a commit that referenced this issue Mar 1, 2014
Dav1dde added a commit that referenced this issue Mar 1, 2014
@Dav1dde
Copy link
Owner

Dav1dde commented Mar 1, 2014

Ok I think I figured it out, the result of the dot product is probably ever so slightly smaller than -1 or bigger than 1, making acos return nan (floating point errors). Clamping the values to -1 and 1 seems to fix it. Please report back, if the issue still exists.

@Dav1dde Dav1dde closed this as completed Mar 1, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants