加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – Overlaping Shapes – 错误的重叠形状行为

发布时间:2020-12-15 05:02:15 所属栏目:Java 来源:网络整理
导读:简而言之 – 我有2个旋转矩形.在旋转时(通过Y轴)它们应该相互重叠 – 不幸的是,尽管旋转180度,但是其中一个ractangles“总是在前面”.如何解决这种行为?它似乎与whitch矩形中的顺序相关,并且已添加到组中.最后添加的那个总是在前面. 现场: package drawing
简而言之 – 我有2个旋转矩形.在旋转时(通过Y轴)它们应该相互重叠 – 不幸的是,尽管旋转180度,但是其中一个ractangles“总是在前面”.如何解决这种行为?它似乎与whitch矩形中的顺序相关,并且已添加到组中.最后添加的那个总是在前面.

现场:

package drawing.scene;

import javafx.application.Application;
import javafx.geometry.Point3D;
import javafx.scene.Camera;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import drawing.objects.Clock;
import drawing.objects.Cube;

public class MyScene extends Application {

    private int sceneEdgeSize = 800;
    private int clolcSize = 400;

    @Override
    public void start(Stage primaryStage) throws Exception {
        Group g = new Group();
        g.setTranslateX((sceneEdgeSize - clolcSize) / 2f);
        g.setTranslateY((sceneEdgeSize - clolcSize) / 2f);

        final Cube c = new Cube(clolcSize);
        g.getChildren().add(c);
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                Rotate r = rotate(0,Rotate.Y_AXIS);
                c.getTransforms().add(r);
                double angle = 0.0;
                while (true) {

                    r.setAngle(angle += 2);
                    try {
                        Thread.sleep(25);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        });
        t.setDaemon(true);
        primaryStage.setScene(new Scene(g,sceneEdgeSize,sceneEdgeSize));
        PerspectiveCamera camera = new PerspectiveCamera();
        primaryStage.getScene().setCamera(camera);
        primaryStage.show();
        t.start();

    }

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

    public Rotate rotate(double angle,Point3D axis) {
        return new Rotate(angle,clolcSize / 2f,axis);
    }

}

立方体类:

package drawing.objects;

import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.RectangleBuilder;
import javafx.scene.transform.Rotate;

public class Cube extends Group {

    private double edgeLength = 0;

    public Cube(double edgeLength) {
        super();
        this.edgeLength = edgeLength;
        create();
    }

    private void create() {
        final Rotate rx = new Rotate(0,Rotate.X_AXIS);
        final Rotate ry = new Rotate(0,Rotate.Y_AXIS);
        final Rotate rz = new Rotate(0,Rotate.Z_AXIS);

        this.getTransforms().addAll(rx,ry,rz);

        ObservableList<Node> children = this.getChildren();
        //@formatter:off

        Rectangle rect;

        rect = RectangleBuilder // face
                .create()
                .width(edgeLength-20)
                .height(edgeLength-20)
                .translateZ(edgeLength * 0.5)
//                  .translateY(edgeLength * 0.5)
                //  .translateX(-edgeLength * 0.5)
                .fill(Color.LIGHTGREEN)
                .build()
                ;
        children.add(rect);
        rect = RectangleBuilder // face
                .create()
                .width(edgeLength-20)
                .height(edgeLength-20)
                .translateZ(-edgeLength * 0.5)
//              .translateY(-edgeLength * 0.5)
            //  .translateX(-edgeLength * 0.5)
                .fill(Color.DARKGREEN)
                .build()
                ;
        children.add(rect);


        //@formatter:on
    }
}

解决方法

你应该 switch depth buffering on in your scene.

此问题中的代码基本上已过时,部分内容也不正确:

>对于JavaFX 3D work,建议使用Java 8.
>要构建立方体,请使用Box形状.
>对于其他几何类型,请使用Sphere,Cylinder或MeshView.
>使用Point和Ambient灯照亮场景.
>将Materials应用于3D对象以遮挡它们.
>使用Model importers导入复杂网格模型.
> Builders已弃用.
>为了处理动画,不建议生成另一个线程,而是使用JavaFX animation package.
>对于您问题中的特定动画,RotateTransition是适当的动画.
>您的解决方案不是线程安全的.您不应该修改活动场景图中节点的属性(例如,显示节点的转换属性),而不是应用程序线程(请改用Platform.runLater).
>您没有创建将depth buffering设置为true的场景.深度缓冲标志告诉JavaFX它应该对3D对象应用深度排序和剔除.

还要检查您的系统是否支持JavaFX 3D:

System.out.println(
  "3D supported? " + 
  Platform.isSupported(ConditionalFeature.SCENE3D)
);

Java 8用于旋转立方体的3D示例代码

这是一个用Java 8编码的旋转立方体.

import javafx.animation.*;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;

