如何使用点类表示线串

时间:2014-01-19 11:33:28

标签: python python-2.7

我想实现一个用于表示线串的类。我有一个名为“Point”的课程 表示具有2个坐标的点,我想用它来存储内部顶点 线串。 我想出了这段代码:

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

class LineString(Point):
    def __init__(self, point):
        self.point = point

但我不知道如何在线串中显示多个点 支持像:

这样的线串
lin = LineString((1, 1), (0, 2), (3,6))

我不知道线串中可能出现的点数。 新代码:

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

class LineString(Point):
    def __init(self, *points):
        #~ self.points=points
        self.points = []
        for point in points:
            if not isinstance(point, Point):
                point = Point(*point)
            self.points.append(point)

    def length(self):
        L = len(self.points)
        return L




if __name__ == '__main__':
    # Tests for LineString
    # ===================================
    lin1 = LineString((1, 1), (0, 2))
    assert len(lin1.points) == sqrt(2.0)

2 个答案:

答案 0 :(得分:1)

为您的构造函数提供一个带*argumentname的变量参数:

class LineString(Point):
    def __init__(self, *points):
        self.points = points

您可以根据需要将元组转换为Point()个实例:

class LineString(Point):
    def __init__(self, *points):
        self.points = []
        for point in points:
            if not isinstance(point, Point):
                point = Point(*point)
            self.points.append(point)

在这两种情况下,self.points现在都是Python list对象。请注意在Point(*point)调用中使用镜像语法; point元组的元素作为单独的参数应用于Point.__init__()方法,将(1, 1)元组作为xy的两个参数传递。< / p>

现在您可以使用以下任一方式构建一个行字符串:

lin = LineString((1, 1), (0, 2), (3,6))

lin = LineString(Point(1, 1), Point(0, 2), Point(3,6))

演示:

>>> lin = LineString((1, 1), (0, 2), (3,6))
>>> len(lin.points)
3
>>> lin.points[0]
<__main__.Point object at 0x108988fd0>
>>> lin.points[0].x, lin.points[0].y
(1, 1)

答案 1 :(得分:1)

行不是点,也不是行的字符串。 Liskov Substitution Principle表明应始终可以将派生类的实例替换为其父类之一。请考虑以下代码:

def move_point(point, xdist, ydist):
    return Point(point.x + xdist, point.y + ydist)

p = Point(3, 4)
q = move_point(p, 5, 6)
assert q.x == 8 and q.y == 10

r = LineString((2, 3), (5, 4), (8, 6))
s = move_point(r, 5, 6)  # ???

s可能是什么?一串行的(x, y)坐标是什么?

解决这个问题的方法就是不从Point派生LineString。相反,代码看起来应该是这样的:

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    ...  # see implementation details @ http://docs.python.org/2.7/library/itertools.html#recipes

class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

def distance(point1, point2):
    ...  # needs implementing

class Line(object):
    def __init__(self, a, b):  # a and b must be Points
        self.a = a
        self.b = b

    @property
    def length(self):
        return distance(self.a, self.b)

class LineString(object):
    def __init(self, *points):
        # We assume that points consists only of proper Point instances.
        # If people pass invalid arguments, it's their problem.
        self.points = points

    @property
    def length(self):
        return sum(distance(p1, p2) for p1, p2 in pairwise(self.points))

if __name__ == '__main__':
    lin1 = LineString((1, 1), (0, 2))
    assert lin1.length == sqrt(2.0)

此外,浮点运算有时会产生奇怪的结果:

>>> .1 + .2 == .3
False
>>> .1 + .2
0.30000000000000004

有关说明,请参阅http://floating-point-gui.de