javafx中鼠标沿Z轴旋转

use*_*468 3 3d javafx rotation javafx-8

我想在 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);
        } 
    });
}
Run Code Online (Sandbox Code Playgroud)

Luk*_*uke 5

我使用 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();
    });
}
Run Code Online (Sandbox Code Playgroud)

整个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);
    }
}
Run Code Online (Sandbox Code Playgroud)