0

/I need to determine if a pair of lines defined by multiple line segments intersects, for example a line defined by (0,0), (1,2), (3,1) and another by (0,2), (2,-1), (4,1).

I do not need to determine where the intersection is, but I need an efficient method because I can have a very large number of edges. I am using the below code to determine if two segments intersect, but that is inefficient for a line of larger lengths. Furthermore, the lines are edges in a graph and they are constrained to a known maximum length.

static bool IsOnSegment(float xi, float yi, float xj, float yj,
                    float xk, float yk) {
  return (xi <= xk || xj <= xk) && (xk <= xi || xk <= xj) &&
     (yi <= yk || yj <= yk) && (yk <= yi || yk <= yj);
}

static char ComputeDirection(float xi, float yi, float xj, float yj,
                         float xk, float yk) {
  float a = (xk - xi) * (yj - yi);
  float b = (xj - xi) * (yk - yi);
  return a < b ? -1 : a > b ? 1 : 0;
}

// Do line segments (x1, y1)--(x2, y2) and (x3, y3)--(x4, y4) intersect? /
bool DoLineSegmentsIntersect(float x1, float y1, float x2, float y2,
                         float x3, float y3, float x4, float y4) {
char d1 = ComputeDirection(x3, y3, x4, y4, x1, y1);
char d2 = ComputeDirection(x3, y3, x4, y4, x2, y2);
char d3 = ComputeDirection(x1, y1, x2, y2, x3, y3);
char d4 = ComputeDirection(x1, y1, x2, y2, x4, y4);
return (((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) &&
      ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0))) ||
     (d1 == 0 && IsOnSegment(x3, y3, x4, y4, x1, y1)) ||
     (d2 == 0 && IsOnSegment(x3, y3, x4, y4, x2, y2)) ||
     (d3 == 0 && IsOnSegment(x1, y1, x2, y2, x3, y3)) ||
     (d4 == 0 && IsOnSegment(x1, y1, x2, y2, x4, y4));
}
  • 3
    possible duplicate of [How do you detect where two line segments intersect?](http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect) – hivert Jul 17 '13 at 15:17
  • That question gave me the functions to determine if two single segments intersect, but I need to consider a path of segments and finding intersections with another path. – Colin Hines Jul 17 '13 at 18:19
  • *a line defined by (0,0), (1.2) and (3,1)*; is this the union of 2 line segments or a triangle? – user5402 Jul 17 '13 at 21:09
  • It's a path (union of line segments) that goes through the points in the order. – Colin Hines Jul 17 '13 at 22:59

1 Answers1

0

You would slightly change Bentley-Ottmann Algorithm which computes all k intersections in O((n+k)logn) time and O(n+k) space.

Proposed modification - Bentley-Ottmann Algorithm gets set of segments and reports all intersections. You would split your segmented lines to set of segments and give this set as the input to algorithm. When some intersection is found just check whether intersecting segments belong to the same segmented line or not. If not it means you've just found intersection of segmented lines.

Please, note that in worst case complexity will be O(n^2) when number of intersections is very large. The worst case for you is two segmented lines which look like intertwining snakes. Remember that there are at least O(N) pseudo-intersections - each segmented line will produce O(length) pseudo-intersections and as lenght1+lenght2 = N, where N is total number of segments, there are O(N) pseudo-intersections. Pseudo-intersection is such intersection that will be detected by Bentley-Ottmann Algorithm but shouldn't be taken to account.

Implementation hints - Bentley-Ottmann Algorithm based on sweep line algo which is based on sorting points - pairs of (X,Y). Now you should just sort triples (X,Y,segmentsLineID). In your case all triples would be (X,Y,1) or (X,Y,2)