Matrix JavaFX 8到俯仰、偏航和滚转旋转角度的变换

Matrix JavaFX 8到俯仰、偏航和滚转旋转角度的变换,matrix,3d,rotation,javafx-8,Matrix,3d,Rotation,Javafx 8,实现来自我的答案有一段代码,它将deltayaw、deltaroll和deltapitch角度转换为一个角度,并围绕它旋转一个节点。作为参数的角度是角度的瞬时变化,因为给出整个角度会忽略方向的变化 public static void matrixRotate(Group n, double deltaroll, double deltapitch, double deltayaw){ double A11 = Math.cos(deltaroll)*Math.cos(d

实现来自我的答案有一段代码,它将deltayaw、deltaroll和deltapitch角度转换为一个角度,并围绕它旋转一个节点。作为参数的角度是角度的瞬时变化,因为给出整个角度会忽略方向的变化

    public static void matrixRotate(Group n, double deltaroll, double deltapitch, double deltayaw){    
    double A11 = Math.cos(deltaroll)*Math.cos(deltayaw);
    double A12 = Math.cos(deltapitch)*Math.sin(deltaroll)+Math.cos(deltaroll)*Math.sin(deltapitch)*Math.sin(deltayaw);
    double A13 = Math.sin(deltaroll)*Math.sin(deltapitch)-Math.cos(deltaroll)*Math.cos(deltapitch)*Math.sin(deltayaw);
    double A21 =-Math.cos(deltayaw)*Math.sin(deltaroll);
    double A22 = Math.cos(deltaroll)*Math.cos(deltapitch)-Math.sin(deltaroll)*Math.sin(deltapitch)*Math.sin(deltayaw);
    double A23 = Math.cos(deltaroll)*Math.sin(deltapitch)+Math.cos(deltapitch)*Math.sin(deltaroll)*Math.sin(deltayaw);
    double A31 = Math.sin(deltayaw);
    double A32 =-Math.cos(deltayaw)*Math.sin(deltapitch);
    double A33 = Math.cos(deltapitch)*Math.cos(deltayaw);

    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);
        Rotate r = new Rotate();
        r.setAxis(p);
        r.setAngle(Math.toDegrees(d));
        n.getTransforms().add(r);
        Transform all = n.getLocalToSceneTransform();
        n.getTransforms().clear();
        n.getTransforms().add(all);               
    }
}
(我使用旋转是因为我需要始终围绕原点而不是中心旋转对象)

现在这就产生了一个问题,因为我不再能够得到实际的俯仰角、横滚角和偏航角

我过去经常这样跟踪他们(不考虑方向的变化):

后来我提出了这个,更准确一点,但是如果角度没有直接修改(插入到主代码段中的n.getTransforms().add(all)之后),则不会跟踪发生的更改:

我一直在寻找解决方案,找到了最终变换的角度,但我没能让它适用于所有角度

double xx = n.getLocalToSceneTransform().getMxx();
double xy = n.getLocalToSceneTransform().getMxy();
double roll = Math.atan2(-xy, xx);

同样,我试图得到的是相对于场景坐标系的完整角度(由不同方向的三角洲角度进行的变换合成)。我在这方面真的很差,所以所有的帮助都会很好。

如果你想在几次旋转后的任何阶段获得俯仰、偏航和侧倾角度,你可以从3D模型的变换矩阵中获得它们

如果在多次旋转后查看变换矩阵:

Transform T = model3D.getLocalToSceneTransform();
System.out.println(T);
您将看到如下内容:

Transform [
        0.9034731871219395, -0.4260296991535005, -0.04727468234587054, 1.4044414829046357
        0.3743586809560477, 0.837958815679334, -0.39709016761704913, 0.5234811188037405
        0.2087864414768669, 0.3410626315861443, 0.9165612381019399, -1.1277640590168572
    ]
如果需要角度,只需将此矩阵与以下矩阵进行比较:

如前所述,要获得滚动角度,可以使用
T.getMxx()
T.getMyx()

现在,对于音高,您可以以相同的方式使用
T.getMzy()
T.getMzz()

double pitch = Math.atan2(-T.getMzy(),T.getMzz());
最后,对于偏航,使用
T.getMzx()
T.getMzy()
T.getMzz()

这将为上述矩阵提供您要查找的角度(弧度):


这种方法是可行的,但角度似乎被限制在-90到90度之间,在到达边界后开始反转。这有点奇怪,因为atan2应该负责这一点。我真的不知道,但问题可能是在
matrixRotate()
上获取旋转角度的方式。在一些情况下,特征值法会给你一些小故障……现在我对它进行了更多的测试,似乎只有偏航计算被关闭,俯仰和横滚在180到-180之间工作良好。我猜平方根会消除一半的结果?也许我可以处理异常……不过还有一件事,似乎是这样的:double yaw=Math.atan2(T.getMzx(),Math.sqrt(T.getMzy()*T.getMzy()+T.getMzz()*T.getMzz());执行与double yaw=Math.toDegrees(Math.asin(T.getMxz())完全相同的操作;当然,正如您在矩阵图上看到的,您可以从
Mxz
获得角度,但我认为使用
tan2
来覆盖更多情况是更好的方法。
Transform [
        0.9034731871219395, -0.4260296991535005, -0.04727468234587054, 1.4044414829046357
        0.3743586809560477, 0.837958815679334, -0.39709016761704913, 0.5234811188037405
        0.2087864414768669, 0.3410626315861443, 0.9165612381019399, -1.1277640590168572
    ]
double roll = Math.atan2(-T.getMyx(),T.getMxx());
double pitch = Math.atan2(-T.getMzy(),T.getMzz());
double yaw = Math.atan2(T.getMzx(),Math.sqrt(T.getMzy()*T.getMzy()+T.getMzz()*T.getMzz()));
roll: -0.39281984604895126
pitch: -0.356235553820928
yaw: 0.21033388848106072