java 旋转矩阵未返回Z轴上的正确数字

kq4fsx7k  于 2023-02-07  发布在  Java
关注(0)|答案(1)|浏览(151)

我在我的Java代码中做了一个方法,它将一个3坐标矢量转换为另一个3坐标系,基于OpenGL曾经使用的旋转矩阵,下面是完整的方法:

public static float[] rotateVector3 (float x, float y, float z, double rX, double rY, double rZ){

        float[] ret = {x,y,z};
        while(rX < 0){rX += Math.PI*2;}
        while(rY < 0){rY += Math.PI*2;}
        while(rZ < 0){rZ += Math.PI*2;}
        while(rX >= Math.PI*2){rX -= Math.PI*2;}
        while(rY >= Math.PI*2){rY -= Math.PI*2;}
        while(rZ >= Math.PI*2){rZ -= Math.PI*2;}

        //ret[0] *= 1;
        ret[1] *= Math.cos(rX) - Math.sin(rX);
        ret[2] *= Math.sin(rX) + Math.cos(rX);

        ret[0] *= Math.cos(rY) + Math.sin(rY);
        //ret[1] *= 1;
        ret[2] *= - Math.sin(rY) + Math.cos(rY);

        ret[0] *= Math.cos(rZ) - Math.sin(rZ);
        ret[1] *= Math.sin(rZ) + Math.cos(rZ);
        //ret[2] *= 1;

        System.out.println("(" + x + " " + y + " " + z +") -> (" + rX + "º " + rY + "º " + rZ + "º) = (" + ret[0] + " " + ret[1] + " " + ret[2] + ")");
        return ret;

    }

然而,由于某种原因,此方法不能很好地用于Z轴。
例如,假设我有4个表示向量的数组,每个数组有3个坐标(分别为XYZ):vecA = {50,50,1}, vecB = {50,-50,1}, vecC = {-50f,-50f,1}, vecD = {-50f,50f,1}
当我在方法中按照它们各自的顺序输入这些值时,每个旋转值分别为{0,2,0}弧度,我得到以下输出:

(50.0 50.0 1.0) -> (0.0º 2.0º 0.0º) = (24.65753 50.0 -1.3254442)
(50.0 -50.0 1.0) -> (0.0º 2.0º 0.0º) = (24.65753 -50.0 -1.3254442)
(-50.0 -50.0 1.0) -> (0.0º 2.0º 0.0º) = (-24.65753 -50.0 -1.3254442)
(-50.0 50.0 1.0) -> (0.0º 2.0º 0.0º) = (-24.65753 50.0 -1.3254442)

这是没有道理的,当我在Y轴上旋转时,Y坐标大于零的向量应该比Y坐标为负的向量更远,但是它总是返回相同的Z值,我不知道为什么,我错过了什么修正吗?

waxmsbnn

waxmsbnn1#

我明白了,正确的方法是

public static float[] rotateVector3 (float x, float y, float z, double rX, double rY, double rZ, float aX, float aY, float aZ){

        float[] ret = new float[3];
        while(rX < 0){rX += Math.PI*2;}
        while(rY < 0){rY += Math.PI*2;}
        while(rZ < 0){rZ += Math.PI*2;}
        while(rX >= Math.PI*2){rX -= Math.PI*2;}
        while(rY >= Math.PI*2){rY -= Math.PI*2;}
        while(rZ >= Math.PI*2){rZ -= Math.PI*2;}

        double cosX = Math.cos(rX);
        double cosY = Math.cos(rY);
        double cosZ = Math.cos(rZ);
        double sinX = Math.sin(rX);
        double sinY = Math.sin(rY);
        double sinZ = Math.sin(rZ);

        double Axx = cosX*cosY;
        double Axy = cosX*sinY*sinZ - sinX*cosZ;
        double Axz = cosX*sinY*cosZ + sinX*sinZ;

        double Ayx = sinX*cosY;
        double Ayy = sinX*sinY*sinZ + cosX*cosZ;
        double Ayz = sinX*sinY*cosZ - cosX*sinZ;

        double Azx = -sinY;
        double Azy = cosY*sinZ;
        double Azz = cosY*cosZ;

        x-=aX;
        y-=aY;
        z-=aZ;

        ret[0] = (float) (Axx*x + Axy*y + Axz*z);
        ret[1] = (float) (Ayx*x + Ayy*y + Ayz*z);
        ret[2] = (float) (Azx*x + Azy*y + Azz*z);

        System.out.println("(" + x + " " + y + " " + z +") -> (" + rX + "º " + rY + "º " + rZ + "º) = (" + ret[0] + " " + ret[1] + " " + ret[2] + ")");
        return ret;

    }

我会解释一下它是如何工作的,但这意味着我实际上知道我在做什么

相关问题