13

I need to find whether two lines overlap each other. I have the intersection code which returns 0, if two lines are parallel. But then I need to know if these two parallel lines overlap.

Edit:

A                    C       B                D
-----------------------------------------------

Line 1: A-B

Line 2: C-D

I need to find if Line 1 overlaps Line 2, but both lines can have a slope > 0.

Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
user2483744
  • 283
  • 1
  • 5
  • 11
  • i would think you could find it mathematically using starting and stopping points along with the slope – Jonesopolis Jun 17 '13 at 13:43
  • could you define Overlap, do you mean overlaps on x or Y plane or overlaps on Vector adjusted plane? assuming that by overlap you mean contains the same vertical or horizontal line as two parallel lines will never cross each other – RoughPlace Jun 17 '13 at 13:49
  • This might be relevant: http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect – Matthew Jun 17 '13 at 13:49
  • do not think intersection is relevant as 2 parallel lines will never intersect and we have already determined that they are parallel – RoughPlace Jun 17 '13 at 13:52
  • 1
    It would help to know if your line segments have their points ordered in a certain way, i.e. is the first point always on the left, or is it variable ? – A.R. Jun 17 '13 at 13:52
  • Please the edit in the question. – user2483744 Jun 17 '13 at 14:00
  • check if they have the same slope - if they do then they are in parallel. If they are in parallel check if any of the points are the same. – Jonesopolis Jun 17 '13 at 14:44
  • Are your line segments "closed" or "open"? That is, do they included the endpoints? If they do, do you consider a line segment where the endpoints are equal valid? – jerry Jun 24 '13 at 13:07

9 Answers9

22

You can compare to find if there is no over lap. you will have less comparisons in this way thus very efficient. Do following comparisons

D < A

B < C

If either case is true the lines are not overlapping. otherwise there must an overlap. You will make least number of comparisons to determine if they are not overlapping. Otherwise there will be more comparisons to make.

Kishore
  • 403
  • 4
  • 11
  • 1
    Only true for 1D case, but it's exactly what I was looking for – Mikhail May 12 '18 at 07:29
  • You can convert this to check for collision using De Morgan's Law, making it `B >= C && A <= D`. More on De Morgan's Laws: https://en.wikipedia.org/wiki/De_Morgan's_laws – Caleb Bertrand Feb 19 '23 at 23:46
2

Since you know they're both parallel, then just check whether line segment CD contains either of the endpoints of the first line (point A and point B).

Harrison Paine
  • 611
  • 5
  • 14
  • 1
    This is a **sufficient** but not **necessary** condition. Consider the case where the entire segment CD overlaps a portion of AB (such as the intervals [0,3] and [1,2]). There's an easy enough fix, but it starts to get a little messy if you consider trying to actually construct the overlap (rather than just determining if one exists). – jerry Jun 17 '13 at 16:37
1

For two co-linear line segments that are not necessarily axis-aligned:

  1. Sort the vertices in clockwise order around the origin.
  2. The lines overlap if the ordered vertices alternate between the two segments, e.g. Line1.Point1, Line2.Point1, Line1.Point2, Line2.Point2.
Community
  • 1
  • 1
mbeckish
  • 10,485
  • 5
  • 30
  • 55
  • It doesn't work for me: many false positives. I copied the code from the link and implemented the trivial sort and decision code. – ceztko Feb 26 '14 at 23:27
  • @ceztko - Can you give an example of two segments that result in a false positive? Give the coordinates of the points, or maybe draw a picture? – mbeckish Feb 27 '14 at 03:32
  • If I find the time to set up the code again, I will. Of course may attempt may have had a bug. I upvoted your answer because you lead me to the right direction anyway: collinearity can be tested very easily and with much less operations, and I already had the code for that. Look at my answer. – ceztko Feb 27 '14 at 22:47
  • Now I see the problem: I was misunderstanding your answer as I thought you were also testing for collinearity. For your overlapping test: should I sort vertices arond the origin, as you write, or around segment points center of mass? Also: is this solution stable also for vertical/near vertical segments? – ceztko Feb 28 '14 at 14:35
  • @ceztko - Whatever point you pick as the origin, this solution will fail if the segments are also co-linear with the origin. Other than that, I think it should work for any choice of origin. – mbeckish Feb 28 '14 at 14:37
  • still it looks a bit overcomplicated. what about a test that: 1) ensures collinearity, 2) checks for endpoints being within interior of the other segment? Code at http://pastebin.com/7Cdyeu3N – ceztko Feb 28 '14 at 15:51
1

It is sufficient to calculate the areas of triangles ACB and CBD. If the area is 0, then the points are collinear, and if both areas are zero then the lines are overlapping.

You can calculate the area of a triangle ABC by this formula:

2*Area(ABC)= (bx – ax)(cy – ay) – (cx – ax)(by – ay);

1

