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

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

问题描述

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




  • 正常向量




喜欢这张图片:





向上向量垂直于法线向量。现在我想找到从一个对象到另一个对象的唯一旋转,该如何做?



我有一个方法来找到一个向量和另一个向量之间的旋转,它的工作原理。问题是,我需要关心两个向量:法线向量和向量向量。如果我使用这个方法从对象1旋转法向量到对象2的正常向量,向上向量可能指向错误的方向,他们需要是平行的。



是找到最短旋转的代码:

  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)//选择另一个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;
}

我应该更改/添加到此代码,以找到正确的旋转?

解决方案

在我们开始之前,我将假设UP向量和法向量都是归一化强>正交(点积为零)。



我们假设您要旋转黄色板以与玫瑰(红色?)板对齐。所以,我们的参考将是从黄板的矢量,我们将称为我们的坐标系统为XYZ,其中Z->正常黄色矢量,Y->向上黄色矢量和X-> YxZ(叉积)。

以同样的方式,对于玫瑰板,旋转的坐标系统将被称为X'Y'Z',其中Z'→正常玫瑰矢量,Y'→上玫瑰矢量,X ' - > Y'xZ'(交叉乘积)。



好找到旋转矩阵,我们只需要确保我们的正常黄色向量将变成正常的玫瑰向量;我们的黄色矢量将在上升矢量中变换,等等:

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

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



如果你的向上和法线向量不正交,你可以很容易地纠正其中之一。只要使正交和向上之间的交叉乘积(为了方便起见,产生一个称为C的向量),并再次执行与C和正交之间的交叉乘积,以校正向上向量。


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

  • normal vector
  • up vector

Like on this image:

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?

解决方案

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

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).

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

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天全站免登陆