public class RotatingCube extends Application {

    private static final double SCENE_SIZE = 300;
    private static final double BOX_EDGE_LENGTH = SCENE_SIZE / 2d;

    private static final Color BOX_COLOR     = Color.DARKGREEN;
    private static final Color AMBIENT_COLOR = Color.rgb(30,30,30);
    private static final Color LIGHT_COLOR   = Color.WHITE;

    private static final Duration ROTATION_DURATION = Duration.seconds(4.5);

    @Override
    public void start(Stage stage) throws Exception {
        Scene scene = new Scene(
                new Group(
                        new AmbientLight(AMBIENT_COLOR),createPointLight(),createRotatingBox()
                ),SCENE_SIZE,true,SceneAntialiasing.BALANCED
        );
        scene.setFill(Color.MIDNIGHTBLUE.darker().darker().darker());
        scene.setCamera(new PerspectiveCamera());

        stage.setScene(scene);
        stage.show();
    }

    private PointLight createPointLight() {
        PointLight light = new PointLight(LIGHT_COLOR);
        light.setTranslateX( SCENE_SIZE / 2d);
        light.setTranslateY( SCENE_SIZE / 2d);
        light.setTranslateZ(-SCENE_SIZE);

        return light;
    }

    private Box createRotatingBox() {
        final Box box = new Box(BOX_EDGE_LENGTH,BOX_EDGE_LENGTH,BOX_EDGE_LENGTH);
        box.setTranslateX(SCENE_SIZE / 2d);
        box.setTranslateY(SCENE_SIZE / 2d);
        box.setTranslateZ(BOX_EDGE_LENGTH / 2d);
        box.setMaterial(new PhongMaterial(BOX_COLOR));

        rotateAroundYAxis(box);

        return box;
    }

    private void rotateAroundYAxis(Box box) {
        RotateTransition rotate = new RotateTransition(ROTATION_DURATION,box);
        rotate.setFromAngle(0);
        rotate.setToAngle(360);
        rotate.setAxis(Rotate.Y_AXIS);
        rotate.setCycleCount(RotateTransition.INDEFINITE);
        rotate.setInterpolator(Interpolator.LINEAR);
        rotate.play();
    }

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

}

用于两个旋转矩形的Java 8 3D示例代码

import javafx.animation.*;
import javafx.application.*;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;
import javafx.util.Duration;

public class RotatingRectangles extends Application {

    private static final double SCENE_SIZE = 300;
    private static final double EDGE_LENGTH = SCENE_SIZE / 2d;

    private static final Duration ROTATION_DURATION = Duration.seconds(4.5);

    @Override
    public void start(Stage stage) throws Exception {
        System.out.println(
            "3D supported? " +
            Platform.isSupported(ConditionalFeature.SCENE3D)
        );

        Scene scene = new Scene(
                createRotatingShapes(),SceneAntialiasing.BALANCED
        );
        scene.setFill(Color.MIDNIGHTBLUE.darker().darker().darker());
        scene.setCamera(new PerspectiveCamera());

        stage.setScene(scene);
        stage.show();
    }

    private Group createRotatingShapes() {
        final Rectangle rect1 = new Rectangle(
            EDGE_LENGTH,EDGE_LENGTH,Color.LIGHTGREEN
        );
        rect1.setTranslateX(-EDGE_LENGTH / 2d);
        rect1.setTranslateY(-EDGE_LENGTH / 2d);
        rect1.setTranslateZ( EDGE_LENGTH / 2d);

        final Rectangle rect2 = new Rectangle(
            EDGE_LENGTH,Color.DARKGREEN
        );
        rect2.setTranslateX(-EDGE_LENGTH / 2d);
        rect2.setTranslateY(-EDGE_LENGTH / 2d);
        rect2.setTranslateZ(-EDGE_LENGTH / 2d);

        final Group shapes = new Group(
            rect1,rect2
        );

        shapes.setTranslateX(SCENE_SIZE / 2d);
        shapes.setTranslateY(SCENE_SIZE / 2d);
        shapes.setTranslateZ(EDGE_LENGTH / 2d);

        rotateAroundYAxis(shapes);

        return shapes;
    }

    private void rotateAroundYAxis(Node node) {
        RotateTransition rotate = new RotateTransition(ROTATION_DURATION,node);
        rotate.setFromAngle(0);
        rotate.setToAngle(360);
        rotate.setAxis(Rotate.Y_AXIS);
        rotate.setCycleCount(RotateTransition.INDEFINITE);
        rotate.setInterpolator(Interpolator.LINEAR);
        rotate.play();
    }

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

}

在第一张图片中,暗矩形已在浅色矩形的前面旋转.

在第一张图片中,浅色矩形已在黑色矩形的前面旋转.

因此,您可以看到JavaFX系统正确显示场景中的深度排序形状.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读