通过元组,列表列表搜索和匹配对象

时间:2014-06-16 16:49:29

标签: python list tuples

工作了几个小时后,在这个问题上花了太多精力,我差点放弃了!这是:

假设:
包含点对象的列表,其中我将点对象和线对象定义为:

class Point():
    def  __init__(self, x, y):
        self._x = x
        self._y = y
    def __eq__(self, other):
        return self.__dict__ == other.__dict__

class Line(object):
    def __init__(self,p1, p2,name):
        self.p1=p1
        self.p2=p2
        self.name=name

问题:
我正在尝试按照连接线的顺序创建一个点列表;到目前为止,我可以检测线之间的连接,例如

p1=Point(2.1,2.0)   
p2=Point(1.1,5.0)   
p3=Point(4.1,3.0)   
p4=Point(3.1,2.0)   

line1=Line(p1,p2,"line.1")
line2=Line(p3,p2,"line.2")   
line3=Line(p3,p4,"line.3")   
line4=Line(p4,p1,"line.4") 

- Lines and points

通常情况下,这些点没有按顺序列出,类似地,这些线也没有排序。

到目前为止,我可以按以下格式检测样条连接(包含元组的列表列表:

connectionList=    [
[(line1, line1.p1), (line4, line4.p2)]
[(line2, line2.p1), (line3, line3.p1)]
[(line3, line3.p2), (line4, line4.p1)]
...
]

我正在尝试以格式[p1, p3,p4, ..]

来实现结果

修改

以下问题的解决方案(在使用@marqs的答案之后)嵌入在一个示例中,如下所示:

class Point():
    def __init__(self, x, y):
        self._x = x
        self._y = y
    def __eq__(self, other):
        return self.__dict__ == other.__dict__

class Line(object):
    def __init__(self,p1, p2,name):
        self.p1=p1
        self.p2=p2
        self.name=name

p1=Point(1,1)
p2=Point(5,2)
p3=Point(1,5)
p4=Point(2,2)
p5=Point(5,5)
p6=Point(6,1)
p7=Point(6,5)
p8=Point(2,5)


s1=Line(p1,p3,"Line1")
s2=Line(p7,p6,"Line2")
s3=Line(p1,p6,"Line3")
s4=Line(p2,p5,"Line4")
s5=Line(p4,p8,"Line5")
s6=Line(p4,p2,"Line6")
s7=Line(p5,p7,"Line7")
s8=Line(p3,p8,"Line8")


def connectivity(s,sl):
    s_L=[]
    s_L=[spl1 for spl1 in sl]
    s_L.remove(s)
    connection=[]
    for sp in s_L:
        if s.p1==sp.p1:
            connection.append([(s, s.p1), (sp, sp.p1)])
            continue
        elif s.p1==sp.p2:
            connection.append([(s, s.p1), (sp, sp.p2)])
            continue
        elif s.p2==sp.p1:
            connection.append([(s, s.p2), (sp, sp.p1)])
            continue
        elif s.p2==sp.p2:
            connection.append([(s, s.p2), (sp, sp.p2)])
            continue
        else:
            pass
    return connection


def getPoints(connectionList):
    firstConnection = connectionList[0]
    points = [firstConnection[1][1]]
    lastLine = firstConnection[1][0]

    connectionList.remove(firstConnection)

    while len(connectionList):
        for connection in list(connectionList):
            (line1, p1), (line2, p2) = connection
            if lastLine == line1 or lastLine == line2:
                points.append(p1)
                lastLine = line1 if lastLine == line2 else line2
                connectionList.remove(connection)
                break
    return points


con=[]
complete=[]
slist=[s1,s2,s3,s4,s5,s6,s7,s8]
for splineX in slist:
    con=connectivity(splineX, slist)
    prev=[temp1 for temp01 in complete for temp1 in temp01]
    if not (con[0][0] in prev or con[0][1] in prev):
        complete.append(con[0])
    if len(con)>1:
        if not (con[1][0] in prev or con[1][1] in prev):
            complete.append(con[1])

connectionList=[xyz for xyz in complete]
pointList=getPoints(connectionList)
pointcord=[]
for pnt in pointList:
    pointcord.append((pnt._x, pnt._y))

print "Ordered list of points:\n" , pointcord

结果是:

Ordered list of points: [(1, 1), (6, 1), (6, 5), (5, 5), (5, 2), (2, 2), (2, 5), (1, 5)]

2 个答案:

答案 0 :(得分:1)

我不会说python,但你可以这样做:

  1. Find the center of your polygon
  2. 根据中心点的角度对顶点进行排序。您可以从中心点获取角度,如下所示:atan2(point.y - Center.y, point.x - Center.x)
  3. 如果两个点具有相同的角度,则最靠近中心的点首先出现。对于性能,您可以在没有平方根的情况下计算它,如下所示:abs((point.y - Center.y)*(point.y - Center.y)+(point.x - Center.x)*(point.x - Center.x))

答案 1 :(得分:1)

我试了一下你的问题。下面的函数尝试查找匹配的行并保存点。它假定connectionList是正确的。如果不是,该函数可能会进入无限循环。

def getPoints(connectionList):
    firstConnection = connectionList[0]
    points = [firstConnection[1][1]]
    lastLine = firstConnection[1][0]

    connectionList.remove(firstConnection)

    while len(connectionList):
        for connection in list(connectionList):
            (line1, p1), (line2, p2) = connection
            if lastLine == line1 or lastLine == line2:
                points.append(p1)
                lastLine = line1 if lastLine == line2 else line2
                connectionList.remove(connection)
                break
    return points