【问题标题】:Overlaping Shapes - wrong overlapping shapes behaviour重叠形状 - 错误的重叠形状行为
【发布时间】:2013-10-25 11:57:23
【问题描述】:

简而言之 - 我有 2 个旋转矩形。在旋转(按 Y 轴)时,它们应该一个接一个地重叠 - 不幸的是,尽管旋转了 180 度,但其中一个 ractangles 是“始终在前面”。如何解决这种行为?看起来它与添加到组中的矩形的顺序有关。最后添加的总是在前面。

场景:

    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, clolcSize / 2f, 0, 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
    }
}

【问题讨论】:

    标签: java javafx


    【解决方案1】:

    你应该switch depth buffering on in your scene

    此问题中的代码大部分已过时,并且部分内容也不正确:

    1. 对于JavaFX 3D work,建议使用Java 8
    2. 要构建立方体,请使用 Box 形状。
    3. 对于其他几何类型,请使用SphereCylinderMeshView
    4. 使用 PointAmbient 灯光照亮您的场景。
    5. Materials 应用于您的 3D 对象以对其进行着色。
    6. 使用Model importers 导入复杂的网格模型。
    7. Builders 已弃用。
    8. 对于处理动画,不建议生成另一个线程,而是使用JavaFX animation package
    9. 对于您问题中的特定动画,RotateTransition 是合适的动画。
    10. 您的解决方案不是线程安全的。您不应在应用程序线程之外修改活动场景图中节点的属性(例如,显示节点的变换属性)(改用Platform.runLater)。
    11. 您没有在 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, 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(),
                    SCENE_SIZE, SCENE_SIZE,
                    true,
                    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, 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 系统在场景中正确显示了深度排序的形状。

    【讨论】:

    • 现在这是一个很好的答案,先生! +1 并为您的努力接受了答案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 2018-07-21
    • 2015-04-18
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多