繁体   English   中英

向量在3D空间中的旋转和方向-逆序

[英]Rotation and direction of a vector in 3D space - Inverse Order

我在3D空间中有两个向量, S (开始)和T (目标),并且我想找到允许这种变换的旋转矩阵(RM)。

我知道通过计算叉积 S × T可以获得旋转轴。 ST之间的角度由tan⁻¹(||S × T||, S·T) ,其中S·T是S和T之间的点积

这给了我旋转矢量rotvec = [S x T; angle] rotvec = [S x T; angle] (叉积标准化)。 然后,通过使用函数vrrotvec2mat (在MATLAB中)或transforms3d.axangles.axangle2mat (在Python中),我可以获得与从ST的转换相对应的旋转矩阵。

在我的应用中, T点积 RM·D ,其中D3x1向量。 我的目标 是找到RM 我知道STD ,但是我很难理解其背后的数学原理。

实际上,我想在ST'之间找到一个RM,其中T'是在应用D (方向)之前的目标矢量。

更多背景信息 :我想从相机坐标系中的3D点获取人体关节角度。

为了完成这项工作,您还需要旋转中心(旋转后保持不变的点)...现在,我们需要两个变换矩阵,一个代表变换之前的坐标系,另一个代表变换之后的坐标系。

要构建3D变换矩阵,您需要3个垂直基矢量和原点位置,请参见:

现在旋转轴将是基本向量之一,我们可以使用S,T作为第二个向量,因此我们可以使用叉积计算第三个向量,并且原点将成为旋转中心:

X = cross(S,T);                      // rotation axis
X /= |X|;                            // unit vector
Y = S;                               // start vector
Y /= |Y|;                            // unit vector
Z = cross(X,Y);                      // Z perpendicular to X,Y
Z /= |Z|;                            // unit vector
O = center_of_rotation;

概观

因此,从中构造4x4变换矩阵A 并对B执行相同操作,但使用T而不是S 现在我们要计算差分变换,因此,如果p=(x,y,z,1)是要变换的任意点,则:

p' = Inverse(A)*p 
p' = B*p'         

因此,您的变换矩阵M为:

M = Inverse(A)*B;

请注意,如果您使用其他方程式(乘法顺序,矩阵方向等),则方程式可能会发生变化,这将与标准OpenGL约定一起使用。

您还可以使用完整的伪逆矩阵来更有效和准确地计算Inverse(A)

如您所见,您不需要任何角度测量法和角度即可(矢量数学很好用)

[Edit1] C ++示例

它使用VCL(您可以忽略的AnsiString和mm_log)和我的向量数学运算(使用的函数在第一个链接中)。

//---------------------------------------------------------------------------
AnsiString matrix_prn(double *a)
    {
    int i; AnsiString s;
    for (s ="(",i=0;i<16;i+=4) { if (a[i]>=0.0) s+=" "; s+=AnsiString().sprintf("%2.3lf,",a[i]); } s[s.Length()]=')'; s+="\r\n";
    for (s+="(",i=1;i<16;i+=4) { if (a[i]>=0.0) s+=" "; s+=AnsiString().sprintf("%2.3lf,",a[i]); } s[s.Length()]=')'; s+="\r\n";
    for (s+="(",i=2;i<16;i+=4) { if (a[i]>=0.0) s+=" "; s+=AnsiString().sprintf("%2.3lf,",a[i]); } s[s.Length()]=')'; s+="\r\n";
    for (s+="(",i=3;i<16;i+=4) { if (a[i]>=0.0) s+=" "; s+=AnsiString().sprintf("%2.3lf,",a[i]); } s[s.Length()]=')';
    return s;
    }
//---------------------------------------------------------------------------
AnsiString vector_prn(double *a)
    {
    int i; AnsiString s;
    for (s ="(",i=0;i<3;i++) { if (a[i]>=0.0) s+=" "; s+=AnsiString().sprintf("%2.3lf,",a[i]); } s[s.Length()]=')';
    return s;
    }
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
    {
    int i;
    double O[3]={0.00, 0.00,0.00};  // center ofrotation
    double S[3]={4.10,-9.44,0.54};  // start vector
    double T[3]={1.40,-9.08,4.10};  // end vector
    double A[16],_A[16],B[16],M[16],X[3],Y[3],Z[3];

    // A
    vector_mul(X,S,T);  // rotation axis
    vector_one(X,X);    // unit vector
    vector_one(Y,S);    // unit start vector
    vector_mul(Z,X,Y);  // Z perpendicular to X,Y
    vector_one(Z,Z);    // unit vector
    for (i=0;i<3;i++)
        {
        A[ 0+i]=X[i];
        A[ 4+i]=Y[i];
        A[ 8+i]=Z[i];
        A[12+i]=O[i];
        A[(i<<2)+3]=0.0;
        } A[15]=1.0;
    // B
    vector_one(Y,T);    // unit end vector
    vector_mul(Z,X,Y);  // Z perpendicular to X,Y
    vector_one(Z,Z);    // unit vector
    for (i=0;i<3;i++)
        {
        B[ 0+i]=X[i];
        B[ 4+i]=Y[i];
        B[ 8+i]=Z[i];
        B[12+i]=O[i];
        B[(i<<2)+3]=0.0;
        } B[15]=1.0;
    // M = B*Inverse(A)
    matrix_inv(_A,A);
    matrix_mul(M,_A,B);

    mm_log->Lines->Add("A");
    mm_log->Lines->Add(matrix_prn(A));
    mm_log->Lines->Add("B");
    mm_log->Lines->Add(matrix_prn(B));
    mm_log->Lines->Add("M");
    mm_log->Lines->Add(matrix_prn(M));
    mm_log->Lines->Add("");

    vector_one(S,S);    // unit start vector
    vector_one(T,T);    // unit end vector
    mm_log->Lines->Add("S = "+vector_prn(S));
    matrix_mul_vector(X,M,S);
    mm_log->Lines->Add("X = "+vector_prn(X));
    mm_log->Lines->Add("T = "+vector_prn(T));
    }
//-------------------------------------------------------------------------

结果如下:

A
(-0.760, 0.398,-0.514, 0.000)
(-0.361,-0.916,-0.175, 0.000)
(-0.540, 0.052, 0.840, 0.000)
( 0.000, 0.000, 0.000, 1.000)
B
(-0.760, 0.139,-0.635, 0.000)
(-0.361,-0.903, 0.235, 0.000)
(-0.540, 0.408, 0.736, 0.000)
( 0.000, 0.000, 0.000, 1.000)
M
( 0.959, 0.258,-0.115, 0.000)
(-0.205, 0.916, 0.345, 0.000)
( 0.194,-0.307, 0.932, 0.000)
( 0.000, 0.000, 0.000, 1.000)

S = ( 0.398,-0.916, 0.052)
X = ( 0.139,-0.903, 0.408) // X = M * S
T = ( 0.139,-0.903, 0.408)

如您所见,如果我将单位S转换为M ,就得到了单位T向量。 PS。 我的matrix_mul_vectorvector_mul假定w=1.0但是当O=(0.0,0.0,0.0) ,矢量和点相同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM