1

在过去的几天里,我一直在慢慢地弄清楚四元数,并遇到了一个意想不到的问题。在最终让代码工作后,我发现我传递给我的旋转函数的数字没有产生与度数或弧度相关的旋转。

这是我的旋转功能

void solveRotation(Quaternion* q, float pitch, bool localx, float yaw, bool localy, float roll, bool localz)
{
    Quaternion temp;
    if(yaw !=0.f)
    { 
        if(localy==true)
        {
            //quaternionMultBA(q, yaw, 0.f, 1.f, 0.f);
            temp.w = q->w*yaw - q->y;
            temp.x = q->x*yaw + q->z;
            temp.y = q->y*yaw + q->w;
            temp.z = q->z*yaw - q->x;
        }
        else
        {
            //quaternionMultAB(q, yaw, 0.f, 1.f, 0.f);
            temp.w = q->w*yaw - q->y;
            temp.x = q->x*yaw - q->z;
            temp.y = q->w + q->y*yaw;
            temp.z = q->z*yaw + q->x;
        }
        q->w=temp.w;
        q->x=temp.x;
        q->y=temp.y;
        q->z=temp.z;
    }
    if(pitch != 0.f)
    {
        if(localx==true)
        {

            //quaternionMultBA(q, pitch, 1.f, 0.f, 0.f);
            temp.w = q->w*pitch - q->x;
            temp.x = q->x*pitch + q->w;
            temp.y = q->y*pitch - q->z;
            temp.z = q->z*pitch + q->y;
        }
        else
        {
            //quaternionMultAB(q, pitch, 1.f, 0.f, 0.f);
            temp.w = q->w*pitch - q->x;
            temp.x = q->w + q->x*pitch;
            temp.y = q->y*pitch + q->z;
            temp.z = q->z*pitch - q->y;
        }
        q->w=temp.w;
        q->x=temp.x;
        q->y=temp.y;
        q->z=temp.z;
    }
    if(roll != 0.f)
    {
        if(localz==true)
        {

            //quaternionMultBA(q, roll, 0.f, 0.f, 1.f);
            temp.w = q->w*roll - q->z;
            temp.x = q->x*roll - q->y;
            temp.y = q->y*roll + q->x;
            temp.z = q->z*roll + q->w;
        }
        else
        {
            //quaternionMultAB(q, roll, 0.f, 0.f, 1.f);
            temp.w = q->w*roll - q->z;
            temp.x = q->x*roll + q->y;
            temp.y = q->y*roll - q->x;
            temp.z = q->z*roll + q->w;
        }
        q->w=temp.w;
        q->x=temp.x;
        q->y=temp.y;
        q->z=temp.z;
    }

    normalize(q);
}

上面的代码传递一个值,具体取决于在循环迭代期间按下了哪些键。起初我将值设置为 0.1 并预计旋转缓慢。相反,我看到每次迭代都有一个大转弯,在 60fps 时看起来非常奇怪。当我将传递的值更改为 1.0 时,我正在处理的立方体似乎做了完美的 90 度转弯(颜色移动但几何形状没有)

当我将传递量增加到 5 以上时,我开始看到我所期望的平滑旋转,并注意到随着我增加值它变慢了。我想了这么多,但它真的对我没有帮助,因为我不能用它来旋转特定的数量。我读过的任何四元数教程都没有提到这类问题,因为它们都提到了弧度。我不确定我是否犯了错误,或者我是否错过了额外的步骤,或者我是否搞砸了整个该死的事情。

提前感谢您的帮助,也可能响应缓慢

4

1 回答 1

0

因此,我进行了更多搜索并修改了我的函数以包含我缺少的 sin 和 cos 函数。由于我在 GPwiki 上看到的代码示例,我认为我可以在没有触发的情况下进行旋转。无论如何,该功能现在已修复,如果有人想使用它 - 即使那里可能有更好的功能 - 这里是:

void solveRotation(Quaternion* q, float pitch, bool localx, float yaw, bool localy, float roll, bool localz)
{
    Quaternion temp;
    float s;
    float c;
    if(yaw !=0.f)
    { 
        yaw*=0.5f;
        s = sin(yaw);
        c = cos(yaw);
        if(localy==true)
        {
            temp.w = q->w*c - q->y*s;
            temp.x = q->x*c + q->z*s;
            temp.y = q->y*c + q->w*s;
            temp.z = q->z*c - q->x*s;
        }
        else
        {
            temp.w = q->w*c - q->y*s;
            temp.x = q->x*c - q->z*s;
            temp.y = q->y*c + q->w*s;
            temp.z = q->z*c + q->x*s;
        }
        q->w=temp.w;
        q->x=temp.x;
        q->y=temp.y;
        q->z=temp.z;
    }
    if(pitch != 0.f)
    {
        pitch*=0.5f;
        s = sin(pitch);
        c = cos(pitch);
        if(localx==true)
        {
            temp.w = q->w*c - q->x*s;
            temp.x = q->x*c + q->w*s;
            temp.y = q->y*c - q->z*s;
            temp.z = q->z*c + q->y*s;
        }
        else
        {
            temp.w = q->w*c - q->x*s;
            temp.x = q->x*c + q->w*s;
            temp.y = q->y*c + q->z*s;
            temp.z = q->z*c - q->y*s;
        }
        q->w=temp.w;
        q->x=temp.x;
        q->y=temp.y;
        q->z=temp.z;
    }
    if(roll != 0.f)
    {
        roll*=0.5f;
        s = sin(roll);
        c = cos(roll);
        if(localz==true)
        {
            temp.w = q->w*c - q->z*s;
            temp.x = q->x*c - q->y*s;
            temp.y = q->y*c + q->x*s;
            temp.z = q->z*c + q->w*s;
        }
        else
        {
            temp.w = q->w*c - q->z*s;
            temp.x = q->x*c + q->y*s;
            temp.y = q->y*c - q->x*s;
            temp.z = q->z*c + q->w*s;
        }
        q->w=temp.w;
        q->x=temp.x;
        q->y=temp.y;
        q->z=temp.z;
    }

    normalize(q);
}

顺便说一句,感谢吉姆刘易斯

于 2013-04-21T02:01:03.293 回答