在Java中计算多个2D形状的交集

时间:2013-12-07 21:06:21

标签: java algorithm geometry shape intersection

请注意我对使用任何第三方JAR或AWT作为此解决方案的一部分不感兴趣。我正竭尽所能保持我的项目无依赖性,我想保持这种方式。而且,如果JRE随附任何可以解决此问题的类,我仍然对这里的自定义解决方案感兴趣,这样我就能真正理解数学,而不是盲目地进行一些API调用。

我有各种形状的POJO结构:

public class Coordinate {
    private Double xVal;
    private Double yVal;

    // Constructors, getters/setters, etc.

    public static Double distance(Coordinate c1, Coordinate c2) {
        // Calculates the Cartesian distance between c1 and c2 using the standard
        // distance formula.
    }
}

public abstract class Shape {
    // Some properties inherent to all 2D shapes.

    public abstract Double calcArea();
    public abstract Double calcPerimeter();
}

public class Rectangle extends Shape {
    private Coordinate upperLeft;
    private Coordinate upperRight;
    private Coordinate lowerLeft;
    private Coordinate lowerRight;

    // Constructors, overrides, getters/setters, etc.
}

public class Circle extends Shape {
    private Coordinate center;
    private Double radius;

    // Constructors, overrides, getters/setters, etc.
}

现在,我将获得List<Shape>(包含0 + Rectangle和0 + Circle s的混合集。我需要确定此列表中的任何形状是否相互交叉(true或false):

public boolean intersectionsExist(List<Shape> shapes) {
    // ???
}

我想在这里实现最佳实践,所以我不知道是否已经有任何算法(可能)有几十种形状。我在SO和网上找到的所有“交叉检测”代码片段都在两种形状之间。但如果列表中有3个矩形和7个圆圈怎么办?!?

我的想法是遍历列表中的每个Shape,并将其与其他Shape进行比较(因此二次解决方案,我对此不感兴趣)。但是那样,我发现true的那一刻我可以回复Shape

至于检测实际的交叉路口,我想知道是否有什么我可以做的,像维恩图一样对待这些形状。意思是,以某种方式确定一个形状是否重叠另一个形状。但至于我如何确定“重叠”,我不知道。

所以有几个问题:

  1. 是否有任何标准算法用于检测3种形状之间的交叉点?如果是这样,有人可以给我一些链接/信息吗?
  2. 如果上面#1的答案是“否”,那么我的二次解决方案是最好的方法(双嵌套for - 循环比较每个Shape,并返回找到一个交叉点时true)?或者有更好/更有效的方式吗?
  3. 最重要的是:如何检测实际的交叉路口?是否有标准算法来完成此任务(链接?)?有人可以提供一个代码示例(使用我上面的POJO),或者甚至给出一个简单的伪代码示例,说明我在这里可以做些什么?
  4. 提前致谢!

3 个答案:

答案 0 :(得分:3)

您的问题通常称为Constructive Solid Geometry。查阅维基百科和/或关于计算机图形学的标准书籍,但请不要指望将这些复杂的东西作为现成的答案。

答案 1 :(得分:1)

碰撞检测有各种解决方案。您可以在大量对象中处理检测,就像现代游戏及其数千种模型一样,但您只能一次比较两个项目的碰撞

最快且最简单的代码选项是使用包含对象的圆圈(如果对象是圆形的话非常容易)并使用距离测试。如果两个圆的中心点之间的距离小于它们的组合半径,那么它们就会发生碰撞。

此选项有一些缺点,例如矩形对象上的圆圈会在未绘制矩形的某些区域(如果圆圈大于矩形)发生碰撞,或者在某些时候不会发生碰撞(如果圆圈小于矩形)。

你可以看到的其他一些东西是轴对齐边界框或n-DOP碰撞,这两种情况在数学上都比较密集。这是一个很好的general collisions tutorial

如果你想变得非常复杂和肮脏,这里有一种称为SAT(分离轴定理)的方法http://www.metanetsoftware.com/technique/tutorialA.html

答案 2 :(得分:-1)

如果您对交叉理论感兴趣,可以在普林斯顿的Chazelle和Dobkin的论文中分析问题。这篇论文太长了,无法在此总结,但它提供了一个带有证据的冗长的逐步算法。您仍然需要自己编写算法代码。但是,OP 确实要求提供链接和/或引用。

Chazelle,B。和Daniel P. Dobkin。 Intersection of Convex Objects in Two and Three Dimensions 的。普林斯顿,新泽西州:普林斯顿大学,计算机科学系,1986年。网络。功能