2014-01-14 45 views
0

我有一個關於點只有2個座標(x,y)的類,我希望這個類和它的所有方法都使用3個座標,(x,y,z)我讀過關於* args但我不知道如何在這個問題上使用它。代碼:我該如何使用2D的3D類,Python3類Point?

#/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

只要給你的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 
+0

非常感謝你。它工作完美! :-) – Tobal