在JavaFX中正确旋转3轴上的3D对象

Mof*_*ast 6 java 3d javafx quaternions javafx-3d

所以我到目前为止用于在JavaFX中旋转对象的方法是我将它分成3组,每组都附加一个Rotate并锁定到单个轴,如下所示:

    Rotate heading, roll, pitch;
    Group normalrotate, rollrotate, verticalrotate;

    heading.setAxis(new Point3D(0,1,0));
    normalrotate.getTransforms().add(heading);

    roll.setAxis(new Point3D(0,0,1));
    rollrotate.getTransforms().add(roll);

    pitch.setAxis(new Point3D(1,0,0));
    verticalrotate.getTransforms().add(pitch);
Run Code Online (Sandbox Code Playgroud)

并且每次我需要旋转对象时都会执行setAngle().这对于前进和滚动非常有效,直到我决定我也需要投球.现在很多OpenGL等教程都说旋转的matix或四元数最适合这种类型的旋转,但是javadoc缺少任何有用的数据.

示例:当我在y轴上旋转对象180度时会发生什么(实际上应该以透明蓝色旋转) 在此输入图像描述 我错过了什么吗?所有帮助将不胜感激.

Jos*_*eda 10

这就是为什么所有这些教程都指向旋转矩阵的原因:在3D中你无法一个一个地同时执行旋转,你需要立即执行它们.由于JavaFX仅使用一个角度和一个轴,因此必须提供在一个角度和一个轴上在三个轴上转换三个旋转的方法.

不久之前,我在博客文章中详细介绍了这些操作背后的所有数学知识,关于使用Leap Motion来获得手的三次旋转(俯仰,偏转,滚动)以旋转3D模型.

所以基本上,从三个旋转:俯仰(围绕其X轴),偏航(围绕其Y轴)和滚动(围绕其Z轴),您有这些矩阵:

矩阵

如果你把它们组合起来就有一个矩阵:

矩阵

无需进一步说明,角度和旋转单轴分量可以通过以下公式计算:

特征值

哪个可以写成:

private void matrixRotateNode(Node n, double alf, double bet, double gam){
    double A11=Math.cos(alf)*Math.cos(gam);
    double A12=Math.cos(bet)*Math.sin(alf)+Math.cos(alf)*Math.sin(bet)*Math.sin(gam);
    double A13=Math.sin(alf)*Math.sin(bet)-Math.cos(alf)*Math.cos(bet)*Math.sin(gam);
    double A21=-Math.cos(gam)*Math.sin(alf);
    double A22=Math.cos(alf)*Math.cos(bet)-Math.sin(alf)*Math.sin(bet)*Math.sin(gam);
    double A23=Math.cos(alf)*Math.sin(bet)+Math.cos(bet)*Math.sin(alf)*Math.sin(gam);
    double A31=Math.sin(gam);
    double A32=-Math.cos(gam)*Math.sin(bet);
    double A33=Math.cos(bet)*Math.cos(gam);

    double d = Math.acos((A11+A22+A33-1d)/2d);
    if(d!=0d){
        double den=2d*Math.sin(d);
        Point3D p= new Point3D((A32-A23)/den,(A13-A31)/den,(A21-A12)/den);
        n.setRotationAxis(p);
        n.setRotate(Math.toDegrees(d));                    
    }
}
Run Code Online (Sandbox Code Playgroud)

其中alf是辊,bet是俯仰和gam是偏航.

你可以在这里找到完整的项目.

  • 另一个很棒的答案!谢谢你,我真的遇到了这个问题的障碍. (2认同)
  • 指出旋转(和矩阵乘法)不会交换可能会有所帮助。也就是说,连续旋转的顺序很重要。绕不同轴的任何两次或多次旋转等效于绕复合轴的单次旋转。但是,如果您更改旋转顺序,则复合答案会有所不同。Jose 的计算是针对三个矩阵的特定乘积,即按特定顺序旋转。我相信它是 A=Az*Ay*Ax 将首先绕 x 轴旋转,然后是绕 y 轴旋转,然后是绕 z 轴旋转 (2认同)