Python语言 - 使用OOP的圆圈中心

时间:2015-02-19 08:55:42

标签: python class oop python-3.x

class Point:

    def __init__(self, initX, initY):
        """ Create a new point at the given coordinates. """
        self.x = initX
        self.y = initY

    def getX(self):
        return self.x

    def getY(self):
        return self.y

    def distanceFromOrigin(self):
        return ((self.x ** 2) + (self.y ** 2))** 0.5

    def __str__(self):
        return "x=" + str(self.x) + ", y=" + str(self.y)

    def get_line_to(self, target):
        mx = (-target.x + self.x ) 
        my = (-target.y + self.y)
        grad=my/mx
        c=-(grad*(self.x))+self.y
        return grad
    def halfway(self, target):
        """calculating midpoint"""
        mx = (self.x + target.x) / 2
        my = (self.y + target.y) / 2
        return Point(mx, my)

def cencd(p1,p2,p3):
    """calculating the center of a circle"""
    ma=(p2.getY-p1.getY)/(p2.getX-p1.getX)
    mb=(p3.getY-p2.getY)/(p3.getX-p2.getX)
    hw=p1.halfway(p2)
    x=(ma*mb*(p1.getY-p3.getY)+mb*(p1.getX+p2.getX)-ma*(p2.getX+p3.getX))/2*(mb-ma)
    ya=-(1/ma)*((x-hw.getX)+hw.getY)
    return x,ya

"""defining the points for p1,p2 and p3"""

    p = Point(5,5)

    q = Point(6,-2)

    r=Point(2,-4)

    print(cencd(p,q,r))

我收到此错误消息:SyntaxError:函数定义中的重复参数'p1' Traceback(最近一次调用最后一次):   文件“python”,第45行,in   文件“python”,第34行,在cencd中 TypeError:不支持的操作数类型 - :'method'和'method'

请协助。 “”“工作解决方案”“”“

ma=(p2.y-p1.y)/(p2.x-p1.x)
mb=(p3.y-p2.y)/(p3.x-p2.x)
hw=p1.halfway(p2)

x1=(ma*mb*(p1.y-p3.y)+mb*(p1.x+p2.x)-ma*(p2.x+p3.x))/(2*(mb-ma))
ya=-(1/ma)*((x1-hw.x))+hw.y

3 个答案:

答案 0 :(得分:1)

你不需要在python中使用getter或setter,也不需要pythonic来使用它们,你应该直接访问这些属性:

def cencd(p1, p2, p3):
    """calculating the center of a circle"""
    ma = (p2.y - p1.y) / (p2.x - p1.x)
    mb = (p3.y - p2.y) / (p3.x - p2.x)
    hw = p1.halfway(p2)
    x = (ma * mb * (p1.y - p3.y) + mb * (p1.x + p2.x) - ma * (p2.x + p3.x)) / 2 * (mb - ma)
    ya = -(1 / ma) * ((x - hw.x) + hw.y)
    return x, ya

答案 1 :(得分:0)

getXgetY都是代码中的方法,而不是属性。因此,您需要使用getX()getY()来调用它们。

所以ma=(p2.getY-p1.getY)/(p2.getX-p1.getX)变为:

ma = (p2.getY()-p1.getY())/(p2.getX()-p1.getX())

依此类推,其他代码也会发生变化。

否则,您也可以将方法定义为@property

class Point:
    ...
    ...
    @property
    def getX(self):
        return self.x
    @property
    def getY(self):
        return self.y
    ...

现在,您可以p1.getXp2.getY等方式访问这些内容。

请注意,上面的@property装饰器将方法转换为getter,这对于仅使用私有变量(定义为以_开头的变量)是有意义的。

因此,由于x和y都是类的普通属性,因此您可以直接访问它们而无需使用和属性修饰符或使用getter方法(如p1.xp2.y)作为@Padraic点在他的帖子中。

答案 2 :(得分:0)

正如Padraic Cunningham所说,我们不需要Python中的getter或setter,但正如mu所说,我们可以根据需要制作getter,但通常它们用于获取实际根据true属性计算的“假”属性。例如,在下面的代码中,我为您的Point类添加了假norm属性。

