gpt4 book ai didi

java - 将坐标从 3D 场景转换为 2D 叠加

转载 作者:行者123 更新时间:2023-11-30 06:40:30 25 4
gpt4 key购买 nike

类似于How to get 2D coordinates on window for 3D object in javafx但我无法使解决方案起作用。

我想为 3d 形状或更像其投影绘制 2d 边框。我写了这个示例代码以供引用:

import javafx.application.Application;
import javafx.geometry.Point3D;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;

public class CoordinateConversion extends Application {

@Override
public void start(Stage stage) {
var box = new Box(20, 20, 20);
box.setMaterial(new PhongMaterial(Color.TEAL));
box.getTransforms().add(new Rotate(45, new Point3D(1, 1, 1)));
var rootGroup = new Group(box);

var camera = new PerspectiveCamera(true);
camera.setFarClip(500);
camera.setTranslateZ(-100);
var aaScene = new SubScene(rootGroup, 0, 0, true, SceneAntialiasing.BALANCED);
aaScene.setCamera(camera);

var pane3d = new Pane(aaScene);
pane3d.setBackground(new Background(new BackgroundFill(Color.BEIGE, null, null)));
aaScene.widthProperty().bind(pane3d.widthProperty());
aaScene.heightProperty().bind(pane3d.heightProperty());

var overlay = new AnchorPane();

var stack = new StackPane(pane3d, overlay);
var filler = new Rectangle(0, 0, 100, 50);
filler.setFill(Color.rgb(0, 255, 0, 0.3));
var borderPane = new BorderPane();
borderPane.setCenter(stack);
borderPane.setTop(filler);
var scene = new Scene(borderPane);
stage.setScene(scene);
stage.setWidth(800);
stage.setHeight(400);
stage.show();

var sceneBounds = box.localToScene(box.getBoundsInLocal(), false);
var overlayBounds = overlay.sceneToLocal(sceneBounds);
var rect = new Rectangle(overlayBounds.getMinX(), overlayBounds.getMinY(), overlayBounds.getWidth(), overlayBounds.getHeight());
rect.setFill(null);
rect.setStroke(Color.RED);
overlay.getChildren().add(rect);
}

public static void main(String[] args) {
launch(args);
}
}

它在角落绘制红色矩形,而我想要的是我添加的“照片处理”橙色矩形。

enter image description here

基本思想是将边界从一个父级转换为另一个父级,因此我从一个父级转换为场景,然后从场景到下一个父级,正如我在 How to translate a node in a parent's coordinate system? 中所教的那样.关于转换我不明白的一些事情

  1. 如果我使用 box.localToScene(box.getBoundsInLocal(), true) 我得到 NaN 边界,即使盒子在子场景中并且我想要坐标现场。
  2. sceneBoundsoverlayBounds 是相同的,即使叠加开始时比场景低 50 像素(因为填充)。我希望叠加层和场景之间的每次转换在 y 上都恰好为 +-50,如果它们没有转换的话。

我还尝试使用 box.getParent().localToScene(box.getBoundsInParent()) 获取 sceneBounds 但 ti 是一样的。我想这是有道理的,因为我使用父级来转换父级中的边界,而不是使用节点来转换本地中的边界。

使用 Javafx 12

最佳答案

您有一个“时间”问题:您将 subScene 设置为 0x0 尺寸,然后添加绑定(bind),并在显示舞台后计算 sceneBounds right ,返回 NaN

如果您向 pane3d.widthProperty() 添加一个监听器,您将看到 sceneBounds 在宽度更改之前被解析,因此,您正在使用 0x0 子场景。所以你说得太早了。

可能的解决方案:

  • 移除绑定(bind)并为子场景维度设置一个值:
var aaScene = new SubScene(rootGroup, 800, 400, true, SceneAntialiasing.BALANCED);
stage.show();
var sceneBounds = box.localToScene(box.getBoundsInLocal(), true);
...
  • 保留绑定(bind),但向子场景的高度属性(在宽度之后设置)添加一个监听器:
aaScene.heightProperty().addListener((obs, ov, nv) -> {
var sceneBounds = box.localToScene(box.getBoundsInLocal(), true);
...
});

无论哪种情况,请注意您必须使用 localToScene(..., true) 来获取场景坐标:

If the Node does not have any SubScene or rootScene is set to true, the result point is in Scene coordinates of the Node returned by getScene().

enter image description here

关于java - 将坐标从 3D 场景转换为 2D 叠加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57967341/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com