java - 验证一个形状是否在另一个形状内的算法 - javafx

标签 java algorithm javafx

我有一个矩形和一个圆形。我需要验证该圆圈内是否有一个矩形。

我尝试了 Shape.intersects,但 intersects 被检查为数字 1。

有人知道javafx中的这种算法吗?

举例说明,图中只有1、2、3、4矩形在圆内。

感谢您的帮助。

enter image description here

最佳答案

解决方案

此解决方案背后的基本思想是,任何多边形都包含在任何(见评论)形状内,前提是多边形内的每个点都在形状内。如果多边形的至少一个点在形状内,则您尝试使用的intersects() 方法返回true。您已经知道它会起作用,但它还会为任何部分相交的形状提供误报。为了解决这个问题,我们定义了自己的交叉测试,它会查看所有点。

这可以概括为扫描任何给定的多边形以寻找具有任何给定形状的“总交集”:

public boolean totalIntersects(Polygon poly, Shape testShape) {
    List<Point> points = flatDoublesToPoints(poly.getPoints());
    boolean inside = true; // If this is false after testing all points, the poly has at least one point outside of the shape.
    for(Point point : points) {
        if(!testShape.intersects(point.x, point.y, 1, 1)) { // The 3rd and 4th parameters here are "width" and "height". 1 for a point.
            inside = false;
        }
    }
    return inside;
}

其中 flatDoublesToPoints()Point 定义为:

private List<Point> flatDoublesToPoints(List<Double> flatDoubles) {
    List<Point> points = new ArrayList<>();
    for(int i = 0; i < flatDoubles.size(); i += 2) {
        points.add(new Point(flatDoubles.get(i), flatDoubles.get(i + 1)));
    }
    return points;
}

class Point {
    public double x, y;
    
    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }
}

flatDoublesToPoints() 需要将“扁平”{x1, y1, x2, y2, x3, y3...} 多边形列表拆分成更简单的- 了解数据结构。但是,如果您要进行大量比较,跳过此步骤并出于内存原因直接对“平面列表”进行操作可能会有所帮助。

申请

以下将其他方法应用于与您极为相似的情况。 (不准确,因为我没有你的代码。)

public class Main extends Application {
    
    public static final int SIZE = 600;
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        Pane rootPane = new Pane();

        List<Rectangle> rects = new ArrayList<>();
        for (int j = 0; j < 2; j++) {
            for(int i = 0; i < 5; i++) {
                Rectangle r = new Rectangle(i * 100, j == 0 ? 0 : 300, 100, 200);
                r.setFill(Color.BEIGE);
                r.setStroke(Color.BLACK);
                rects.add(r);
            }
        }
        rootPane.getChildren().addAll(rects);
    
        Circle circle = new Circle(350, 100, 200);
        circle.setStroke(Color.BLACK);
        circle.setFill(null);
        rootPane.getChildren().add(circle);
    
        List<Polygon> polys = new ArrayList<>();
        for(Rectangle rect : rects) {
            polys.add(rectangleToPolygon(rect));
        }
        List<Polygon> intersects = getTotalIntersections(polys, circle);
        System.out.println(intersects);
        
        primaryStage.setScene(new Scene(rootPane, SIZE, SIZE));
        primaryStage.show();
    }
    
    public List<Polygon> getTotalIntersections(List<Polygon> polys, Shape testShape) {
        List<Polygon> intersections = new ArrayList<>();
        for(Polygon poly : polys) {
            if(totalIntersects(poly, testShape)) {
                intersections.add(poly);
            }
        }
        return intersections;
    }
    
    public static Polygon rectangleToPolygon(Rectangle rect) {
        double[] points = {rect.getX(), rect.getY(),
                            rect.getX() + rect.getWidth(), rect.getY(),
                            rect.getX() + rect.getWidth(), rect.getY() + rect.getHeight(),
                            rect.getX(), rect.getY() + rect.getHeight()};
        return new Polygon(points);
    }
    
    public static void main(String[] args) {
        Main.launch(args);
    }
}

此代码将打印以下内容:

[Polygon[points=[200.0, 0.0, 300.0, 0.0, 300.0, 200.0, 200.0, 200.0], fill=0x000000ff], Polygon[points=[300.0, 0.0, 400.0, 0.0, 400.0, 200.0, 300.0, 200.0], fill=0x000000ff], Polygon[points=[400.0, 0.0, 500.0, 0.0, 500.0, 200.0, 400.0, 200.0], fill=0x000000ff]]

标记为 2、3 和 4 的三个多边形是什么。

关于java - 验证一个形状是否在另一个形状内的算法 - javafx,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39553446/

相关文章:

amazon-web-services - 仅使用 replaceAll ("\r", "_".replaceAll ("\n", "_"传递 Veracode CWE 117(日志的不正确输出中和)

java - Hash Map 中的 getEntry() 方法使用了冗余的 Object 引用

java - 使用 Java 计算 11^-1 mod 26

java - android 媒体播放器中的完成监听器

java - 使用 linkedList 的合并排序无法正常工作 - 在 Java 中实现

algorithm - k近邻算法应该使用数字0-9的二值图像的哪些特征?

java - 更新到 gradle 3.3 后构建失败

algorithm - 使用贪婪耐心排序证明最长递增子序列

java - 如何从 fxml 文件中的 xml 文件读取值?

java - 向 Java BooleanProperty 类添加自定义方法