JavaFX 8 Transform to pitch, yaw and roll rotation

2019-01-26 02:41发布

问题:

Implementing the answer from this thread I have this code that translates the deltayaw, deltaroll and deltapitch angles into one angle and rotates a node around it. The angles that are taken as the parameters are momentary changes of angles since giving the whole angles would ignore the changes in orientation.

    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);               
    }
}

(I'm using rotate because I need to always rotate the object around the origin, not the center)

Now this creates a problem as I'm no longer able to get the actual pitch, roll and yaw angles.

I used to keep track of them like this (which doesn't take into account the changing orientation):

roll +=deltaroll;
pitch += deltapitch;
yaw += deltayaw;

And later I've come up with this, which is a bit more accurate, but doesn't track the changes that occur if the angles are not directly modified(inserted after the n.getTransforms().add(all) in the main snippet):

roll+= Math.toDegrees(d)*((A32-A23)/den);
pitch += Math.toDegrees(d)*((A13-A31)/den);
yaw += Math.toDegrees(d)*((A21-A12)/den);  

I've been searching around for solutions and found this answer which is supposed to give the angle from the final transform but I haven't been able to get it working for all angles.

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

Again what I'm trying to get are the full angles (composited out of the transforms made from the delta angles in different orientations) relative to the scene's coodrdinate system. I'm really bad at this so all help would be great.

回答1:

If you want to get the pitch, yaw and roll angles at any stage after several rotations, you can get them from the transformation matrix of the 3D model.

If you have a look at the transformation matrix after several rotations:

Transform T = model3D.getLocalToSceneTransform();
System.out.println(T);

you'll see something like this:

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
    ]

If you want the angles, you just need to compare this matrix with this one from this answer:

As you have already stated, to get the roll angle you can use T.getMxx() and T.getMyx():

double roll = Math.atan2(-T.getMyx(),T.getMxx());

Now, for the pitch, you can use T.getMzy() and T.getMzz() in the same way:

double pitch = Math.atan2(-T.getMzy(),T.getMzz());

Finally, for the yaw, use T.getMzx(), T.getMzy() and T.getMzz():

double yaw = Math.atan2(T.getMzx(),Math.sqrt(T.getMzy()*T.getMzy()+T.getMzz()*T.getMzz()));

This will give for the above matrix the angles you are looking for (in radians):

roll: -0.39281984604895126
pitch: -0.356235553820928
yaw: 0.21033388848106072