如何使用Python找到线段的长度

6

我想用Python计算(任意数量的)线段长度。我使用了以下代码,但遇到了元组无法进行减法运算的问题。我该如何解决?我想知道是否有重要的Python概念我没有掌握。

from itertools import starmap
import math
class Point(object):
    def __init__(self,x,y):
        self.x=x
        self.y=y
    def move(self,dx,dy):
        self.x+=dx
        self.y+=dy


class LineString(object):

    def __init__(self,*args): # A method with any number of arguments, args

        self.args=[Point(*args) for p in args] # A list of Points

    def length(self):
        pairs=zip(self.args, self.args[1:])
        return sum(starmap(distance,pairs))

def distance(p1, p2):
    a = p1.x,p1.y
    b = p2.x,p2.y

    print (math.sqrt((a[0]-b[0])**2-(a[1]-b[1])**2))
    # calculates distance between two given points p1 and p2
    return math.sqrt((a** 2)+ (b** 2))


if __name__ == '__main__':
    # Tests for LineString
    # ===================================
    lin1 = LineString((1, 1), (0, 2))

    assert lin1.length() == sqrt(2.0)

    lin1.move(-1, -1) # Move by -1 and -1 for x and y respectively

    assert lin1[0].y == 0 # Inspect the y value of the start point.
    # Implement this by overloading __getitem__(self, key) in your class.

    lin2 = LineString((1, 1), (1, 2), (2, 2))

    assert lin2.length() == 2.0

    lin2.move(-1, -1) # Move by -1 and -1 for x and y respectively

    assert lin2.length() == 2.0

    assert lin2[-1].x == 1 # Inspect the x value of the end point.

    print ('Success! Line tests passed!')
3个回答

5
正如已经提到的那样,必须使用Point(*p)而不是Point(*args)。后者会将所有点元组传递给每个点的构造函数。你还需要修复distance
def __init__(self, *args):
    self.args=[Point(*p) for p in args]

def distance(p1, p2):
    return math.sqrt((p1.x-p2.x)**2 + (p1.y-p2.y)**2)

然而,与其创建自己的Point类,你可以使用内置的complex 数字,这是一个"重要的Python概念",可以使distance变得更简单:
def __init__(self, *args):
    self.args=[complex(*p) for p in args]

def distance(p1, p2):
    return abs(p1 - p2)

4

数学模块中有hypot函数可用于此目的

math.hypot(x, y)

返回欧几里得范数,即sqrt(xx + yy)。这是从原点到点(x, y)的向量长度。

这是我的建议

return math.hypot(p1.x - p2.x, p1.y - p2.y)

1

Python不支持元组的指数运算(以及其他数学运算)。虽然可以编写如下代码:

print (1, 2) * 3       # produces (1, 2, 1, 2, 1, 2)
print (1, 2) + (1, 2)  # produces (1, 2, 1, 2)

这不是对整个元组进行向量计算,而只是元组连接的一种语法糖。

此外,代码片段似乎有几个拼写错误/漏洞。

self.args=[Point(*args) for p in args] 应该改为 self.args=[Point(*p) for p in args]

LineString 没有 move() 方法。

并且 distance() 计算应该稍作修改(请注意,我在公式中用 + 替换了 -):

return math.sqrt((p1.x - p2.x)**2 + (p1.y - p2.y)**2)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接