Line equation is direction of line in infinite, by finding slope or intercept you wont be able do anything with them(even though horizontal line doesn't have slope), i suggest use point on line. so AB is your line [(x,y),(x,y)] and C is on of the point (x,y) and then you need to check if point on the line.
Check Point On a Line

Bear
  • 550
  • 9
  • 25
0

We are given two line segments

AB = line segment from (Ax,Ay) to (Bx,By)
CD = line segment from (Cx,Cy) to (Dx,Dy)

with the same slope.

  • Order the endpoints E1 < E2 < E3 < E4 such that Ei,x ≤ Ei+1,x and Ei,y ≤ Ei+1,y if Ei,x = Ei+1,x
  • If E1 and E2 are from different segments, the overlap is the segment from E2 to E3.

There are some degenerate cases:

  • A < B = C < D
  • A < C = D < B
  • A < B = C = D
  • A = B = C = D

These result in a single point of intersection. I'm not sure if any of those can occur in your system, but if so you'll have to decide whether or not you consider that "overlap" and add special case checks.

jerry
  • 2,581
  • 1
  • 21
  • 32
0

The characteristic of two segments of being in the same lines is called collinearity and can be tested calculating the area of the 2 triangles formed by one segment endpoints and, respectively, the endpoints of the other segment. If the area is zero or close to zero below a threshold the segments are collinear.

    public static bool AreSegmentsCollinear(Segment a, Segment b, double epsilon)
    {
        return IsPointCollinear(a, b.Left, epsilon) && IsPointCollinear(a, b.Right, epsilon);
    }

    public static bool IsPointCollinear(Segment a, Vector2D p, double epsilon)
    {
        return Math.Abs(GetSignedTriangleArea2(a, p)) <= epsilon;
    }

    /// <returns>The squared signed area of the triangle formed with endpoints
    /// of segment a and point p</returns>
    public static double GetSignedTriangleArea2(Segment a, Vector2D p)
    {
        return (p - a.Left) ^ (a.Right - a.Left);
    }

   /// <summary>Cross product of vectors in 2D space. NB: it returns a
   /// magnitude (scalar), not a vector</summary>
   /// <returns>The area of the parallelogram formed with u, v as the edges</returns>
   public static Double operator ^(Vector2D u, Vector2D v)
   {
       return u.X * v.Y - u.Y * v.X;
   }
ceztko
  • 14,736
  • 5
  • 58
  • 73
  • Checking for collinearity is only half the problem (which I missed in my answer - I misread the problem and thought that he already had a test for collinearity). The other half is my answer - once you determined they are co-linear, you need to see if they overlap. – mbeckish Feb 28 '14 at 02:22
  • The question is not very clear, indeed: eventually I ended understasting he was asking for collinearity. – ceztko Feb 28 '14 at 13:49
0

Just to be clear since there seems to be some confusion in the answers, the question being asked is as follows. Given two 2D line segments A and B how do I determine if both of the following are true:

  1. A and B are colinear.
  2. A and B intersect.

Note that there are tolerances involved in both questions i.e. how close to parallel and how near each other do A and B need to be to be considered colinear? How much do they need to overlap to be considered overlapping?

I think to handle such tolerances robustly the best algorithm is to treat the line segments as thin rectangles, where the thickness of the rectangles is a tolerance parameter t1. Let t2 be another tolerance parameter on slopes that are considered parallel. Then the algorithm becomes

  1. If the slope of A and the slope of B are not within t2 of each other return false. To handle vertical lines cleanly, slope can be represented as a unit vector and the test can be on whether the Euclidean distance between the two unit vectors is smaller than t2.

  2. Represent A and B as (non-axis-aligned) rectangles R1 and R2. Where R1 encloses A in the obvious way, i.e. it is length(A) + t1 units long and is t1 units wide with A centered inside it, and R2 analogously encloses B.

  3. Determine if R1 and R2 intersect each other. This can be done relatively efficiently by treating each rectangle as the union of two triangles and testing for triangle-triangle intersections across all combinations of A triangles and B triangles. If there is an intersection return true; otherwise return false.

jwezorek
  • 8,592
  • 1
  • 29
  • 46
0

With lines l1 and l2 given in the following form [x1, y1, x2, y2] the following python code will give the intersection for collinear line segments with any slope.

intersection = line_intersect(l1, l2)
def line_intersect(l1, l2):
    """Find the intersection of two line segments"""
    
    x1, y1, x2, y2 = l1
    x3, y3, x4, y4 = l2
    
    x_inter = component_intersect(x1, x2, x3, x4)
    y_inter = component_intersect(y1, y2, y3, y4)
    
    return math.sqrt(x_inter**2 + y_inter**2)
    
def component_intersect(c1, c2, c3, c4):
    """Calculate intersection in one dimension/component"""
    
    # find left endpoints
    cl1 = min(c1, c2)
    cl2 = min(c3, c4)
    
    # find right endpoints
    cr1 = max(c1, c2)
    cr2 = max(c3, c4)
    
    # find endpoints of intersection
    c_inter_l = max(cl1, cl2)
    c_inter_r = min(cr1, cr2)
    # calcuate intersection
    c_inter = c_inter_r - c_inter_l
    c_inter = max(c_inter, 0)
    
    return c_inter
Waylon Flinn
  • 19,969
  • 15
  • 70
  • 72