【问题标题】:How to check if a line intersect an image如何检查一条线是否与图像相交
【发布时间】:2017-09-13 05:26:26
【问题描述】:

这是我的以下代码:

  public void start(Stage primaryStage) throws Exception {
        Pane root = new Pane();
        Scene scene = new Scene(root, 500, 500, Color.WHITE);

        ImageView image = new ImageView(new Image(getClass().getResourceAsStream("dice.jpeg")));
        image.setX(35);
        image.setY(225);
        image.setFitWidth(50);
        image.setFitHeight(70);
        root.getChildren().add(image);

        Line line = new Line(20, 40, 120, 40);
        line.setStroke(Color.RED);
        line.setStrokeWidth(10);
        root.getChildren().add(line);

        if (line.getBoundsInParent().intersects(image.getBoundsInParent())) {
            System.out.println("intersect");
        }

        Timeline timeline = new Timeline(
                new KeyFrame(
                        Duration.seconds(2),
                        new KeyValue(line.translateYProperty(), 600)
                ));
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.setAutoReverse(false);

        timeline.play();
        primaryStage.setScene(scene);
        primaryStage.show();
    }

我希望在线条和图像相交时打印此System.out.println("intersect") 消息,但是当我运行我的代码时它不起作用。谁能告诉我我做错了什么?任何帮助表示赞赏!

【问题讨论】:

  • collision detection 上看到这个问题(也许这是重复的?)。你真的想检查边界交叉点还是你想检查视觉交叉点?当你有动画时,你需要在有东西移动时检查交叉点(例如在AnimationTimer中)而不是在创建时检查。
  • 你也可以给line.translateYProperty()添加一个监听器并检查其中的冲突。
  • 是的,在这个只有 y 属性发生变化的简单情况下,它的监听器会很好地工作并且实现起来非常简单。如果您的整个应用程序更复杂,并且每个帧可能会更改多个属性,则动画计时器内的检查可能更易于管理。

标签: java image javafx line intersect


【解决方案1】:

我想出了一个解决方案。这涉及在其他代码仍在运行时使用线程一直检查。您的代码中的错误是仅在动画尚未开始运行时检查一次。

显然,我的代码并不完美,因此您可能需要对其进行清理以满足您的需求:

public class Test extends Application{

public static void main(String[] args) {
    Test.launch(args);
    //The thread which checks continues to run so you have to stop it 
    //(There is definitly a better way to do this)
    System.exit(0);
}

@Override
public void start(Stage primaryStage) throws Exception {
    Pane root = new Pane();
    Scene scene = new Scene(root, 500, 500, Color.WHITE);

    ImageView image = new ImageView(new Image(getClass().getResourceAsStream("dice.jpeg")));
    image.setX(35);
    image.setY(225);
    image.setFitWidth(50);
    image.setFitHeight(70);
    root.getChildren().add(image);

    Line line = new Line(20, 40, 120, 40);
    line.setStroke(Color.RED);
    line.setStrokeWidth(10);
    root.getChildren().add(line);

    //new code
    Thread t = new Thread(){
        @Override
        public void run(){
            while(true){               
                try {
                    //you could add a Thread.sleep so it only checks every x miliseconds 
                    Thread.sleep(40);
                    if (line.getBoundsInParent().intersects(image.getBoundsInParent())) {
                        System.out.println("intersect");
                    }
                } catch (InterruptedException ex) {
                    Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

        }
    };
    t.start();
    //end of new code

    Timeline timeline = new Timeline(
            new KeyFrame(
                    Duration.seconds(2),
                    new KeyValue(line.translateYProperty(), 600)
            ));
    timeline.setCycleCount(Animation.INDEFINITE);
    timeline.setAutoReverse(false);
    timeline.play();

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

}

【讨论】:

  • 您不应在 JavaFX 应用程序线程之外查询活动场景图中节点的属性(这将导致race conditions)。相交检查应在Platform.runLater call 中执行。或者,更好的是,应该用AnimationTimer 替换自定义线程,并且应该在计时器的handle() 方法内完成检查。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 2019-01-24
  • 1970-01-01
  • 2015-05-11
  • 1970-01-01
  • 2011-09-28
  • 2018-04-06
相关资源
最近更新 更多