检查数千个矩形是否相交

时间:2016-10-04 10:24:02

标签: java bukkit rectangles

我目前正在使用Bukkit插件来声明自定义区域,并且我在创建声明之前使用矩形(和.intersect())检查区域是否重叠。

我试图找到一种方法,我不需要检查每一个现有的声明(其中最终会有数万个),因为这肯定需要相当长的时间。当玩家执行诸如休息区或地块等事情时,我还需要检查索赔所有者。

在我目前的系统中(不允许自定义索赔规模,只有正方形)我只需要检查最多约10件索赔,因为我可以检测索赔附近的索赔(最多64个街区以外是这个系统中索赔的最大半径)但是现在理论上的索赔大小在新系统中可以无限大。

检查所有矩形会花费大量时间吗?我是否愚蠢,有没有办法检查附近的矩形,即使尺寸无限制?

2 个答案:

答案 0 :(得分:1)

首先检查数以千计的矩形对于java(或你的插件)来说不是什么大问题。它的简单数学运算应该以毫秒为单位。处理你的主人问题我建议你创建我自己的矩形和所有者类。因此,您的矩形可以拥有一个已定义的所有者,您只需检查该玩家是否是他现在所在区域的所有者。

public class custom_Area extends Rectangle{

    private owner o;

    public owner getOwner() {
        return o;
    }

    public void setOwner(owner o) {
        this.o = o;
    }    
}

编辑:

我刚刚通过创建100.000个随机矩形并检查其中一个是否与其他矩形相交来测试它。

- 自定义矩形类

public class area extends Rectangle{
private owner o;
public area(owner o, int i, int i1, int i2, int i3) {
    super(i, i1, i2, i3);
    this.o = o;
}
public owner getO() {
    return o;
}
public void setO(owner o) {
    this.o = o;
}

}

- 自定义所有者类

public class owner {
String name;

public owner(String name) {
    this.name = name;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}

}

- 主要课程

public class Rectanglesearch {
        public static area a[] = new area[100000];
        public static owner o[] = new owner[10];
        public static int intersectCounter = 0;
        public static int ownerCounter = 0;

    public static void main(String[] args) {
        for(int y = 0; y<10;y++){
        o[y] = new owner("y");
        }
        for (int i = 0; i < 100000; i++) {
            a[i] = new area(o[(int)(Math.random() * 10)],random(),random(),random(),random());
        }
        checkArea(a[10]);
        checkOwner(o[3]);
        System.out.println("Area a[10] intersects with "+intersectCounter+" out of "+a.length);
        System.out.println("Owner o[3] owns "+ownerCounter+" areas out of "+a.length);
    }
    public static int random(){
    return (int)(Math.random() * 100000) + 1;
    }
    public static void checkArea(area ab){
            for (area a1 : a) {
                if (ab.intersects(a1)) {
                    intersectCounter +=1;
                }
            }
    }
    public static void checkOwner(owner ob){
            for (area a1 : a){
                if(a1.getOwner()==ob){
                    ownerCounter +=1;
                }
            }
    }
}

方法checkArea(区域ab)返回man区域与区域ab相交的方式 方法checkOwner(所有者ob)返回man区域如何拥有我的ob

答案 1 :(得分:1)

考虑将矩形存储在加速结构中,例如quadtree。要针对现有集测试新矩形,您将向下导航到包含它的节点,沿着每个节点测试矩形,但忽略所有未遍历的节点中的矩形。这很快就消除了许多不可能与新的矩形相交的矩形,而无需单独测试每个矩形。

其他加速结构也可以作为替代,例如binary space partitioning。阅读spatial indexes,了解可能相关的其他几个列表。

添加新的矩形不会经常发生,所以性能可能不是一个大问题。但我想你的插件还需要检查一个特定的坐标(例如一个块)是否在一个声明的区域内,并且可能更频繁地发生 - 可能每一帧 - 所以它确实需要快速。四叉树或其他加速结构对此有价值。