gpt4 book ai didi

javafx 3d 球体局部纹理

转载 作者:行者123 更新时间:2023-12-04 17:17:43 24 4
gpt4 key购买 nike

我正在尝试使用 JavaFX (16) 在球体上绘制纹理。我添加了带有纹理的 Material ,但纹理被拉伸(stretch)到整个表面。是否可以仅在表面的一部分上设置纹理?如下图(不是我的,取自 SO):
enter image description here
到目前为止我的代码(非常简单):

public void start(Stage stage) throws Exception {
Sphere sphere = new Sphere(200);
PhongMaterial material = new PhongMaterial();
material.setDiffuseMap(new Image(new File("picture.png").toURI().toURL().toExternalForm()));
sphere.setMaterial(material);
Group group = new Group(sphere);
Scene scene = new Scene( new StackPane(group), 640, 480, true, SceneAntialiasing.BALANCED);
scene.setCamera(new PerspectiveCamera());
stage.setScene(scene);
stage.show();
}

最佳答案

你应用的纹理被拉伸(stretch)到整个球体的原因是定义Sphere的纹理坐标。网格正在映射整个球体表面,因此,当您应用漫反射图像时,它会 1-1 转换到该表面。
您可以使用自定义纹理坐标值创建自定义网格,但这可能会更复杂。
另一种选择是根据您的需要“按需”创建漫反射图像。
对于球体,可以通过 2*r*PI x 2*r 定义可以包裹在 3D 球体周围的 2D 图像。矩形容器(JavaFX Pane 用于我们的目的)。
然后,您可以在图像内部绘制,相应地缩放和平移它们。
最后,您需要一种将绘图转换为图像的方法,为此您可以使用 Scene::snapshot .
只是为了玩弄这个想法,我将创建一个矩形网格,它将环绕球体,以便拥有某种坐标系。

    private Image getTexture(double r) {
double h = 2 * r;
double w = 2 * r * 3.125; // 3.125 is ~ PI, rounded to get perfect squares.

Pane pane = new Pane();
pane.setPrefSize(w, h);
pane.getStyleClass().add("pane-grid");

Group rootAux = new Group(pane);
Scene sceneAux = new Scene(rootAux, rootAux.getBoundsInLocal().getWidth(), rootAux.getBoundsInLocal().getHeight());
sceneAux.getStylesheets().add(getClass().getResource("/style.css").toExternalForm());
SnapshotParameters sp = new SnapshotParameters();
return rootAux.snapshot(sp, null);
}
哪里 style.css拥有:
.pane-grid {
-fx-background-color: #D3D3D333,
linear-gradient(from 0.5px 0.0px to 50.5px 0.0px, repeat, black 5%, transparent 5%),
linear-gradient(from 0.0px 0.5px to 0.0px 50.5px, repeat, black 5%, transparent 5%);
}

.pane-solid {
-fx-background-color: black;
}
(基于此 answer )
半径为 400 时,您会得到以下图像:
2D grid
每个方块是 50x50,有 50x16 个方块。
如果将此漫反射贴图应用于 Sphere :
    @Override
public void start(Stage stage) {
PhongMaterial earthMaterial = new PhongMaterial();
earthMaterial.setDiffuseMap(getTexture(400));

final Sphere earth = new Sphere(400);
earth.setMaterial(earthMaterial);

Scene scene = new Scene(root, 800, 600, true);
scene.setFill(Color.WHITESMOKE);
stage.setScene(scene);
stage.show();
}
你得到:
3D grid
理论上,现在您可以填充任何网格方块,例如:
private Image getTexture(double r) throws IOException {
double h = 2 * r;
double w = 2 * r * 3.125;

Pane pane = new Pane();
pane.setPrefSize(w, h);
pane.getStyleClass().add("pane-grid");

Rectangle rectangle = new Rectangle(50, 50, Color.RED);
rectangle.setStroke(Color.WHITE);
rectangle.setStrokeWidth(2);
// fill rectangle at 20 x 10
rectangle.setTranslateX(20 * 50 + 1);
rectangle.setTranslateY(10 * 50 + 1);
Group rootAux = new Group(pane, rectangle);
...
结果:
1 rectangle
现在你有一个定位良好的图像(现在只是一个红色矩形),你可以去掉网格,简单地为纹理图像使用黑色:
   private Image getTexture(double r) throws IOException {
double h = 2 * r;
double w = 2 * r * 3.125;

Pane pane = new Pane();
pane.setPrefSize(w, h);
// pane.getStyleClass().add("pane-grid");
pane.getStyleClass().add("pane-solid");
导致:
black sphere
现在由您来将这个想法应用到您的需求中。请注意,您可以使用 ImageView大小为 50x50 或 100x100,...而不是红色矩形,因此您可以使用更复杂的图像。

关于javafx 3d 球体局部纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68186839/

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