四元数与新的四元数相乘时会局部旋转

问题描述

所以我正在研究游戏引擎,但是我对线性代数的了解有限-仅是最近几天我自学的知识-尽管我成功地实现了四元数,但我不能完全理解它们。

根据收集的数据,如果我有单位四元数(格式为[w,x,y,z])[0.92387956、0.38268343、0.0、0.0](围绕+ x轴旋转45度),然后乘以通过另一个单位四元数[0.7071068,0.0,0.70710677,0.0](围绕+ y轴90度),它应该产生一个新的四元数,该四元数是原始的围绕x轴45度,然后围绕全局y轴旋转90度,而是绕局部y轴(“偏航”轴)旋转它。

如果我的理解不正确,是否有人可以帮助我找到预期的行为?以下是我使用的一些代码。附带说明一下,我写了所有这些内容,因此很有可能完全错误。

public class Quaternion
{
    public Quaternion(float x,float y,float z,float w)
    {

        float mod = (float)Math.sin(w / Mathf.RAD2DEG/2);
        this.x = x * mod;
        this.y = y * mod;
        this.z = z * mod;
        //System.out.println(Math.cos(w / Mathf.RAD2DEG /2));
        this.w = (float)Math.cos(w / Mathf.RAD2DEG /2);

    }

    public Quaternion multiplyBy(Quaternion q)
    {
        
        setRaw(
                w * q.x + x * q.w + y * q.z - z * q.y,w * q.y + y*q.w + z * q.x - x * q.z,w * q.z + z * q.w + x * q.y - y * q.x,w * q.w - x * q.x - y * q.y - z *q.z);
        normalize();
        return this;
    }

    public Quaternion setRaw(float x,float w)
    {
        this.x = x;
        this.y = y;
        this.z = z;
        this.w = w;
        return this;
    }

    public float magnitude()
    {
        return Mathf.sqrt(w*w + x*x + y*y + z*z);
    }
    
    public Quaternion normalize()
    {
        float norm = magnitude();
        w/= norm;
        x /= norm;
        y /= norm;
        z /= norm;
        return this;
    }

    //does not return a real Quaternion but merely uses it as a means to store 4 floating points
    public Quaternion angleAxis()
    {
        if(w > 1)
            normalize();
        float newAngle =2* (float)Math.acos(w);
        float s = Mathf.sqrt(1-w *w);
        //.out.println(newAngle);
        ///System.out.println(newAngle  * Mathf.RAD2DEG);
        //System.out.println();

        return new Quaternion().setRaw(x,y,z,newAngle * Mathf.RAD2DEG);
    }

}

public class ExampleClass
{
    public static void main(String[] args)
    {
        //formatted x,w
        Quaternion xrot = new Quaternion(1,45);
        //evaluates to [0.92387956,0.38268343,0.0,0.0] formatted w,x,z

        Quaternion yrot = new Quaternion(0,1,90);
        //evaluates to [0.7071068,0.70710677,z

        xrot.multiplyBy(yrot);
        //evals to [0.9999837,0.0015426596,0.0037243098,0.0]
        //an online quat calculator states the result should be [0.65328,0.2706,0.65328,0.2706]
    }

}

最后一点,我使用OpenGL在3d中渲染视图,并且OpenGL接受由angleAxis()方法提供的旋转的角轴表示。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)