如何找到从一个向量到另一个向量的正确旋转? [英] How to find correct rotation from one vector to another?

查看:158
本文介绍了如何找到从一个向量到另一个向量的正确旋转?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个对象,每个对象都有两个向量:

I have two objects, and each object has two vectors:

  • 法线向量
  • 向上向量

喜欢这张图片:

上向量垂直于法向量.现在我想找到从一个对象到另一个对象的唯一旋转,该怎么做?

Up vector is perpendicular to normal vector. Now I want to find unique rotation from one object to another, how to do that?

我有一种方法可以找到一个向量到另一个向量之间的旋转,并且它有效.问题是我需要注意两个向量:法线向量和向上向量.如果我使用这种方法将法线向量从对象一旋转到法线从对象二,向上向量可能指向错误的方向,它们需要平行.

I have one method to find rotation between one vector to another, and it works. The problem is that I need to take care the two vectors: normal vector and up vector. If I use this method to rotate normal vector from object one to normal from object two, the up vector could be pointing wrong way, and they needs to be parallel.

这是寻找最短旋转的代码:

Here is the code for finding the shortest rotation:

GE::Quat GE::Quat::fromTo(const Vector3 &v1, const Vector3 &v2)
{
    Vector3 a = Vector3::cross(v1, v2);
    Quat q;

    float dot = Vector3::dot(v1, v2);

    if ( dot >= 1 ) 
    {
        q = Quat(0,0,0,1);

    }
    else if ( dot < -0.999999 )
    {
        Vector3 axis = Vector3::cross(Vector3(1,0,0),v2);

        if (axis.length() == 0) // pick another if colinear
                axis = Vector3::cross(Vector3(0,1,0),v2);
        axis.normalize();
        q = Quat::axisToQuat(axis,180);
    }
    else
    {
        float s = sqrt( (1+dot)*2 );
        float invs = 1 / s;

        Vector3 c = Vector3::cross(v1, v2);

        q.x = c.x * invs;
        q.y = c.y * invs;
        q.z = c.z * invs;
        q.w = s * 0.5f;
    }
    q.normalize();
    return q;
}

为了找到正确的旋转,我应该更改/添加到此代码中的哪些内容?

What should I change/add to this code, to find the correct rotation?

推荐答案

在开始之前,我先假设UP向量和法向量都是标准化正交(点积为零).

Before we begin, I will assume that both UP vector and normal vector are normalized and orthogonal (dot product is zero) between them.

假设您想旋转黄色盘子以与玫瑰(红色?)盘子对齐.因此,我们的参考将是来自黄色板的向量,我们将坐标系称为 XYZ,其中 Z -> 正常黄色向量,Y -> 向上黄色向量和 X -> YxZ(叉积).

Let's say that you want to rotate your yellow plate to be aligned with the rose (red?) plate. So, our reference will be the vectors from yellow plate and we will call our coordinate system as XYZ, where Z -> normal yellow vector, Y -> Up yellow vector and X -> YxZ (cross product).

同理,对于玫瑰板,旋转后的坐标系将被称为 X'Y'Z' 其中 Z' -> 正常玫瑰矢量,Y' -> 向上玫瑰矢量和 X' -> Y'xZ'(交叉产品).

In the same way, for rose plate, the rotated coordinate system will be called X'Y'Z' where Z' -> normal rose vector, Y' -> up rose vector and X' -> Y'xZ' (cross product).

确定旋转矩阵,我们只需要确保我们正常的黄色向量会变成正常的玫瑰向量;我们的向上黄色向量将转换为向上玫瑰向量,依此类推,即:

Ok to find the rotation matrix, we only need to make sure that our normal yellow vector will become normal rose vector; that our up yellow vector will be transfomed in the up rose vector, and so on, i.e.:

RyellowTOrose = |X'x   Y'x   Z'x|
                |X'y   Y'y   Z'y|
                |X'z   Y'z   Z'z|

换句话说,在将任何图元转换为黄色系统坐标后,应用此转换,将旋转它以与玫瑰坐标系统对齐

in other words, after you have any primitives transformed to be in coordinates of yellow system, applying this transformation, will rotate it to be aligned with rose coordinates system

如果您的向上和法线向量不是正交的,您可以轻松地纠正其中一个.只需在 normal 和 up 之间进行叉积(为方便起见,得到一个称为 C 的向量),然后再次在 C 和 normal 之间进行叉积,以校正 up 向量.

If your up and normal vector aren't orthogonal, you can correct one of them easily. Just make the cross product between normal and up (results in a vector called C, for convenience) and do again the cross product between with C and normal, to correct the up vector.

这篇关于如何找到从一个向量到另一个向量的正确旋转?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