2

OK, here is the problem. I am trying to calculate the intersection of two lines by comparing multiple line segments that are read out of a series of csv files. I've already got the x,y coordinate pairs for each line segment into a list of tuples within tuples as follows:

continuousLine = [((x1,y1),(x2,y2)), ...]
crossingLines = [((x1,y1),(x2,y2)), ...]

Line Problem

I am trying to figure out how to iterate along the continuous line and through the crossing lines to find out where along the continuous line each crossing line intersects.

Basically I want (pseudo-code listed below):

for segment in continuousLine:
    if segment in crossingLines intersect == True:
       return intersection
    else:
       move on to next crossing line segment and repeat test

I hate asking for help on this because I am too new to coding to help other people, but hopefully someone can work through this with me.

I do have a method that I think will work to calculate the intersection once I've figured out the iterator:

line1 = ()
line2 = ()
def line_intersection(line1, line2):
    xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
    ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1]) #Typo was here

    def det(a, b):
        return a[0] * b[1] - a[1] * b[0]

    div = det(xdiff, ydiff)
    if div == 0:
       raise Exception('lines do not intersect')

    d = (det(*line1), det(*line2))
    x = det(d, xdiff) / div
    y = det(d, ydiff) / div
    return x, y

print line_intersection((A, B), (C, D))
haplessgeo
  • 23
  • 4
  • Do you know how to determine the intersection point of two lines, given their end points? If so, [edit] your question and add that. – martineau Aug 19 '16 at 22:53
  • 1
    I do, thanks for the suggestion and see the post edit above. – haplessgeo Aug 19 '16 at 23:28
  • Jolly good—you can see you got a few answers as a result. BTW, I suggest you `raise` a less generic exception, perhaps something specific like `ValueError('lines do not intersect')` because a generic one can hide many other issues (like `SyntaxError` or `KeyboardInterrupt`) which can make code development more difficult, since the caller will have to `except Exception:` to handle cases that don't. – martineau Aug 22 '16 at 17:50

2 Answers2

0

Suppose the function line_intersection would return False on div == 0 instead of raising exeption.

The easy way:

filter(None, [intersection(a, b) for a in continuousLine for b in crossingLines])

However, using nested loop, it is slow when there are lots of segments in crossingLines.

A more efficient way:

To improve performance, have a try on intervaltree, which will give you the intersect candidates for testing. In your case, first build a interval tree on crossingLines, then loop through continuousLine to find intersect candidates in that tree, and test to get the final result.

citaret
  • 416
  • 4
  • 11
0

Since you haven't provided any sample input and expected output, I'm going to use the dummy version of the line_intersection() function shown below. All it does is print its input and returns a hardcoded result — but it will show you how to iterate through the input data and pass it to the real function.

It should be clear from the output what it's doing.

def line_intersection(line1, line2):
    print('intersecting:')
    print('  ({}. {}), ({}, {})'.format(line1[0][0], line1[0][1],
                                        line1[1][0], line1[1][1]))
    print('  ({}. {}), ({}, {})'.format(line2[0][0], line2[0][1],
                                        line2[1][0], line2[1][1]))
    print('')
    return 100, 200

All the looping has been put in a generator function named find_intersections() which returns successive intersections it finds, skipping any combinations that don't.

def find_intersections(continuous_line, crossing_lines):
    for cl_segment in continuous_line:
        for xl_segment in crossing_lines:
            try:
                x, y = line_intersection(cl_segment, xl_segment)
            except Exception:
                pass
            else:
                yield x, y

Here's a usage example with made-up input data:

continuous_line = [((1,2),(3,4)), ((5,6),(7,8)), ((9,10),(11,12))]
crossing_lines = [((21,22),(23,24)), ((25,26),(27,28)), ((29,30),(31,32))]
intersections = [(x, y) for x, y in
                    find_intersections(continuous_line, crossing_lines)]
print('intersections found:')
print(intersections)

Output:

intersecting:
  (1. 2), (3, 4)
  (21. 22), (23, 24)

intersecting:
  (1. 2), (3, 4)
  (25. 26), (27, 28)

intersecting:
  (1. 2), (3, 4)
  (29. 30), (31, 32)

intersecting:
  (5. 6), (7, 8)
  (21. 22), (23, 24)

intersecting:
  (5. 6), (7, 8)
  (25. 26), (27, 28)

intersecting:
  (5. 6), (7, 8)
  (29. 30), (31, 32)

intersecting:
  (9. 10), (11, 12)
  (21. 22), (23, 24)

intersecting:
  (9. 10), (11, 12)
  (25. 26), (27, 28)

intersecting:
  (9. 10), (11, 12)
  (29. 30), (31, 32)

intersections found:
[(100, 200), (100, 200), (100, 200), (100, 200), (100, 200), (100, 200), (100,
200), (100, 200), (100, 200)]
martineau
  • 119,623
  • 25
  • 170
  • 301