我怎样才能使用Point for 2D for 3D,Python3?

时间:2014-01-14 19:06:06

标签: python python-3.x

我有一个关于仅有2个坐标(x,y)的点的类,我想要这个相同的类及其所有方法使用3个坐标(x,y,z)我读过* args但我不知道我怎么能用它解决这个问题。代码:

#/usr/bin/env python3
# -*- coding: utf-8 -*-


from math import sqrt, pow, hypot, atan2, cos, sin


class Point(object):
    __slots__ = ['x', 'y']

    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __del__(self):
        #del P destroy (delete) a point
        class_name = self.__class__.__name__

    def __add__(self, P):
        S = Point(self.x, self.y)
        S.x = self.x + P.x
        S.y = self.y + P.y
        return S

    __radd__ = __add__

    def __sub__(self, P):
        R = Point(self.x, self.y)
        R.x = self.x - P.x
        R.y = self.y - P.y
        return R

    __rsub__ = __sub__

    def __mul__(self, num):
        M = Point(self.x, self.y)
        M.x = num * self.x
        M.y = num * self.y
        return M

    __rmul__ = __mul__

    def __pow__(self, n):
        P = Point(self.x, self.y)
        P.x = self.x ** n
        P.y = self.y ** n
        return P

    def __neg__(self):
        O = Point(self.x, self.y)
        O.x = - self.x
        O.y = - self.y
        return O

    def __invert__(self):
        I = Point(self.x, self.y)
        I.x = 1. / self.x
        I.y = 1 / self.y
        return I

    def dist(self, P):
        return sqrt(pow(self.x - P.x, 2) + pow(self.y - P.y, 2))

    def pto_medio(self, P):
        Q = Point(self.x, self.y)
        R = (1. / 2.) * (P + Q)
        return R

    def traslacion(self, tx, ty):
        T = Point(self.x, self.y)
        T.x = self.x + tx
        T.y = self.y + ty
        return T

    def incentro(self, B, C):
        A = Point(self.x, self.y)
        a = B.dist(B)
        b = A.dist(C)
        c = A.dist(B)
        sumd = a + b + c
        A = (a / sumd) * A + (b / sumd) * B + (c / sumd) * C
        return A

    def rect2pol(self):
        P = Point(self.x, self.y)
        P.x = hypot(self.x, self.y)
        P.y = atan2(self.y, self.x)
        return(P)

    def pol2rect(self):
        P = Point(self.x, self.y)
        P.x = self.x * cos(self.y)
        P.y = self.x * sin(self.y)
        return(P)

    def entrada(self):
        point = raw_input('Introduce un punto:\n')
        point = point.replace('(', '')
        point = point.replace(')', '')
        l1 = point.rsplit(',')
        self.x = float(l1[0])
        self.y = float(l1[1])
        l1 = []

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


def main():
    p = Point()
    q = Point()

    Point.entrada(p)
    Point.entrada(q)

    s = p + q
    r = p - q
    m = 5 * p

    pol = p.rect2pol()
    rect = pol.pol2rect()

    print(('s = {}'.format(s)))
    print(('r = {}'.format(r)))
    print(('m = {}'.format(m)))
    print(('p ^ 3 = {}'.format(p ** 3)))
    print(('opuesto = {}'.format(- p)))
    print(('inverso = {}'.format(~ p)))
    print(('distancia = {}'.format(p.dist(q))))
    print(('Punto Medio = {}'.format(p.pto_medio(q))))
    print(('Traslación = {}'.format(p.traslacion(5, -2))))
    print(('En Polares = {}'.format(pol)))
    print(('En Rectangulares = {}'.format(rect)))

    A = Point(0, 0)
    B = Point(1, 0)
    C = Point(1. / 2., sqrt(3.) / 2.)
    I = A.incentro(B, C)
    print(('Incentro = {}'.format(I)))


if __name__ == '__main__':
    main()

本课程中的所有功能我可以将它们重复使用3D。我不想只为3D创建一个新的派生类,因为我应该重新编写所有方法,或者为3D点创建一个新类。有可能吗?

1 个答案:

答案 0 :(得分:1)

只需为z参数设置默认值None

class Point(object):
    __slots__ = ['x', 'y', 'z']

    def __init__(self, x=0, y=0, z=None):
        self.x = x
        self.y = y
        self.z = z

然后检测z是否未设置为计算所需的None

def __add__(self, P):
    S = Point(self.x, self.y, self.z)
    S.x = self.x + P.x
    S.y = self.y + P.y
    if self.z is not None:
        if P.z is None:
            raise ValueError('Cannot add a 2D point to a 3D point')
        S.z = self.z + P.z
    return S