computational geometry

1D segment intersection detection part 2

After the part 1 of the tutorial, part 2 is born to kill.

I have one small tweak for the naive method, in theory, it will can only speed up the detection. so if your segments are always in extreme condition and keep running to the worst case for the previous algorithm, with this one you can't lose much.

Sort set B and compare with set A, but this time, If a x1 for one segment in set B is larger than the x2 in a set A segment, break the loop because all the x1's after that segment will have larger x1 values.
Just change following part in the original code:

for(i=0;i<size;++i){
    for(n=0;n<size;++n){
        if(b[n].x1<=a[i].x2 && a[i].x1<=b[n].x2)
        {
            ++counter;
            }
    }
}

to

for(i=0;i<size;++i){
    for(n=0;n<size;++n){
        if(b[n].x1<=a[i].x2)
        {
 		if(a[i].x1<=b[n].x2){
            		++counter;
		}
        }else{
        	break;
	}
    }
}

This code is usually good enough for most detections you will ever use if you use it to create a game(unless you have 20000 3D objects flying around).

To extend the 1D segment detection to 2D axis aligned bounding rectangle detection. Create a pair of y coordinates and x coordinates for each rectangle. Do the x's and y's separately. When both 1D segments for x and 1D segments for y need intersects, those 2D rectangles intersects. Same for 3D boxes, just add the z coordinates.

When come to databases, advanced algorithms comes to play.

Currently, all the fastest algorithms in this field works with tree structures. I believes the best thing for the 1D problem is the interval tree, a data structure mentioned in both Introduction to Algorithms and Computational Geometry1. While segment tree costs O(nlog(n)) memory, interval tree cost O(n) memory and just as fast.

Quadtree and Octree proven useful in 2D and 3D respectively.

For hardcore n Dimension hyperrectangles intersection detection, try PR-tree, a R-tree variant.

  1. 1. two books completely shatters the idea "Me can understand anything!"

1D segment intersection detection part 1

In a 1D space, find if 2 segments intersect or not is frequenly implemented in simple collision detection. 1D segment intersection detection can be extended into 2D rectangle intersection detection and 3D box intersection detection. Many games have to use these to detect if 2 object intersects. Sometimes, details like how much space is intersected are also essential for many game.

1D segment detection is super easy.
suppose there is a segment a, it have 2 points, one is x1, the other is x2. Then there is segment b, also with 2 points, y1 and y2. x1<=x2 and y1<=y2. Then, if x1<=y2 and y1<=x2, then the 2 segment intersects with each other.
show how two segment intersects

The function in both C++ and PHP

function intersectsegment($a,$b){
if($a[0]<=$b[1]&&$a[1]>=$b[0]){
return 1;
}
return 0;
}
struct segment{
int x1, x2;
};
int intersectsegment(segment a, segment b){
if(a.x1<=b.x2&&a.x2>=b.x1){
return 1;
}
return 0;
}

In theory, this is the fastest algorithm possible for finding the intersection between 2 segments.

Ahh, what a weak opponent... I don't even have the time to use my powerful algorithms...
Time to tackle what I was here for:
Boss-- Find all the overlaps between set A, a few segments and set B, a huge amount of segments.

The naive idea: loop though each one of the set A segment with each one in set B. Suppose set B have n segments, because set B is a lot larger than A. The naive algorithm runs in Θ(n) time constantly.
The source code for the naive algorithm is on the attachment. For simplicity, I only counted how many intersections there are without returning the intersected segments.

If you test the source code, you will find if you take out

std::sort(b, b+size);

intersection detection will run slower. If anyone know the reason, please comment, thx in advance.

I have a lot more better algorithm. Meet one of them now :)
First sort the array of segments by their smaller value(x1).
Then, create a larger segment outside 2 adjacent smaller segments and create even larger segment covers the 2 large segments. Do the same operations until there is only one large segment left.
The large segments can be created with a function like this:

segment largegment(segment a, segment b){
segment tmp;
tmp.x1 = min(a.x1,b.x1);
tmp.x2 = max(a.x2,b.x2);
return tmp;
}

Start comparing segments in set A with the largest segments in segment B. if overlaps, compare with the 2nd level, then 3rd level until a point where both smaller segments does not overlap or loop till the smallest segments. If a large segment does not overlap, every smaller segments under the large segment is no longer useful.

The running time for best case(no overlap) will be Ω(1), worst case O(n) and most cases, it's Θ(log n).
In worst case, it actually slower than the naive algorithm, since it preform all the calculation in the naive algorithm and to calculate intersect for all the larger segments.

Oh, it's not over, this is only part 1. Some of my algorithmic predator are still waiting to kill its prey...

Syndicate content
Honey Pot that kill bots