Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

java - Rotate a 3D object on 3 axis in JavaFX properly

So the method that I've used so far to rotate objects in JavaFX was that I layered it in 3 groups, each of them with a Rotate attached and locked to a single axis like so:

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

and did a setAngle() for each time I needed to rotate the object. This worked very well for only heading and roll until i decided that I need pitch too. Now a lot of tutorials for OpenGL and alike say that rotational matixes or quaternions are best for these type of rotations, but the javadoc lacks any usefull data regaring this.

Example: What happens when I rotate an object by 180 degrees on the y axis (and what should actually have happened in transparent blue) enter image description here Am I missing something? All help would be appreciated.

See Question&Answers more detail:os

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

1 Answer

0 votes
by (71.8m points)

There's a reason why all those tutorials point to rotational matrices: in 3D you can't perform simultaneous rotations one by one, you need to perform them at once. Since JavaFX only uses one angle and one axis, you have to provide the way to convert three rotations over three axes in just one angle and one axis.

A while ago I went to all the math behind these operations in my blog post about using Leap Motion to get the three rotations of your hand (pitch, yaw, roll) to rotate a 3D model.

So basically, from three rotations: pitch (around its X axis), yaw (around its Y axis) and roll (around its Z axis), you have these matrices:

Matrices

and if you combine them you have one single matrix:

Matrix

Without further explanations, the angle and the rotation unitary axis components can be computed from:

eigenvalues

Which can be written as:

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

where alf is roll, bet is pitch and gam is yaw.

You can find the full project here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...