JavaFX形状和多边形的交集

3
我目前正在使用JavaFX处理不同形状的交集范围。我想在它们的点上检测两个多边形的碰撞,而不是在它们的范围上(即2个多边形)。
请参见图1:不希望的行为,和图2:期望的行为。
有没有现成的算法或库可以帮助我?
谢谢! :)
以下是我的解决方案:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;

public class Tester extends Application {

@Override
public void start(Stage stage) throws Exception {
    Pane root = new Pane();
    root.setStyle("-fx-background-color:cyan;");
    Polygon p1 = new Polygon();
    p1.getPoints().addAll(new Double[]{
            50.,50.,
            50.,100.,
            60.,100.,
            60.,80.,
            80.,70.,
            80.,100.,
            100.,100.,
            100.,50.
    });
    p1.setFill(Color.GREEN);

    Polygon p2 = new Polygon();
    p2.getPoints().addAll(new Double[]{
            65.,100.,
            65.,90.,
            75.,80.,
            100.,100.
    });
    p2.setFill(Color.RED);

    root.getChildren().addAll(p1,p2);

    stage.setScene(new Scene(root));
    stage.show();

    Shape inter = Shape.intersect(p1, p2);
    root.getChildren().add(inter);

    System.out.println(inter.getLayoutBounds().getWidth() + ":" + inter.getLayoutBounds().getHeight());
    if(inter.getLayoutBounds().getHeight()<=0 || inter.getLayoutBounds().getWidth()<=0) {
        System.out.println("No intersection");
    }
    else {
        System.out.println("intersection detected");
    }
}

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

输出:

enter image description here

20.0:16.0 检测到交叉点

看起来它正常工作,我将使用路径对象替换多边形对象进行测试。


你可能想检查一个多边形的边缘交点是否在另一个多边形的范围内。使用:mypolygon1.getBoundsInLocal().contains(myPolygon2.getBoundsInLocal()) - Aspirant
@user 我测试过了,但是它是图1的情况。 - PacDroid
jewelsea的答案最适合你。 - Aspirant
我测试了Shape.intersect(...);,看起来没问题。我更新了我的示例。 - PacDroid
2个回答

1
我在尝试你的代码时,发现了这个解决方案,我给 polygon2 添加了鼠标事件,然后修改了 if 语句。如果还来得及的话,请尝试一下。
public class Tester extends Application {

    Shape inter;
    Point2D pc;
    double initX, initY, mx, my;

    @Override
    public void start(Stage stage) throws Exception {
        Pane root = new Pane();
        root.setStyle("-fx-background-color:cyan;");
        final Polygon p2 = new Polygon();
        final Polygon p1 = new Polygon();
        p1.getPoints().addAll(new Double[]{
            50., 50.,
            50., 100.,
            60., 100.,
            60., 55.,
            80., 70.,
            80., 100.,
            100., 100.,
            100., 50.
        });
        p1.setFill(Color.GREEN);
        p2.getPoints().addAll(new Double[]{
            65., 100.,
            65., 45.,
            75., 80.,
            100., 100.
        });

        p2.setFill(Color.RED);

        p1.setTranslateX(400);
        p1.setTranslateY(250);

        p2.setOnMousePressed(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent me) {
                initX = p2.getTranslateX();
                initY = p2.getTranslateX();
                pc = new Point2D(me.getSceneX(), me.getSceneY());
            }
        });

        p2.setOnMouseDragged(new EventHandler<MouseEvent>() {
            public void handle(MouseEvent me) {
                double dragX = me.getSceneX() - pc.getX();
                double dragY = me.getSceneY() - pc.getY();
                double newXPosition = initX + dragX;
                double newYPosition = initY + dragY;
                p2.setTranslateX(newXPosition);
                p2.setTranslateY(newYPosition);
                System.out.println("no intersection");
                if (Shape.intersect(p2, p1).getBoundsInLocal().isEmpty() == false) {
                    p1.setTranslateX(p2.getTranslateX() + mx);
                    p1.setTranslateY(p2.getTranslateY() + my);
                    System.out.println("colision");

                } else {
                    mx = p1.getTranslateX() - p2.getTranslateX();
                    my = p1.getTranslateY() - p2.getTranslateY();
                }

            }
        });
        root.getChildren().addAll(p1, p2);

        final Scene scene = new Scene(root, 1200, 850);
        stage.setScene(scene);
        stage.show();
    }

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

0
如果您的应用程序可以使用java.awt.geom包,我建议您查看Area类,特别是intersect方法。
基本上,您可以这样做:
area1.intersect(area2);
boolean areasintersect = !area1.isEmpty();

您可以使用同一包中的GeneralPath类创建任意区域。


不好意思,如果可能的话,我想只使用JavaFX。 我现在正在深入研究交集方法,但还是谢谢您。 - PacDroid
我有一个关于这个问题的疑问:是否可以将java.awt.geom Area类转换为JavaFx多边形?我想将一个Swing应用程序转换为JavaFx。谢谢。 - Davem M
@DavemM 我会说这是一个新问题。但是答案可能是:只有当区域描述多边形时,您才会使用getPathIterator迭代形状并创建FX多边形。 - Sebastian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接