Rotate a 3D object on 3 axis in JavaFX properly

风流意气都作罢 提交于 2019-11-28 08:47:27

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:

and if you combine them you have one single matrix:

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

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.

I can offer a solution. But it is a bit uncivilized and might be a discouraged practice.

Node[] my3dModel = get3DModel();//the method creates a mesh (I suppose that you used Interactive mesh, but it's not important here)
Pane paneForMyModel = new Pane();
paneForMyModel.getChildren.addAll(my3dModel);//you add your model to this pane
//and now
paneForMyModel.getTransforms().add(new Rotate(angle, axis));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!