java四元数3D旋转实现

标签 java math 3d

现在旋转工作了,我尝试将一个对象旋转 90 度,它旋转了它,但也在 oX 轴上向左产生了意想不到的平移。我为四元数的 w、x、y、z 分量添加了标准化方法,并纠正了我发现的任何代码错误。

这是我使用的方法:

 public class Point3DRotationQuaternions 
  {
   public static ArrayList<Float> rotation3D(ArrayList<Float> points, double angle, int x, int y, int z)
   {
    ArrayList<Float> newpoints = points;

    for (int i=0;i<points.size();i+=3)
    {
        float x_old = points.get(i).floatValue();
        float y_old = points.get(i+1).floatValue();
        float z_old = points.get(i+2).floatValue();
        double[] initial = {1,0,0,0};
        double[] total = new double[4];
        double[] local = new double[4];

        //components for local quaternion
        //w
        local[0] = Math.cos(0.5 * angle);
        //x
        local[1] = x * Math.sin(0.5 * angle);
        //y
        local[2] = y * Math.sin(0.5 * angle);
        //z
        local[3] = z * Math.sin(0.5 * angle);
        //local = magnitude(local);

        //components for final quaternion Q1*Q2
        //w = w1w2 - x1x2 - y1y2 - z1z2
        total[0] = local[0] * initial[0] - local[1] * initial[1] - local[2] * initial[2] - local[3] * initial[3];
        //x = w1x2 + x1w2 + y1z2 - z1y2
        total[1] = local[0] * initial[1] + local[1] * initial[0] + local[2] * initial[3] - local[3] * initial[2];
        //y = w1y2 - x1z2 + y1w2 + z1x2
        total[2] = local[0] * initial[2] - local[1] * initial[3] + local[2] * initial[0] + local[3] * initial[1];
        //z = w1z2 + x1y2 - y1x2 + z1w2
        total[3] = local[0] * initial[3] + local[1] * initial[2] - local[2] * initial[1] + local[3] * initial[0];

        //new x,y,z of the 3d point using rotation matrix made from the final quaternion
        float x_new = (float)((1 - 2 * total[2] * total[2] - 2 * total[3] * total[3]) * x_old
                         + (2 * total[1] * total[2] - 2 * total[0] * total[3]) * y_old
                         + (2 * total[1] * total[3] + 2 * total[0] * total[2]) * z_old);
        float y_new = (float) ((2 * total[1] * total[2] + 2 * total[0] * total[3]) * x_old
                         + (1 - 2 * total[1] * total[1] - 2 * total[3] * total[3]) * y_old
                         + (2 * total[2] * total[3] + 2 * total[0] * total[1]) * z_old);
        float z_new = (float) ((2 * total[1] * total[3] - 2 * total[0] * total[2]) * x_old
                         + (2 * total[2] * total[3] - 2 * total[0] * total[1]) * y_old
                         + (1 - 2 * total[1] * total[1] - 2 * total[2] * total[2]) * z_old);
        newpoints.set(i, x_new);
        newpoints.set(i+1, y_new);
        newpoints.set(i+2, z_new);

    }

    return newpoints;
  }
}

public static void main(String args[]) 
{

    ArrayList<Float> list = new ArrayList<>();
    list.add(new Float(0));
    list.add(new Float(0));
    list.add(new Float(-11));
    ArrayList<Float> list1 = Point3DRotationQuaternions.rotation3D(list, Math.toRadians(90), 0, 1, 0);
    for (int i=0;i<list1.size();i++)
        System.out.print(list1.get(i)+" ");
}

现在调用看起来像这样 rotation3D(points, Math.toRadians(90), 0, 1, 0)。 为了编写这些方法,我使用了 this article .

这些是我尝试旋转的图形的顶点:

//底部底座

旧顶点:

0.0 0.0 -9.0

0.0 0.0 -11.0

20.0 0.0 -11.0

20.0 0.0 -9.0

新顶点:

-9.0 0.0 -1.9984014E-15

-11.0 0.0 -2.4424907E-15

-11.0 0.0 -20.0

-9.0 0.0 -20.0

//顶部底座

旧顶点:

0.0 20.0 -11.0

0.0 20.0 -9.0

20.0 20.0 -9.0

20.0 20.0 -11.0

新顶点:

-11.0 20.0 -2.4424907E-15

-9.0 20.0 -1.9984014E-15

-9.0 20.0 -20.0

-11.0 20.0 -20.0

//脸

旧顶点:

0.0 20.0 -9.0

0.0 0.0 -9.0

20.0 0.0 -9.0

20.0 20.0 -9.0

新顶点:

-9.0 20.0 -1.9984014E-15

-9.0 0.0 -1.9984014E-15

-9.0 0.0 -20.0

-9.0 20.0 -20.0

//返回

旧顶点:

20.0 20.0 -9.0

20.0 0.0 -9.0

20.0 0.0 -11.0

20.0 20.0 -11.0

新顶点: -9.0 20.0 -20.0

-9.0 0.0 -20.0

-11.0 0.0 -20.0

-11.0 20.0 -20.0

//右侧

旧顶点:

0.0 0.0 -11.0

0.0 20.0 -11.0

20.0 20.0 -11.0

20.0 0.0 -11.0

新顶点:

-11.0 0.0 -2.4424907E-15

-11.0 20.0 -2.4424907E-15

-11.0 20.0 -20.0

-11.0 0.0 -20.0

//左基

旧顶点:

0.0 20.0 -9.0

0.0 20.0 -11.0

0.0 0.0 -11.0

0.0 0.0 -9.0

新顶点:

-9.0 20.0 -1.9984014E-15

-11.0 20.0 -2.4424907E-15

-11.0 0.0 -2.4424907E-15

-9.0 0.0 -1.9984014E-15

最佳答案

您执行了 total[0] = ... 四次。

关于java四元数3D旋转实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9843298/

相关文章:

java - ZipEntry 脚本压缩目录,15 个文件中有 14 个为空

python - 以编程方式求解函数方程

javascript - 支票号码彼此在范围内

c++ - 3D 空间中四边形的角度

java - hibernate 覆盖 "lazy=false"

java - 能否将不可运行的任务传递给 ThreadPoolExecutor

c++ - 如何识别分隔符以及如何将其与路径一起使用 Open Inventor

opengl - 获取变换后OpenGL 3D对象的屏幕坐标和大小

java - Android - 按类别过滤列表

java - Android Studio 返回简单数学表达式的错误结果