计算python中列表的行交叉点

时间:2014-10-02 00:31:44

标签: python list loops for-loop zip

我刚刚开始学习python,我需要解决这个问题但是我被卡住了。我们已经获得了一个函数(lSegInt)来查找线的交叉点。我需要做的是正确格式化数据,以便通过这个函数传递两条折线相交的时间。

以下是数据:

pt1 = (1,1)
pt2 = (5,1)
pt3 = (5,5)
pt4 = (1,5)
pt5 = (2,2)
pt6 = (2,3)
pt7 = (4,6)
pt8 = (6,3)
pt9 = (3,1)
pt10 = (1,4)
pt11 = (3,6)
pt12 = (4,3)
pt13 = (7,4)
l5 = [[pt1, pt5, pt6, pt7, pt8, pt9]] 
l6 = [[pt10, pt11, pt12, pt13]]

这是我的代码:

    def split(a):
      lines = []
      for i in range(len(a[0]) - 1):
         line = []
      for j in (i,i+1):
         line.append(a[0][j])
      lines.append(line)
      return lines
    sl5 = split(l5)
    sl6 = split(l6) + split(l6)

这就是我被困住的地方。需要找出折线相交的次数。我想使用带有sl5和sl6的zipped for循环,但它不会检查一个列表的每一行与另一个列的每一行,并且列表的长度不同。

while i < len(sl5):
    for x, in a,:
       z = 1
       fresults.append(lSegInt(x[0],x[1],sl6[0][0],sl6[1][0]))
       fresults.append(lSegInt(x[0],x[1],sl6[1][0],sl6[1][1]))
       fresults.append(lSegInt(x[0],x[1],sl6[2][0],sl6[2][1]))
       i = i + 1
print fresults

功能:

def lSegInt(s1, s2, t1, t2):
'''Function to check the intersection of two line segments. Returns 
None if no intersection, or a coordinate indicating the intersection.

An implementation from the NCGIA core curriculum. s1 and s2 are points 
(e.g.: 2-item tuples) marking the beginning and end of segment s. t1 
and t2 are points marking the beginning and end of segment t. Each point 
has an x and y coordinate: (1, 3). 
Variables are named following linear formula: y = a + bx.'''
if s1[0] != s2[0]:                # if s is not vertical
    b1 = (s2[1] - s1[1]) / float(s2[0] - s1[0])
    if t1[0] != t2[0]:             # if t is not vertical
        b2 = (t2[1] - t1[1]) / float(t2[0] - t1[0])
        a1 = s1[1] - (b1 * s1[0])
        a2 = t1[1] - (b2 * t1[0])
        if b1 == b2:                # if lines are parallel (slopes match)
            return(None)
        xi = -(a1-a2)/float(b1-b2)  # solve for intersection point
        yi = a1 + (b1 * xi)
    else:
        xi = t1[0]
        a1 = s1[1] - (b1 * s1[0])
        yi = a1 + (b1 * xi)
else:
    xi = s1[0]
    if t1[0] != t2[0]:            # if t is not vertical
        b2 = (t2[1] - t1[1]) / float(t2[0] - t1[0])
        a2 = t1[1] - (b2 * t1[0])
        yi = a2 + (b2 * xi)
    else:
        return(None)
# Here is the actual intersection test!
if (s1[0]-xi)*(xi-s2[0]) >= 0 and \
(s1[1]-yi)*(yi-s2[1]) >= 0 and \
(t1[0]-xi)*(xi-t2[0]) >= 0 and \
(t1[1]-yi)*(yi-t2[1]) >= 0:
    return((float(xi), float(yi)))  # Return the intersection point.
else:
    return(None)

非常感谢任何帮助。对不起文字墙。

2 个答案:

答案 0 :(得分:0)

我不知道您的split功能应该用于什么,但我认为您不需要它。我也不知道为什么你的折线是列表列表,但是你去了:

