【问题标题】:Rotating a vector by angle and axis in java在java中按角度和轴旋转矢量
【发布时间】:2026-01-28 16:30:01
【问题描述】:

我知道有很多关于这个主题或相关主题的问题和答案,但我已经尝试了 2 个小时,但仍然无法弄清楚。

我想要一个看起来像这样的函数:

public static Vector rotateVector(Vector v, Vector axis, double angle){

}

其中轴是定义旋转平面的单位向量(如果角度为正,则向量 v 朝向向量轴旋转)

我已经看过旋转矩阵,但无法将其实现到上述函数

【问题讨论】:

  • 我发现了一些可能有用的类。一个矩阵类pastebin.com/6WpiAX5R 和一个向量类pastebin.com/hsmTVhT8。 Matrix 类有一个接受轴和角度的构造函数,Vector 类有一个接受矩阵的 rotate 方法。

标签: java matrix vector


【解决方案1】:

将 (x, y, z) 绕 unit 向量 (u, v, w) 逆时针旋转角度 theta 会产生一个向量 (xPrime, yPrime, zPrime):

double xPrime = u*(u*x + v*y + w*z)*(1d - Math.cos(theta)) 
                + x*Math.cos(theta)
                + (-w*y + v*z)*Math.sin(theta);
double yPrime = v*(u*x + v*y + w*z)*(1d - Math.cos(theta))
                + y*Math.cos(theta)
                + (w*x - u*z)*Math.sin(theta);
double zPrime = w*(u*x + v*y + w*z)*(1d - Math.cos(theta))
                + z*Math.cos(theta)
                + (-v*x + u*y)*Math.sin(theta);

来源here

【讨论】:

    【解决方案2】:

    知道了,谢谢@Chris K。这是 java 函数:

    public static Vector rotateVectorCC(Vector vec, Vector axis, double theta){
        double x, y, z;
        double u, v, w;
        x=vec.getX();y=vec.getY();z=vec.getZ();
        u=axis.getX();v=axis.getY();w=axis.getZ();
        double xPrime = u*(u*x + v*y + w*z)*(1d - Math.cos(theta)) 
                + x*Math.cos(theta)
                + (-w*y + v*z)*Math.sin(theta);
        double yPrime = v*(u*x + v*y + w*z)*(1d - Math.cos(theta))
                + y*Math.cos(theta)
                + (w*x - u*z)*Math.sin(theta);
        double zPrime = w*(u*x + v*y + w*z)*(1d - Math.cos(theta))
                + z*Math.cos(theta)
                + (-v*x + u*y)*Math.sin(theta);
        return new Vector(xPrime, yPrime, zPrime);
    }
    

    不过,我会继续检查 Chris 的回答。

    【讨论】:

      【解决方案3】:

      这是旋转矢量的正确方法。

      private Vector rotateZ(Vector vector,double angle) { // angle in radians
      
        //normalize(vector); // No  need to normalize, vector is already ok...
      
        float x1 = (float)(vector.x * Math.cos(angle) - vector.y * Math.sin(angle));
      
        float y1 = (float)(vector.x * Math.sin(angle) + vector.y * Math.cos(angle)) ;
      
        return new Vector(x1, y1);
      
      }
      

      【讨论】:

      • 如果被旋转的向量已经在垂直于旋转轴的平面中,这是正确的。如果不是,请将矢量投影到平面上并应用旋转。平面外分量不受影响。
      • 是的,我认为它有效,但仅适用于 Z 轴!在任何给定的轴上做什么呢?
      • @BIELSIMON 你知道如何将矩阵应用于向量
      • @MCMastery 我认为它只是相乘,但我想要的是在 any 轴上旋转,作为参数给出。那么它不仅仅是乘以特定的旋转矩阵。那应该怎么做呢?
      • This question 在 c++ 中,但应该很容易扩展到 java。
      【解决方案4】:

      如果您想要 x、y 和 z 轴的旋转,那么您应该一次性使用旋转矩阵。

      NewVector = [Rotation_X][Rotation_Y][Rotation_Z]*OldVector

      这里 Rotation_X、Rotation_Y 和 Rotation_Z 是 3x3 矩阵。 (可以看http://mathworld.wolfram.com/RotationMatrix.html

      乘法的顺序取决于问题,但我想你只想要一个轴旋转(即其他 2 个矩阵成为单位矩阵)

      因此,只需放置一个 if 块,您就可以设置正确的矩阵,并将其余的保留为单位矩阵。

      希望这会有所帮助。

      【讨论】: