Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(Python)脚本以确定(x,y)坐标是否共线-出现一些错误_Python_List_Function_Graph_Points - Fatal编程技术网

(Python)脚本以确定(x,y)坐标是否共线-出现一些错误

(Python)脚本以确定(x,y)坐标是否共线-出现一些错误,python,list,function,graph,points,Python,List,Function,Graph,Points,正如标题所说,我正在尝试编写一个程序,它获取(x,y)坐标列表,并确定是否有任何3个点共线(位于具有相同斜率的直线上) 我收到一些错误消息。目前,我收到一条“TypeError:'int'对象不可订阅”消息。如果我去掉共线测试调用AreCollinar函数的部分,我会得到一个“索引超出范围”错误。我是python新手,只是想学习一下 def areCollinear(p1, p2, p3): slope1 = (p2[1] - p1[1]) / (p2[0] - p1[0]) s

正如标题所说,我正在尝试编写一个程序,它获取(x,y)坐标列表,并确定是否有任何3个点共线(位于具有相同斜率的直线上)

我收到一些错误消息。目前,我收到一条“TypeError:'int'对象不可订阅”消息。如果我去掉共线测试调用AreCollinar函数的部分,我会得到一个“索引超出范围”错误。我是python新手,只是想学习一下

def areCollinear(p1, p2, p3):
    slope1 = (p2[1] - p1[1]) / (p2[0] - p1[0])
    slope2 = (p3[1] - p2[1]) / (p3[0] - p2[0])
    if slope1 == slope2:
        print "Points are colinear"
    else:
        print "Points are NOT colinear, what's the matter with you?"

def collinearityTest(pointList):
    position = 0
    while position >=0 and position < len(pointList):

        for p1 in pointList[position]:
            position = position + 1
            for p2 in pointList[position]:
                position = position + 1
                for p3 in pointList[position]:
                    position = position + 1
                    areCollinear(p1, p2, p3)

pointList = [(10, 20), (55, 18), (10, -45.5), (90, 34), (-34, -67), (10, 99)]

collinearityTest(pointList)
def共线(p1、p2、p3):
斜率1=(p2[1]-p1[1])/(p2[0]-p1[0])
斜率2=(p3[1]-p2[1])/(p3[0]-p2[0])
如果slope1==slope2:
打印“点是共线的”
其他:
打印“点不是共线的,你怎么了?”
def共线测试(点列表):
位置=0
当位置>=0且位置
错误消息:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 23, in <module>
  File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 19, in collinearityTest
  File "C:\Program Files (x86)\Wing IDE 101 4.1\src\debug\tserver\_sandbox.py", line 2, in areCollinear
    if __name__ == '__main__':
TypeError: 'int' object is not subscriptable
回溯(最近一次呼叫最后一次):
文件“C:\Program Files(x86)\Wing IDE 101 4.1\src\debug\tserver\\u sandbox.py”,第23行,在
文件“C:\Program Files(x86)\Wing IDE 101 4.1\src\debug\tserver\\ u sandbox.py”,第19行,共线性测试
文件“C:\Program Files(x86)\Wing IDE 101 4.1\src\debug\tserver\\u sandbox.py”,第2行,共线
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
TypeError:“int”对象不可下标

您的代码可能会更干净:

import itertools

def arecolinear(points):
    xdiff1 = float(points[1][0] - points[0][0])
    ydiff1 = float(points[1][1] - points[0][1])
    xdiff2 = float(points[2][0] - points[1][0])
    ydiff2 = float(points[2][1] - points[1][1])

    # infinite slope?
    if xdiff1 == 0 or xdiff2 == 0:
        return xdiff1 == xdiff2
    elif ydiff1/xdiff1 == ydiff2/xdiff2:
        return True
    else:
        return False

pointlist = [(10, 20), (55, 18), (10, -45.5), (90, 34), (-34, -67), (10, 99)]

for points in itertools.combinations(pointlist, 3):
    if arecolinear(points):
        print("Points are colinear")
    else:
        print("Points are NOT colinear")

所以你需要3个for循环,每个循环都在相同的点列表中迭代。那你为什么有while循环呢?把它拿走。在这种情况下没有必要

此外
pointList[position]
是一个二维元组,例如(10,20)。通过在pointList[position]
中为p1编写
,您正试图迭代该元组。您想要的是在列表上迭代。因此,请在点列表中为p1尝试
。即,删除尖括号以迭代列表,而不是元组。因此,;你也不需要跟踪位置

所以它变成了

for p1 in pointList:
  for p2 in pointList:
    for p3 in pointList:
        #do something with p1 p2 p3

<强>提示:< /强>您也可以考虑使用<代码> AcLogoLoad 函数返回布尔值,而不是打印某些东西。不会真正改变功能,但这是一种更好的做法,因为它使您的功能以后可以在其他地方重用。

错误 主要错误是您试图访问
int
对象的一部分,但这是不可能的。您可以复制类似的错误,如下所示:

>>> p1 = 1
>>> p1[1]
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    p1[1]
TypeError: 'int' object is not subscriptable

我会使用
itertools.combinations()
,但由于您正在尝试学习Python,这是您的基本问题:您对
点列表的了解比您需要的更深

修改功能:

def collinearityTest(pointList):
    for p1 in pointList:
        for p2 in pointList:
            if p2 is p1:
                continue
            for p3 in pointList:
                if p3 is p2 or p3 is p1:
                    continue
                areCollinear(p1, p2, p3)
点列表中p1的
将为您提供点列表中的每个项目。那正是你想要的。如果愿意,您也可以使用索引(
pointList[index]
)来实现这一点


再次使用
itertools.combines()

这里有一个更简单、数值更稳定的函数来测试三个点的共线性:

def collinear(p0, p1, p2):
    x1, y1 = p1[0] - p0[0], p1[1] - p0[1]
    x2, y2 = p2[0] - p0[0], p2[1] - p0[1]
    return abs(x1 * y2 - x2 * y1) < 1e-12
def共线(p0、p1、p2): x1,y1=p1[0]-p0[0],p1[1]-p0[1] x2,y2=p2[0]-p0[0],p2[1]-p0[1] 返回abs(x1*y2-x2*y1)<1e-12

(请注意,最好不要硬编码ε,并使其与向量的长度相对。)

其他答案存在一些问题,例如检查是否被零除。下面是我的解决方案,它使用“All”Python功能,可以检查任意长度的点列表:

def collinear(Points):
    '''Accepts [(x1, y1), (x2, y2), ...] and returns true if the 
    points are on the same line.'''
    ERR=1.0e-12
    if len(Points)<3:
        return True
    x1, y1 = Points[0]
    x2, y2 = Points[1]
    if x2==x1:
        raise Exception("points are not a function")
    m=(y2-y1)/(x2-x1)
    return all([abs(m*(xi-x1)-yi+y1)<ERR for xi,yi in Points[2:]])
def共线(点):
''接受[(x1,y1),(x2,y2),…],如果
点在同一条线上
误差=1.0e-12

如果len(指出)如果您发布了导致错误的代码,这将有所帮助。编辑您的问题,将其包括在内。请发布您的代码。如果没有它,你的问题基本上是不可能回答的。告诉我这是一个可怕的代码并不能真正解决这个问题。非常感谢您的输入,但是请发布完整的错误。我们无法猜测(好吧,我们可能需要一些努力)生成它的直线。在您的代码和一些答案中,由每组三个连续点组成的两条直线的浮点斜率是相等的。一般来说,由于浮点计算的方式,这不太可能起作用。您需要使用不同的方法(如@Sven建议的方法),或者将两个斜率之间差值的绝对值与几乎为零的小浮点值进行比较,例如
1e-12
。这里的关键是他们的python库
itertools
已经有了一个函数来创建列表中的元素组合:@nightcracker:您是否知道
1.8/1
不等于Python2.x中的
18/10
,在本例中使用得很清楚?@Tadeck:OP清楚地使用了Python2.x,但是这个答案中的代码并不是针对2.x或3.x的。@Tadeck:是的,我知道,我会在其中添加一个
float
,以防止这个bug。我只是懒惰:P@SvenMarnach:当我查看答案时,代码显然是针对2.x的(参见:
print
语句而不是函数)。但事实上,它现在可能不是2.x特定的。谢谢你的回复。我被“如果p2是p1”和“如果p3是p2或p3是p1”弄糊涂了,我以前从未见过这样的事情。这是做什么的?显然你不想比较两个相同的点是否共线。由于您在同一列表上迭代了3次,因此这避免了使用where的任何场景
def collinear(Points):
    '''Accepts [(x1, y1), (x2, y2), ...] and returns true if the 
    points are on the same line.'''
    ERR=1.0e-12
    if len(Points)<3:
        return True
    x1, y1 = Points[0]
    x2, y2 = Points[1]
    if x2==x1:
        raise Exception("points are not a function")
    m=(y2-y1)/(x2-x1)
    return all([abs(m*(xi-x1)-yi+y1)<ERR for xi,yi in Points[2:]])