【问题标题】:Mouse Rotation along Z axis in javafxjavafx中鼠标沿Z轴旋转
【发布时间】:2015-06-18 12:14:32
【问题描述】:

我想在 javafx 中使用鼠标旋转 3D 对象。我能够从鼠标 x,y 位置计算 x 轴旋转和 y 轴旋转的旋转角度,并能够围绕 x 轴和 y 轴旋转它。但我也想围绕 z 轴旋转对象。

如何计算鼠标x,y位置z轴旋转的旋转角度?

以下是用于围绕 x 和 y 轴旋转对象的示例代码。

private void handleMouseEvents() {
    setOnMousePressed((MouseEvent me) -> {
        setActivated(true);
        mousePosX = me.getSceneX();
        mousePosY = me.getSceneY();
        mouseOldX = me.getSceneX();
        mouseOldY = me.getSceneY();
    });

    setOnMouseDragged((MouseEvent me) -> {
        mousePosX = me.getSceneX();
        mouseOldY = me.getSceneY();
        double dx = (mousePosX - mouseOldX) ;
        double dy = (mouseOldY - mouseOldY);
        mouseOldX = mousePosX;
        mouseOldY = mouseOldY;
        if (me.isPrimaryButtonDown()) {
            rotateY.setAngle(rotateY.getAngle() - dx);
            rotateX.setAngle(rotateX.getAngle() + dy);
        } 
    });
}

【问题讨论】:

    标签: javafx 3d rotation javafx-8


    【解决方案1】:

    我使用 Zydar 的公式创建了一个可立即运行的示例。 testBox 是正在旋转的 3D 对象。

    如果这不是您想要的行为,请详细说明您的问题。

    重要的部分:

    private void handleMouseEvents() {
        scene.setOnMousePressed((MouseEvent me) -> {
            mousePosX = me.getSceneX();
            mousePosY = me.getSceneY();
        });
    
        scene.setOnMouseDragged((MouseEvent me) -> {
            double dx = (mousePosX - me.getSceneX()) ;
            double dy = (mousePosY - me.getSceneY());
            if (me.isPrimaryButtonDown()) {
                rotateX.setAngle(rotateX.getAngle() - 
                        (dy / testBox.getHeight() * 360) * (Math.PI / 180));
                rotateY.setAngle(rotateY.getAngle() - 
                        (dx / testBox.getWidth() * -360) * (Math.PI / 180));
            }
            mousePosX = me.getSceneX();
            mousePosY = me.getSceneY();
        });
    }
    

    整个SSCCE

    import javafx.application.Application;
    import javafx.scene.Group;
    import javafx.scene.Parent;
    import javafx.scene.PerspectiveCamera;
    import javafx.scene.Scene;
    import javafx.scene.SceneAntialiasing;
    import javafx.scene.SubScene;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Box;
    import javafx.scene.transform.Rotate;
    import javafx.scene.transform.Translate;
    import javafx.stage.Stage;
    
    public class SampleApp extends Application {
        private Box testBox;
        private Scene scene;
        private Rotate rotateX = new Rotate(0, Rotate.X_AXIS);
        private Rotate rotateY = new Rotate(0, Rotate.Y_AXIS);
        private Rotate rotateZ = new Rotate(0, Rotate.Z_AXIS);
        private final double TURN_FACTOR = 0.5; 
    
        public Parent createContent() throws Exception {
            // Box
            testBox = new Box(5, 5, 5);
            testBox.getTransforms().addAll(rotateZ, rotateY, rotateX);
    
            // Create and position camera
            PerspectiveCamera camera = new PerspectiveCamera(true);
            camera.getTransforms().addAll(
            new Rotate(-20, Rotate.Y_AXIS),
            new Rotate(-20, Rotate.X_AXIS),
            new Translate(0, 0, -50));
    
            // Build the Scene Graph
            Group root = new Group();
            root.getChildren().add(camera);
            root.getChildren().add(testBox);
    
            // Use a SubScene
            SubScene subScene = new SubScene(root, 300, 300, true, 
                 SceneAntialiasing.BALANCED);
            subScene.setFill(Color.TRANSPARENT);
            subScene.setCamera(camera);
    
            return new Group(subScene);
        }
    
        private double mousePosX, mousePosY = 0;
        private void handleMouseEvents() {
            scene.setOnMousePressed((MouseEvent me) -> {
                mousePosX = me.getSceneX();
                mousePosY = me.getSceneY();
            });
    
            scene.setOnMouseDragged((MouseEvent me) -> {
                double dx = (mousePosX - me.getSceneX()) ;
                double dy = (mousePosY - me.getSceneY());
                if (me.isPrimaryButtonDown()) {
                    rotateX.setAngle(rotateX.getAngle() - 
                        (dy / testBox.getHeight() * 360) * (Math.PI / 180));
                    rotateY.setAngle(rotateY.getAngle() - 
                        (dx / testBox.getWidth() * -360) * (Math.PI / 180));
                }
                mousePosX = me.getSceneX();
                mousePosY = me.getSceneY();
            });
        }
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            primaryStage.setResizable(false);
            scene = new Scene(createContent());
            handleMouseEvents();
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    【讨论】:

    • 我使用了上面的源代码,在做鼠标旋转时,盒子的位置被重置为初始位置。但我想从对象的最后一个位置进行旋转。
    • 我刚刚更新了代码,因此块的前一个角度包含在计算中。现在也可以拖动整个场景。
    【解决方案2】:

    您可以在拖动的事件中尝试类似的操作:

    double dx = (mousePosX - me.getSceneX());
    double dy = (mousePosY - me.getSceneY());
    
    rotateX((dy / 'Your 3D-object'.getHeight() * -360) * (Math.PI / 180));
    rotateY((dx / 'Your 3D-object'.getWidth() * -360) * (Math.PI / 180));
    
    mousePosX = me.getSceneX();
    mousePosY = me.getSceneY();
    

    也许您的计算可能是正确的,但我猜您将 Y 值设置错了。特别是dy 将永远为0,因为你计算mouseOldY - mouseOldY

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      • 2014-02-07
      • 1970-01-01
      • 2017-10-26
      相关资源
      最近更新 更多