Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
551 views
in Technique[技术] by (71.8m points)

matrix - JavaFX 8 Transform to pitch, yaw and roll rotation angles

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:

Matrix

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...