确定四元旋转是顺时针还是逆时针

0 quaternions unity-game-engine

我使用以下代码来将我的玩家模型旋转到鼠标的位置。

void Update() {
    // Generate a plane that intersects the transform's position with an upwards normal.
    Plane playerPlane = new Plane(Vector3.up, transform.position);

    // Generate a ray from the cursor position
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

    // Determine the point where the cursor ray intersects the plane.
    // This will be the point that the object must look towards to be looking at the mouse.
    // Raycasting to a Plane object only gives us a distance, so we'll have to take the distance,
    // then find the point along that ray that meets that distance. This will be the point
    // to look at.
    float hitdist = 0f;
    // If the ray is parallel to the plane, Raycast will return false.
    if (playerPlane.Raycast(ray, out hitdist)) {
        // Get the point along the ray that hits the calculated distance.
        var targetPoint = ray.GetPoint(hitdist);

        // Determine the target rotation. This is the rotation if the transform looks at the target point.
        Quaternion targetRotation = Quaternion.LookRotation(targetPoint - transform.position);


        // Smoothly rotate towards the target point.
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime); // WITH SPEED
        //transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 1); // WITHOUT SPEED!!!
    }
Run Code Online (Sandbox Code Playgroud)

我希望能够确定出于动画目的旋转是顺时针还是逆时针。处理这个问题的最佳方法是什么?我对四元数相当不熟悉,所以我不太确定如何解决这个问题。

小智 5

四元数之间的角度是无符号的。您将始终获得最短距离,并且除非您主动指定轴(一个视点),否则无法定义“逆时针”或“顺时针”。

然而,你可以做的是采用你感兴趣的轴(我假设它是你的基准平面的法线......也许是你的世界的垂直方向?)并采用四元数的平面 2D 分量,将它们映射在那里并计算它们之间的简单二维角度。

Quaternion A; //first Quaternion - this is your desired rotation
Quaternion B; //second Quaternion - this is your current rotation

// define an axis, usually just up
Vector3 axis = new Vector3(0.0f, 1.0f, 0.0f);`

// mock rotate the axis with each quaternion
Vector3 vecA = A * axis;
Vector3 vecB = B * axis;

// now we need to compute the actual 2D rotation projections on the base plane
float angleA = Mathf.Atan2(vecA.x, vecA.z) * Mathf.Rad2Deg;
float angleB = Mathf.Atan2(vecB.x, vecB.z) * Mathf.Rad2Deg;
 
// get the signed difference in these angles
var angleDiff = Mathf.DeltaAngle( angleA, angleB );
Run Code Online (Sandbox Code Playgroud)

应该是这样。我从来不需要自己做,上面的代码也没有经过测试。类似于:http://answers.unity3d.com/questions/26783/how-to-get-the-signed-angle- Between-two-quaternion.html

即使 A 或 B 不是四元数,但其中之一是欧拉角旋转,这也应该起作用。