def count_intersections(polyline1, polyline2):
    intersections= 0

    # for each line in polyline1...
    iter1= iter(polyline1)
    point1= next(iter1)
    while True:
        try:
            point2= next(iter1)
        except StopIteration:
            break

        #...count the intersections with polyline2
        iter2= iter(polyline2)
        point3= next(iter2)
        while True:
            try:
                point4= next(iter2)
            except StopIteration:
                break

            if lSegInt(point1, point2, point3, point4):
                intersections+= 1

    return intersections

print count_intersections(l5[0], l6[0])
# this prints "2". I didn't manually confirm if it's correct, but it doesn't look too bad.

在那里解释不多:我们的想法是计算polyline1中任何线与polyline2中任何线相交的频率,因此您只需要遍历两条折线和在每次迭代中调用lSegInt函数。

答案 1 :(得分:0)

这对我有用:

  1. 确保列表配置良好。 x1y1 是第一行上的点。 x2y2 是第二行上的点。
def config_lists(x1, y1, x2, y2):
    line1 = list(zip(x1, y1))
    line2 = list(zip(x2, y2))
    return line1, line2

line1, line2 = config_lists(x1, y1, x2, y2)
  1. 现在我们有了线条,让我们计算交叉点的数量。这仅在 x 值对齐且列表长度相同时才有效。此外,大部分功劳归功于 OP,lSegInt 完成了大部分工作。
def lSegInt(s1, s2, t1, t2):
    '''Function to check the intersection of two line segments. Returns 
    None if no intersection, or a coordinate indicating the intersection.

    An implementation from the NCGIA core curriculum. s1 and s2 are points 
    (e.g.: 2-item tuples) marking the beginning and end of segment s. t1 
    and t2 are points marking the beginning and end of segment t. Each point 
    has an x and y coordinate: (1, 3). 
    Variables are named following linear formula: y = a + bx.'''
    if s1[0] != s2[0]:                # if s is not vertical
        b1 = (s2[1] - s1[1]) / float(s2[0] - s1[0])
        if t1[0] != t2[0]:             # if t is not vertical
            b2 = (t2[1] - t1[1]) / float(t2[0] - t1[0])
            a1 = s1[1] - (b1 * s1[0])
            a2 = t1[1] - (b2 * t1[0])
            if b1 == b2:                # if lines are parallel (slopes match)
                return(None)
            xi = -(a1-a2)/float(b1-b2)  # solve for intersection point
            yi = a1 + (b1 * xi)
        else:
            xi = t1[0]
            a1 = s1[1] - (b1 * s1[0])
            yi = a1 + (b1 * xi)
    else:
        xi = s1[0]
        if t1[0] != t2[0]:            # if t is not vertical
            b2 = (t2[1] - t1[1]) / float(t2[0] - t1[0])
            a2 = t1[1] - (b2 * t1[0])
            yi = a2 + (b2 * xi)
        else:
            return(None)
    # Here is the actual intersection test!
    if (s1[0]-xi)*(xi-s2[0]) >= 0 and \
    (s1[1]-yi)*(yi-s2[1]) >= 0 and \
    (t1[0]-xi)*(xi-t2[0]) >= 0 and \
    (t1[1]-yi)*(yi-t2[1]) >= 0:
        return((float(xi), float(yi)))  # Return the intersection point.
    else:
        return(None)


def count_intersections(line1, line2):
#     Make sure the x values of both lines are same length and aligned.
    assert len(line1) == len(line2)
    
    intersections= 0
    for i in range(len(line1) - 1):
#         Taking starting and end point of every segment in the line
        x1_start, y1_start = line1[i]
        x1_end, y1_end = line1[i + 1]
        x2_start, y2_start = line2[i]
        x2_end, y2_end = line2[i + 1]
        
        assert x1_start == x2_start and x1_end == x2_end
        
        if lSegInt([x1_start, y1_start], [x1_end, y1_end], [x2_start, y2_start], [x2_end, y2_end]):
            intersections+= 1

    return intersections

print(count_intersections(line1, line2))