Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ procedure for determining whether two segments intersect

I'm working a bit with computational geometry lately, and I am trying to find a way of checking whether two line segments intersect. I thought that I can use counterclockwise direction (CCW for short) to determine that. Here is my code so far:

struct point { double x, y };

double CCW(point a, point b, point c)
{ return (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x); }

int intersect(point a, point b, point c, point d)
{ return (CCW(a,b,c)*CCW(a,b,d)<0 && CCW(c,d,b)*CCW(c,d,a)<0); }

The above code worked for the test cases I entered, and it's pretty readable and very easy to implement. But after searching on the web, I found an other way of solving the segment intersection problem. The code is similar to mine, but it has some more if statements that my implementation omits. Here is the code:

struct line { point s, e; };

int middle(int a, int b, int c) {
  int t;    
  if ( a > b ) {
    t = a;
    a = b;
    b = t;
  }
  if ( a <= c && c <= b ) return 1;
  return 0;
}

int intersect(line a, line b) {
  if ( ( CCW(a.s, a.e, b.s) * CCW(a.s, a.e, b.e) < 0 ) &&
     ( CCW(b.s, b.e, a.s) * CCW(b.s, b.e, a.e) < 0 ) ) return 1;

  if ( CCW(a.s, a.e, b.s) == 0 && middle(a.s.x, a.e.x, b.s.x) && middle(a.s.y, a.e.y, b.s.y) ) return 1;
  if ( CCW(a.s, a.e, b.e) == 0 && middle(a.s.x, a.e.x, b.e.x) && middle(a.s.y, a.e.y, b.e.y) ) return 1;
  if ( CCW(b.s, b.e, a.s) == 0 && middle(b.s.x, b.e.x, a.s.x) && middle(b.s.y, b.e.y, a.s.y) ) return 1;
  if ( CCW(b.s, b.e, a.e) == 0 && middle(b.s.x, b.e.x, a.e.x) && middle(b.s.y, b.e.y, a.e.y) ) return 1;

    return 0;
}

Could someone explain which is the difference between the two implementations, and which is safer to use? Thanks in advance.

like image 803
Rontogiannis Aristofanis Avatar asked Mar 09 '13 13:03

Rontogiannis Aristofanis


People also ask

How do you find the intersection of two segments?

To find the point at which the two lines intersect, we simply need to solve the two equations for the two unknowns, x and y. Finally, divide both sides by A 1B 2 - A 2B 1, and you get the equation for x. The equation for y can be derived similarly.

How do you know if a line segment intersects?

Given two points on each line segmentThere will be an intersection if 0 ≤ t ≤ 1 and 0 ≤ u ≤ 1. The intersection point falls within the first line segment if 0 ≤ t ≤ 1, and it falls within the second line segment if 0 ≤ u ≤ 1.

What is the intersection of two segments called?

Intersecting Lines Definition Line segments can be measured from one endpoint to the other. Lines and line segments often meet or cross each other at a single point. The point where lines or line segments intersect is called the point of intersection.


1 Answers

The function that you found is also checking the case where the line segments lie within the same line. In that case, it becomes a one-dimensional problem of finding whether the two line segments overlap. Your code would return false in this case. Whether this is preferred or not depends on the application.

Example:

point a={1,0}, b={3,0}, c={2,0}, d={4,0};

intersect(a,b,c,d); // your function will return false, 
                    // but the one you found will return true

The function you found also looks at cases where the endpoint of one line-segment lies along the other line segment:

Example:

point a={1,0}, b={3,0}, c={2,0}, d={2,3};

intersect(a,b,c,d); // your function will return false, 
                    // but the one you found will return true
like image 151
Vaughn Cato Avatar answered Sep 30 '22 01:09

Vaughn Cato