矩阵围绕任意轴旋转 [英] Matrix Rotation Around an Arbitrary Axis Bug

查看:211
本文介绍了矩阵围绕任意轴旋转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图围绕一个任意轴旋转矩阵,我认为我很接近但是我有一个bug。我对3D旋转比较陌生,对发生的事情有基本的了解。

  public static Matrix4D Rotate(Vector3D u,Vector3D v)
{
double angle = Acos(u .DOT(v));
Vector3D轴= u.Cross(v);

double c = Cos(角度);
double s = Sin(angle);
double t = 1 - c;

return new Matrix4D(new double [,]
{
{c + Pow(axis.X,2)* t,axis.X * axis.Y * t - Z * s,axis.X * axis.Z * t + axis.Y * s,0},
{axis.Y * axis.X * t + axis.Z * s,c + Pow( Y,2)* t,axis.Y * axis.Z * t - axis.X * s,0},
{axis.Z * axis.X * t - axis.Y * s,axis 。* * axis.Y * t + axis.X * s,c + Pow(axis.Z,2)* t,0},
{0,0,0,1}
}) ;
}

上面的代码是矩阵旋转的算法。当我用单位向量测试算法时,我得到以下结果:

  Matrix4D rotationMatrix = Matrix4D.Rotate(new Vector3D(1,0) ,0),new Vector3D(0,0,1)); 

Vector4D vectorToRotate = new Vector4D(1,0,0,0);

Vector4D结果= rotationMatrix * vectorToRotate;

//结果
X = 0.0000000000000000612;
Y = 0;
Z = 1;
长度= 1;

随着90度的旋转,我发现它几乎完美地工作。现在让我们看看45度旋转:

pre $ Matrix4D rotationMatrix = Matrix4D.Rotate(new Vector3D(1,0,0), new Vector3D(1,0,1).Normalize());

Vector4D vectorToRotate = new Vector4D(1,0,0,0);

Vector4D结果= rotationMatrix * vectorToRotate;

//结果
X = .70710678118654746;
Y = 0;
Z = .5;
长度= 0.8660254037844386;

当我们采用atan(.5 / .707)时,我们发现我们有35.28度的旋转而不是45度旋转。矢量的长度也从1变为.866。有没有人有任何关于我在做什么的提示错误? 解决方案

您的矩阵代码看起来正确,但您需要 u> 和 v )进行了规范化操作,使得 axis 我不建议使用简单乘法而不是 Pow ,因为性能和准确性的原因;但是这是次要的,而不是问题的根源)


I have been attempting to get matrix rotation around an arbitrary axis working, I think I'm close but I have a bug. I am relatively new to 3D rotations and have a basic understanding of what is going on.

public static Matrix4D Rotate(Vector3D u, Vector3D v)
{
    double angle = Acos(u.Dot(v));
    Vector3D axis = u.Cross(v);

    double c = Cos(angle);
    double s = Sin(angle);
    double t = 1 - c;

    return  new Matrix4D(new double [,]
    {
        { c + Pow(axis.X, 2) * t,  axis.X * axis.Y * t -axis.Z * s, axis.X * axis.Z * t + axis.Y * s, 0 },
        { axis.Y * axis.X * t + axis.Z * s, c + Pow(axis.Y, 2) * t, axis.Y * axis.Z * t - axis.X * s, 0 },
        { axis.Z * axis.X * t - axis.Y * s, axis.Z * axis.Y * t + axis.X * s, c + Pow(axis.Z, 2) * t, 0 },
        { 0, 0, 0, 1 }
    });
}

The above code is the algorithm for the matrix rotation. When I test the algorithm with unit vectors I get the following:

Matrix4D rotationMatrix = Matrix4D.Rotate(new Vector3D(1, 0, 0), new Vector3D(0, 0, 1));

Vector4D vectorToRotate = new Vector4D(1,0,0,0);

Vector4D result = rotationMatrix * vectorToRotate;

//Result
X = 0.0000000000000000612;
Y = 0;
Z = 1;
Length = 1;

With a 90 degree rotation I find it works almost perfectly. Now lets look at a 45 degree rotation:

Matrix4D rotationMatrix = Matrix4D.Rotate(new Vector3D(1, 0, 0), new Vector3D(1, 0, 1).Normalize());

Vector4D vectorToRotate = new Vector4D(1,0,0,0);

Vector4D result = rotationMatrix * vectorToRotate;

//Result
X = .70710678118654746;
Y = 0;
Z = .5;
Length = 0.8660254037844386;

When we take the atan(.5/.707) we find that we have a 35.28 degree rotation instead of a 45 degree rotation. Also the length of the vector is changing from 1 to .866. Does anyone have any tips on what I am doing wrong?

解决方案

Your matrix code looks correct, but you need to normalize the axis too (just because u and v are normalized doesn't mean u cross v also is).

(I would also recommend using a simple multiply instead of Pow, for performance and accuracy reasons; but this is minor and not the source of your problem)

这篇关于矩阵围绕任意轴旋转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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