睡眠问题,视角扭曲

Slerp issues, perspective warping

本文关键字:问题      更新时间:2023-10-16

我基本上是工作在一个功能的睡眠,虽然它有点工作,它有一个奇怪的角度扭曲的问题,我被困试图解决现在。

Quaternion sLerp(Quaternion start, Quaternion end, float s)
{
    float dot = qDot(start, end);
    float theta = std::acos(dot);
    float sTheta = std::sin(theta);
    float w1 = sin((1.0f-s)*theta) / sTheta;
    float w2 = sin(s*theta) / sTheta;
    Quaternion Temp(0,0,0,0);
    Temp = start*w1 + end*w2;
    return Temp;
}

本质上它所做的(或应该做的)只是在两个值之间休眠以提供旋转,并且由此产生的结果被转换为旋转矩阵。但出问题的是一个可怕的,可怕的延伸的观点……由于某种原因,在旋转过程中,它拉伸了所有的东西,从所有的东西都太长/太细开始,在开始变细之前达到一个更短的中点。

您的slerp代码看起来很好,尽管通常会确保dot>=0,因为否则,您将绕圆旋转很长一段路。一般来说,确保dot!=1也很重要因为你会遇到除以0 的问题。

一个合适的四元数不应该扩展视图。要么你在传递startend的非单位长度四元数,要么你的四元数到矩阵的代码是可疑的(或者你得到奇怪的行为,因为两个四元数之间的角度非常小,你除以几乎为零)。


我的代码转换从四元数到一个矩阵在OpenGL中使用:

// First row
glMat[ 0] = 1.0f - 2.0f * ( q[1] * q[1] + q[2] * q[2] );
glMat[ 1] = 2.0f * (q[0] * q[1] + q[2] * q[3]);
glMat[ 2] = 2.0f * (q[0] * q[2] - q[1] * q[3]);
glMat[ 3] = 0.0f;
// Second row
glMat[ 4] = 2.0f * ( q[0] * q[1] - q[2] * q[3] );
glMat[ 5] = 1.0f - 2.0f * ( q[0] * q[0] + q[2] * q[2] );
glMat[ 6] = 2.0f * (q[2] * q[1] + q[0] * q[3] );
glMat[ 7] = 0.0f;
// Third row
glMat[ 8] = 2.0f * ( q[0] * q[2] + q[1] * q[3] );
glMat[ 9] = 2.0f * ( q[1] * q[2] - q[0] * q[3] );
glMat[10] = 1.0f - 2.0f * ( q[0] * q[0] + q[1] * q[1] );
glMat[11] = 0.0f;
// Fourth row
glMat[12] = 0.0;
glMat[13] = 0.0;
glMat[14] = 0.0;
glMat[15] = 1.0f;

您需要规范化四元数吗?

我认为如下:

float sTheta = std::sin(theta);
应:

float sTheta = sqrt(1.0f - sqr(theta));