JavaFX 形状和多边形的交集

问题描述 投票:0回答:3

我目前正在使用 JavaFX 处理不同形状之间的边界相交。 我想检测两个多边形在其点上而不是在其边界上的碰撞(即 2 个多边形)。

请参阅图 1:不期望的行为,以及图 2:期望的行为。

是否有任何现有的算法可以帮助我或有任何库可以使用? 预先感谢:)

enter image description here

在这里找到我的解决方案:

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
intersection detected

看起来工作正常,我将用 Path 对象替换 Polygon 对象进行测试。

javafx shapes intersect
3个回答
1
投票

如果您可以在应用程序中使用

java.awt.geom
包,我建议您查看
Area
类,尤其是
intersect
方法。

基本上你可以这样做:

area1.intersect(area2);
boolean areasintersect = !area1.isEmpty();

您可以使用同一包中的

GeneralPath
类创建任意区域。


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
投票

看看这个参考 OpenMap-java

示例代码示例:

public static HashMap<AirDefenceZone, BoundingCircle> circleHashMap = new HashMap<>();
public static HashMap<AirDefenceZone, GeoRegion> regionHashMap = new HashMap<>();

public static boolean isPointInside(double lat, double lon, AirDefenceZone zone){
    if(zone == null){
        return false;
    }
    boolean isPointInside = false;
    try {
        Geo geo = new Geo(lat, lon, true);
        if(zone.distance > 1){
            BoundingCircle boundingCircle = circleHashMap.get(zone);
            if(boundingCircle == null){
                boundingCircle = newBoundingCircle(zone);
                circleHashMap.put(zone, boundingCircle);
            }
            isPointInside = boundingCircle.intersects(geo, 0);
        }else{
            GeoRegion geoRegion = regionHashMap.get(zone);
            if(geoRegion == null){
                geoRegion = newGeoRegion(zone);
                regionHashMap.put(zone, geoRegion);
            }
            isPointInside = geoRegion.isPointInside(geo);
        }
    } catch (Exception e) {}
    return isPointInside;
}

private static BoundingCircle newBoundingCircle(AirDefenceZone zone){
    List<Double> doubles = zone.locations.get(0);
    double lon = doubles.get(0);
    double lat = doubles.get(1);
    double radius = zone.distance;
    Geo center = Geo.makeGeoDegrees(lat, lon);
    BoundingCircle boundingCircle = new BoundingCircle.Impl(center, radius);
    return boundingCircle;
}

private static GeoRegion newGeoRegion(AirDefenceZone zone){
    int i = 0;
    double[] poly = new double[zone.locations.size() * 2];
    for(List<Double> doubles : zone.locations){
        double lon = doubles.get(0);
        double lat = doubles.get(1);
        poly[i++] = lat;
        poly[i++] = lon;
    }
    //GeoArray ga = GeoArray.Double.createFromLatLonDegrees(poly);
    GeoRegion reg = new GeoRegion.Impl(poly);
    return reg;
}
© www.soinside.com 2019 - 2024. All rights reserved.