c++ - "Looking At"具有四元数的对象

标签 c++ opengl rotation sfml quaternions

所以我目前正在尝试创建一个函数,它将采用两个 3D 点 A 和 B,并为我提供代表 A 点“观察”B 点所需的旋转的四元数(这样点 A 的局部 Z轴穿过点 B,如果你愿意的话)。

我最初找到了this post ,其中的最佳答案似乎为我提供了一个很好的起点。我继续执行以下代码;正如原始答案所暗示的那样,我没有假设默认的 (0, 0, -1) 方向,而是尝试提取表示相机实际方向的单位 vector 。

void Camera::LookAt(sf::Vector3<float> Target)
{
    ///Derived from pseudocode found here:
    ///https://stackoverflow.com/questions/13014973/quaternion-rotate-to

    //Get the normalized vector from the camera position to Target
    sf::Vector3<float> VectorTo(Target.x - m_Position.x,
                                Target.y - m_Position.y,
                                Target.z - m_Position.z);
    //Get the length of VectorTo
    float VectorLength = sqrt(VectorTo.x*VectorTo.x +
                              VectorTo.y*VectorTo.y +
                              VectorTo.z*VectorTo.z);
    //Normalize VectorTo
    VectorTo.x /= VectorLength;
    VectorTo.y /= VectorLength;
    VectorTo.z /= VectorLength;

    //Straight-ahead vector
    sf::Vector3<float> LocalVector = m_Orientation.MultVect(sf::Vector3<float>(0, 0, -1));

    //Get the cross product as the axis of rotation
    sf::Vector3<float> Axis(VectorTo.y*LocalVector.z - VectorTo.z*LocalVector.y,
                            VectorTo.z*LocalVector.x - VectorTo.x*LocalVector.z,
                            VectorTo.x*LocalVector.y - VectorTo.y*LocalVector.x);

    //Get the dot product to find the angle
    float Angle = acos(VectorTo.x*LocalVector.x +
                       VectorTo.y*LocalVector.y +
                       VectorTo.z*LocalVector.z);

    //Determine whether or not the angle is positive
    //Get the cross product of the axis and the local vector
    sf::Vector3<float> ThirdVect(Axis.y*LocalVector.z - Axis.z*LocalVector.y,
                                 Axis.z*LocalVector.x - Axis.x*LocalVector.z,
                                 Axis.x*LocalVector.y - Axis.y*LocalVector.x);
    //If the dot product of that and the local vector is negative, so is the angle
    if (ThirdVect.x*VectorTo.x + ThirdVect.y*VectorTo.y + ThirdVect.z*VectorTo.z < 0)
    {
        Angle = -Angle;
    }

    //Finally, create a quaternion
    Quaternion AxisAngle;
    AxisAngle.FromAxisAngle(Angle, Axis.x, Axis.y, Axis.z);

    //And multiply it into the current orientation
    m_Orientation = AxisAngle * m_Orientation;
}

几乎有效。发生的情况是相机似乎向目标点旋转了一半的距离。如果我再次尝试旋转,它会执行剩余旋转的一半,无限循环,这样如果我按住“Look-At-Button”,相机的方向会越来越接近直接注视目标,但也会不断放慢它的旋转速度,这样它就永远不会完全到达那里。

请注意,我不想求助于 gluLookAt(),因为我最终还需要此代码将相机以外的对象指向彼此,并且我的对象已经使用四元数他们的方向。例如,我可能想要创建一个眼球来跟踪在它前面移动的物体的位置,或者创建一个可以更新其方向以寻找目标的射弹。

最佳答案

在将其传递给 FromAxisAngle 之前规范化 Axis vector 。

关于c++ - "Looking At"具有四元数的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14337441/

相关文章:

rotation - 在 x3d 中旋转对象

C - 旋转 64 位无符号整数

c++ - 从第二个(或第 n 个)项开始循环 C++ 迭代器

c++ - 使用 reverse_iterator 删除最后一个元素

c++ - 设置 3d 空间中对象的方向

c++ - 从转换中获取结果顶点?

c++ - 从二叉搜索树中删除一个值

c++ - 向下转换基本类型

c++ - OpenGL:带着色器的 glColor3f() 和 glVertex3f()

java - 如何制作检测碰撞的旋转碰撞盒?