鼠标在javafx中沿Z轴旋转

时间:2015-06-18 12:14:32

标签: javafx 3d 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);
        } 
    });
}

2 个答案:

答案 0 :(得分:4)

我使用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);
    }
}

答案 1 :(得分:1)

你可以在拖动的事件中尝试类似的东西:

<ImageView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_gravity="center_vertical|right"
  android:clickable="true"
  android:src="@drawable/sel_fed" />

也许您的计算可能正确,但我猜您的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将始终为0,因为您计算dy