You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX 3D场景鼠标拖拽旋转相机功能失效 无法调整相机位置

核心问题原因

  1. 自定义相机未绑定到场景:JavaFX 默认使用内置正交相机渲染,你创建的PerspectiveCamera仅作为普通节点加入了Group,没有被设置为场景的渲染相机,所以所有对该相机的平移、旋转修改都不会生效。
  2. 旋转锚点配置错误:你给相机添加的Rotate变换默认以相机自身位置为旋转中心,而非世界原点,所以即使相机生效,也只会原地旋转,无法实现绕原点轨道运动的效果。
  3. 坐标对齐问题:场景默认2D原点在左上角,原点位置的坐标轴自然显示在左上角,需要调整对齐让原点对应屏幕中心。

具体修改方案

1. 修改Application启动类

将自定义相机绑定到场景,新增scene.setCamera(g.camera)配置:

public class TestApp extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        RotateCameraExample g = new RotateCameraExample();
        Scene scene = new Scene(g, 800, 800, Color.BLACK);
        // 新增:将自定义相机设置为场景渲染相机
        scene.setCamera(g.camera);
        stage.setScene(scene);
        stage.show();
    }
    public static void main(String[] args) {
        launch();
    }
}

2. 调整RotateCameraExample配置

  • 调整相机初始位置,沿Z轴后移避免和原点重合
  • 给旋转变换设置原点为旋转中心
  • 调整坐标轴位置对齐屏幕中心
    修改后的完整代码如下:
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;

public class RotateCameraExample extends Group {

    private double anchorX, anchorY;
    private double anchorAngleX = 0;
    private double anchorAngleY = 0;
    private final DoubleProperty angleX = new SimpleDoubleProperty(0);
    private final DoubleProperty angleY = new SimpleDoubleProperty(0);

    Camera camera;
    Group axes;

    public RotateCameraExample() {
        axes = buildAxes();
        // 新增:将坐标轴原点对齐800x800屏幕中心
        axes.setTranslateX(400);
        axes.setTranslateY(400);
        getChildren().add(axes);

        camera = new PerspectiveCamera(true);
        camera.setFarClip(6000);
        camera.setNearClip(0.01);
        camera.setFieldOfView(60);
        // 调整相机初始位置:与坐标轴同X/Y,沿Z轴后移800单位正对原点
        camera.setTranslateX(400);
        camera.setTranslateY(400);
        camera.setTranslateZ(800);

        getChildren().add(camera);
        initMouseControl();
    }

    private void initMouseControl() {
        Rotate xRotate = new Rotate(0, Rotate.X_AXIS);
        Rotate yRotate = new Rotate(0, Rotate.Y_AXIS);
        // 新增:设置旋转中心为坐标轴原点
        xRotate.setPivotX(400);
        xRotate.setPivotY(400);
        xRotate.setPivotZ(0);
        yRotate.setPivotX(400);
        yRotate.setPivotY(400);
        yRotate.setPivotZ(0);
        
        camera.getTransforms().addAll(xRotate, yRotate);
        xRotate.angleProperty().bind(angleX);
        yRotate.angleProperty().bind(angleY);

        setOnMousePressed(event -> {
            anchorX = event.getSceneX();
            anchorY = event.getSceneY();
            anchorAngleX = angleX.get();
            anchorAngleY = angleY.get();
        });

        setOnMouseDragged(event -> {
            angleX.set(anchorAngleX - (anchorY - event.getSceneY()));
            angleY.set(anchorAngleY + anchorX - event.getSceneX());
        });
    }

    private Group buildAxes() {
        final Box xAxis = new Box(1200, 10, 10);
        final Box yAxis = new Box(10, 1200, 10);
        final Box zAxis = new Box(10, 10, 1200);

        xAxis.setMaterial(new PhongMaterial(Color.RED));
        yAxis.setMaterial(new PhongMaterial(Color.GREEN));
        zAxis.setMaterial(new PhongMaterial(Color.BLUE));

        Group axisGroup = new Group();
        axisGroup.getChildren().addAll(xAxis, yAxis, zAxis);
        return axisGroup;
    }
}

修改后拖拽鼠标即可实现相机绕坐标轴原点轨道旋转的效果,坐标轴默认显示在屏幕中心。


内容的提问来源于stack exchange,提问作者Joshua Chambers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 05:45:04