1
votes

I would rather not use any third party JARs or AWT as part of this solution. I am doing everything in my power to keep my project dependency-free. And, if the JRE ships with any classes that solve this for me, I'm still interested in a custom solution here so that I can really understand the mathematics and not just blindly make a few API calls.

I have the following POJO structure for various shapes:

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.
}

Now then, I will be given a List<Shape> (mixed set containing 0+ Rectangles and 0+ Circles). I need to determine if any of the shapes in this list intersect with each other (true or false):

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

I'd like to implement best practices here, so I don't know if there is already any algorithm to do this with (potentially) dozens of shapes. All the "intersection detection" code snippets I've found on SO and on the web have been between exactly 2 shapes. But what if I have 3 rectangles and 7 circles in the list?!?

My thinking is to iterate through each Shape in the list, and compare it with every other Shape (hence a quadratic solution, which I'm not thrilled about). But that way, I could return true the instant I find a Shape that intersects with another.

As for detecting the actual intersection, I am wondering if there is anything I can do that treats these shapes like a Venn diagram. Meaning, somehow determine if one shape is overlapping another. But as to how I could determine "overlap", I have no idea.

So several questions:

  1. Are there any standard algorithms out there for detecting intersections among 3+ shapes? If so, can someone please give me some links/info on them?
  2. If the answer to #1 above is "no", then is my quadratic solution above the best way to go (double-nested for-loops comparing each Shape to every other, and returning true when one intersection is found)? Or is there a better/more efficient way?
  3. Most importantly: how to detect the actual intersections? Are there standard algorithms to accomplish this (links?)? Can someone provide a code example (using my POJOs above), or even give a simple pseudo-code example of what I could do here?
3
1. No, you can only detect the intersection of 2 shapes. 2. Your quadratic solution is the best. If you have 10 objects, that's less than 100 intersection tests. You don't test the intersection of Shape A with Shape A. 3. Use the intersects (and contains) methods of Shape. Shape is an interface, so Shape will pick the concrete intersects (and contains) methods to use.Gilbert Le Blanc
Thanks @GilbertLeBlanc (+1) - what lib is "Shape" a part of? Can you provide a link to its Javadoc? Once I know where to find the source code, I'll sift around it for a bit and see if I can find the actualy "intersects" algorithm. Thanks again!IAmYourFaja

3 Answers

3
votes

Your problem is commonly called Constructive Solid Geometry. Lookup Wikipedia and or a standard book about computer graphics but please don't expect working code about this complex stuff as a ready-to-use answer.

2
votes

There are varying solutions for collision detection. You can handle detection within a huge array of objects, as with modern games and their thousands of models, but you are only ever comparing collision for two items at a time

The fastest and simplest-to-code option is to use circles that encompass your objects(very easy if your object is circular) and use a distance-between test. If the distance between the two circles' center points is less than their combined radii, then they are colliding.

This option has some drawbacks, such as a circle on a rectangular object will either collide in some areas where the rectangle isn't drawn(if the circle is larger than the rect) or won't collide at some times it should(if the circle is smaller than the rect).

Some other things you can look at are Axis-Aligned Bounding Boxes or n-DOP collision, both of which are somewhat more mathematically intensive. Here's a good general collisions tutorial

If you want to get extremely complicated and mathy, here is a method known as SAT(Separating Axis Theorem) http://www.metanetsoftware.com/technique/tutorialA.html

-1
votes

If you're interested in the theory of intersections, there is an analysis of the problem in a paper by Chazelle and Dobkin of Princeton. The paper is too long to summarize here, but it provides a lengthy step-by-step algorithm with proofs. You would still need to code the algorithm yourself. However, the OP did ask for links and/or references.

Chazelle, B., and Daniel P. Dobkin. Intersection of Convex Objects in Two and Three Dimensions. Princeton, NJ: Princeton U, Dept. of Computer Science, 1986. Web.