我还为您的班级添加了一些双下划线方法(又名dunder方法或magic methods)。这些方法在the official Python docs中讨论。

最常见的dunder方法之一是__repr__(),它应返回与您创建类实例的方式相对应的字符串。当您在交互式解释器中使用类时,这尤其方便。 FWIW,如果某个类未定义__str__()方法,则在尝试将类实例转换为字符串时将使用其__repr__()方法。如果尚未定义__repr__()方法,则将使用默认方法。

我添加的其他dunder方法可以更容易地对点执行算术运算;这可以使代码更容易编写和读取。我想你会同意它使cencd()功能更清晰一些。 (我不确定那个函数到底应该做什么;我假设你的代数是正确的:))。

此代码在Python 2.6.6上进行了测试;它应该在没有修改的情况下在Python 3上运行正常。

#!/usr/bin/env python

''' Point class demo

    From http://stackoverflow.com/q/28602056/4014959

    Written by koseph, Padraic Cunningham, and PM 2Ring
    2015.02.19
'''

from __future__ import print_function
from __future__ import division

class Point(object):
    def __init__(self, initX, initY):
        """ Create a new point at the given coordinates. """
        self.x, self.y = initX, initY

    @property
    def norm(self):
        return self.x ** 2 + self.y ** 2

    def distance_from_origin(self):
        return self.norm ** 0.5

    def __repr__(self):
        return 'Point({self.x}, {self.y})'.format(self=self)

    def __str__(self):
        return 'x={self.x}, y={self.y}'.format(self=self)

    def __add__(self, other):
        return Point(self.x + other.x, self.y + other.y)

    def __mul__(self, scale):
        return Point(self.x * scale, self.y * scale)

    __rmul__ = __mul__

    def __neg__(self):
        return -1 * self

    def __sub__(self, other):
        return self + -other

    def weighted_mean(self, other, weight):
        cweight = 1.0 - weight
        x = cweight * self.x + weight * other.x
        y = cweight * self.y + weight * other.y
        return Point(x, y)

    def halfway(self, other):
        return self.weighted_mean(other, 0.5)


def cencd(p1, p2, p3):
    """ Calculate the center of a circle """
    a = p2 - p1
    b = p3 - p2
    ma = a.y / a.x
    mb = b.y / b.x
    hw = p1.halfway(p2)
    x = ma * mb * (p1 - p3).y + mb * (p1 + p2).x - ma * (p2 + p3).x
    x /= 2.0 * (mb - ma)
    y = -(x - hw.x + hw.y) / ma
    return Point(x, y)


p1 = Point(3, 4)
print(p1)
print('p1 is {0!r}, its norm is {1}'.format(p1, p1.norm))
print('and its distance from the origin is', p1.distance_from_origin(), end='\n\n')

p2 = Point(7, 2)
print('p2 is', repr(p2), end='\n\n')

print('p1 + p2 is', repr(p1 + p2))
print('p1 * 0.1 is', repr(p1 * 0.1))
print('p2 - p1 is', repr(p2 - p1), end='\n\n')

p3 = 4 * p1
print('p3 is', repr(p3), end='\n\n')

print('Weighted means from p1 to p3')
for i in range(5):
    weight = i / 4.0
    print('{0} {1:4.2f} {2!r}'.format(i, weight, p1.weighted_mean(p3, weight)))
print()

print('center of a circle for p1, p2, & p3:', repr(cencd(p1, p2, p3)))

<强>输出

x=3, y=4
p1 is Point(3, 4), its norm is 25
and its distance from the origin is 5.0

p2 is Point(7, 2)

p1 + p2 is Point(10, 6)
p1 * 0.1 is Point(0.3, 0.4)
p2 - p1 is Point(4, -2)

p3 is Point(12, 16)

Weighted means from p1 to p3
0 0.00 Point(3.0, 4.0)
1 0.25 Point(5.25, 7.0)
2 0.50 Point(7.5, 10.0)
3 0.75 Point(9.75, 13.0)
4 1.00 Point(12.0, 16.0)

center of a circle for p1, p2, & p3: Point(8.22727272727, 12.4545454545)