在JavaFX中正确旋转3轴上的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); 

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

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

这就是为什么所有这些教程都指向旋转矩阵的原因:在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)); } } 

其中alf是roll, bet是pitch, gam是yaw。

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