0001"""
0002**points of the complex plane** with fixed or dependant position 
0003"""
0004__Def__ =       ['zPoint']
0005
0006__Classes__ =   [ 'zFixedPoint', 'zPolarPoint', 'zOrthoPoint', 'zConjugate',
0007                'u_to_zPoint','zInversePoint', 'zPowerPoint',
0008                'zCircumPoint', 'zHarmonic', 'zRotation', 'z_uRotation']
0009
0010__all__ = __Classes__ + __Def__
0011
0012__doc_hints__={'m_type':'factory'}
0013
0014
0015import pygeo.base.abstracts._complex as Complex
0016
0017from pygeo.base.analytics.pygeomath import math_E, tan, sqrt, array, matrixmultiply,                                  PI, mod2, Mobius
0019
0020class zFixedPoint(Complex._zPoint):
0021    """
0022*complex point* fixed at given (real, imaginary) **coordinates**
0023    
0024    inherits
0025    
0026        `_zPoint`__
0027
0028__ class-base.abstracts._complex._zPoint.html        
0029    
0030    """
0031
0032    __doc_hints__=  {'factory':'zPoint',
0033                    'args':['float <,float>']}
0034
0035    def __init__(self,*args,**kws):
0036        Complex._zPoint.__init__(self,*args,**kws)
0037        self.init()
0038
0039class zPolarPoint(Complex._zPoint):
0040    """
0041*complex point* fixed at given 'angle' and 'dist' **polar coordinates**
0042    
0043    inherits
0044    
0045        `_zPoint`__
0046
0047__ class-base.abstracts._complex._zPoint.html        
0048    
0049    """
0050
0051    __doc_hints__=  {'factory':'zPoint',
0052                    'args':['angle=float,dist=float']}
0053
0054    def __init__(self,angle=PI,dist=1.0,**kw):
0055        Complex._zPoint.__init__(self,**kw)
0056        self.angle=angle
0057        self.dist=dist
0058        self.init()
0059
0060    def findSelf(self):
0061        self.set(math_E**complex(0,self.angle)*self.dist)
0062        return True
0063
0064class zOrthoPoint(Complex._zPoint):
0065    """
0066*complex point* orthogonal to the given **complex point**, i.e. antipodal 
0067to it's stereographic projection onto the Riemann sphere.
0068    
0069    inherits
0070    
0071        `_zPoint`__
0072
0073__ class-base.abstracts._complex._zPoint.html        
0074    
0075    """
0076
0077    __doc_hints__=  {'factory':'zPoint',
0078                    'args':['zpoint'],
0079                    'qualifier':'ORTHO'}
0080
0081    __opts__= Complex._zPoint.__opts__[:] +['alt']
0082
0083    def __init__(self,cpoint,**kws):
0084        Complex._zPoint.__init__(self,*[cpoint],**kws)
0085        self._cpoint=cpoint
0086        self.init()
0087
0088    def findSelf(self):
0089        self.set(-1./self._cpoint.conjugate())
0090        return True
0091
0092
0093class zConjugate(Complex._zPoint):
0094    """
0095*complex point* conjugate of the given **complex point**
0096    
0097    inherits
0098    
0099        `_zPoint`__
0100
0101__ class-base.abstracts._complex._zPoint.html        
0102    
0103    """
0104
0105    __doc_hints__=  {'factory':'zPoint',
0106                    'args':['zpoint'],
0107                    'qualifier':'CONJUGATE'}
0108
0109    def __init__(self,cpoint,**kws):
0110        Complex._zPoint.__init__(self,*[cpoint],**kws)
0111        self._cpoint=cpoint
0112        self.init()
0113
0114    def findSelf(self):
0115        cpoint=self._cpoint
0116        self.real=cpoint.real
0117        self.imag=-cpoint.imag
0118        return True
0119
0120
0121class u_to_zPoint(Complex._zPoint):
0122    """
0123*complex point* (stereographically) projected  from the given **point of 
0124the Riemann sphere**
0125    
0126    inherits
0127    
0128        `_zPoint`__
0129
0130__ class-base.abstracts._complex._zPoint.html        
0131    
0132    """
0133
0134    __doc_hints__=  {'factory':'zPoint',
0135                    'args':['upoint']}
0136
0137    def __init__(self,upoint,**kws):
0138        Complex._zPoint.__init__(self,*[upoint],**kws)
0139        self.upoint=upoint
0140        self.init()
0141
0142    def findSelf(self):
0143        t,p=self.upoint.polar()
0144        try:
0145            self.set(1.0/tan(t/2.0)*(math_E**complex(0,p)))
0146        except ZeroDivisionError:
0147            print self.__class__.__name__
0148            print """zpoint at infinity, returned False"""
0149            return False
0150        return True
0151
0152
0153class zInversePoint(Complex._zPoint):
0154    """
0155*complex point* inverse to the given **complex point** with respect to 
0156the given complex circle
0157    
0158    inherits
0159    
0160        `_zPoint`__
0161
0162__ class-base.abstracts._complex._zPoint.html        
0163    
0164    """
0165    __doc_hints__=  {'factory':'zPoint',
0166                    'args':['zpoint, zcircle']}
0167
0168    def __init__(self,cpoint,circle,**kws):
0169        Complex._zPoint.__init__(self,*[cpoint,circle],**kws)
0170        self._cpoint=cpoint
0171        self.circle=circle
0172        self.init()
0173
0174    def findSelf(self):
0175        h=self.circle._hermitian
0176        c=self._cpoint.conjugate()
0177        self.set((h.C*c+h.D)/(h.A*c+h.B)*-1)
0178        return True
0179
0180
0181class zPowerPoint(Complex._zPoint):
0182    """
0183*complex point* of intersection of the radical axis of the given **2 circles** 
0184and the line of the circles' centers
0185    
0186    inherits
0187    
0188        `_zPoint`__
0189
0190__ class-base.abstracts._complex._zPoint.html        
0191    
0192    """
0193
0194    __doc_hints__=  {'factory':'zPoint',
0195                    'args':['zcircle1,zcircle2']}
0196
0197    def __init__(self,circle1,circle2,**kws):
0198        Complex._zPoint.__init__(self,*[circle1,circle2],**kws)
0199        self.zCircle1=circle1
0200        self.zCircle2=circle2
0201        self.init()
0202
0203    def findSelf(self):
0204        z0=self.zCircle1._center
0205        z1 =self.zCircle2._center
0206        v=z1-z0
0207        d2=mod2(v)
0208        d=sqrt(d2)
0209        r02=self.zCircle1._radiusSquared
0210        r12=self.zCircle2._radiusSquared
0211        a = (r02 - r12 + d2 ) / (2*d)
0212        self.set(z0 + a * v / d)
0213        return True
0214
0215class zCircumPoint(Complex._zPoint):
0216    """
0217*complex point* on the given **complex circle** rotated by the given 
0218angle (in radians)
0219    
0220    inherits
0221    
0222        `_zPoint`__
0223
0224__ class-base.abstracts._complex._zPoint.html        
0225    
0226    """
0227
0228    __doc_hints__=  {'factory':'zPoint',
0229                    'args':['zcircle,<angle=float>']}
0230
0231    __opts__= Complex._zPoint.__opts__[:] +['angle']
0232
0233    def __init__(self,zcircle,**kws):
0234        self.zcircle=zcircle
0235        self.angle=kws.get("angle",0)
0236        Complex._zPoint.__init__(self,*[zcircle],**kws)
0237        self.init()
0238
0239    def findSelf(self):
0240        circle=self.zcircle
0241        self.set(circle._radius*(math_E**complex(0,self.angle))+circle._center)
0242        return True
0243
0244
0245class zHarmonic(Complex._zPoint):
0246    """
0247*complex* point harmonic conjugate to the 3rd given **complex point** with 
0248the respect to the 1st and 2nd given **complex points**
0249    
0250    inherits
0251    
0252        `_zPoint`__
0253
0254__ class-base.abstracts._complex._zPoint.html        
0255    
0256    """
0257
0258    __doc_hints__=  {'factory':'zPoint',
0259                    'args':['zpoint1,zpoint2,zpoint3']}
0260
0261
0262    def __init__(self,z1,z2,z3,**kws):
0263        Complex._zPoint.__init__(self,*[z1,z2,z3], **kws)
0264        self.c1= z1
0265        self.c2= z2
0266        self.c3= z3
0267        self.init()
0268
0269    def findSelf(self):
0270        t3 =(self.c2 + self.c3) * .5
0271        t2 = self.c2 -  t3
0272        t1 = self.c1 - t3
0273        d  = t1.real*t2.real+t1.imag*t2.imag
0274        m1 = mod2(t1)
0275        m2 = mod2(t2)
0276
0277        v=t2*(2.0*d) - t1*m2
0278        try:
0279            self.set(v/m1+t3)
0280        except ZeroDivisionError:
0281             print self.__class__.__name__
0282             print """reference points noe distinct, harmonic undefined, 
0283                   returning False"""
0284             return False
0285        return True
0286
0287class zRotation(Complex._zPoint):
0288    """
0289**complex point** determined by stereographic projection of the rotation of 
0290the second **complex point** argument, with the projection of the first **complex point** 
0291argument as the rotation axis, by the given angle.
0292    
0293    inherits
0294    
0295        `_zPoint`__
0296
0297__ class-base.abstracts._complex._zPoint.html        
0298    
0299    """
0300
0301    __doc_hints__=  {'factory':'zPoint',
0302                    'args':['zpoint,zpoint,<angle=float>']}
0303
0304    __opts__= Complex._zPoint.__opts__[:] +['angle']
0305
0306    def __init__(self,zcenter,cpoint,angle=PI,**kws):
0307        Complex._zPoint.__init__(self,*[cpoint,zcenter], **kws)
0308        self.angle=angle
0309        self.c_point=cpoint
0310        self.z_center=zcenter
0311        self.init()
0312
0313    def findSelf(self):
0314        self.set(self.c_point)
0315        center=self.z_center.uVector()
0316        self.uRotate(center,self.angle)
0317        return True
0318
0319
0320class z_uRotation(Complex._zPoint):
0321    """
0322*complex point* determined by stereographic projection of the rotation of 
0323the **complex point** argument, with the given **point of the Riemann sphere**
0324as the rotation axis, by the given angle.
0325    """
0326    __doc_hints__=  {'factory':'zPoint',
0327                    'args':['upoint,zpoint,<angle=float>']}
0328
0329    __opts__= Complex._zPoint.__opts__[:] +['angle']
0330
0331    def __init__(self,upoint,zpoint,angle=PI,**kws):
0332        Complex._zPoint.__init__(self,*[upoint,zpoint], **kws)
0333        self.angle=angle
0334        self.zpoint=zpoint
0335        self.upoint=upoint
0336        self.init()
0337
0338
0339    def findSelf(self):
0340        self.set(self.zpoint)
0341        self.uRotate(self.upoint,self.angle)
0342        return True
0343
0344
0345def zPoint(*args,**kws):
0346    """
0347'class factory' function returns instance of object derived from the 
0348_zPoint abstract class representing a point of the complex plane with position
0349fixed or dependant on its arguments
0350    """
0351
0352    from pygeo.base.abstracts._element import method_get
0353    from pygeo.base.support.pygeoexceptions import Argument_Type_Error
0354    import pygeo.base.abstracts._usphere as USphere
0355    from pygeo.base.support.pygeoconstants import ORTHO, CONJUGATE
0356
0357    __sigs__=[[],[float,float],[complex],[float],
0358               [Complex._zPoint],[Complex._zPoint, float],
0359               [USphere._uPoint],[Complex._zPoint,Complex._zCircle],
0360               [Complex._zCircle,Complex._zCircle],
0361               [Complex._zCircle],
0362               [Complex._zPoint,Complex._zPoint,Complex._zPoint],
0363               [Complex._zPoint,Complex._zPoint],[Complex._zPoint,Complex._zPoint],
0364               [USphere._uPoint,Complex._zPoint],[USphere._uPoint,Complex._zPoint]]
0365
0366    t,i = method_get(__sigs__,args)
0367
0368    if t is None:
0369        raise Argument_Type_Error(__sigs__,args)
0370    else:
0371        if i==0:
0372            if kws.get("angle"):
0373                return zPolarPoint(**kws)
0374            else:
0375                return zFixedPoint(**kws)
0376        elif i==1:
0377            return zFixedPoint(t[0],t[1],**kws)
0378        elif i==2:
0379            return zFixedPoint(t[0],**kws)
0380        elif i==3:
0381            return zFixedPoint(t[0],0,**kws)
0382        elif i==4:
0383            return zConjugate(t[0],**kws)
0384        elif i==5:
0385            if t[1]==ORTHO:
0386                return zOrthoPoint(t[0],**kws)
0387            elif t[1]==CONJUGATE:
0388                return zConjugate(t[0],**kws)
0389            else:
0390                return zConjugate(t[0],**kws)
0391        elif i==6:
0392            return u_to_zPoint(t[0],**kws)
0393        elif i==7:
0394            return zInversePoint(t[0],t[1],**kws)
0395        elif i==8:
0396            return zPowerPoint(t[0],t[1],**kws)
0397        elif i==9:
0398            return zCircumPoint(t[0],**kws)
0399        elif i==10:
0400            return zHarmonic(t[0],t[1],t[2],**kws)
0401        elif i==11:
0402            return zRotation(t[0],t[1],**kws)
0403        elif i==12:
0404            return zRoration(t[0],t[1],t[2],**kws)
0405        elif i==13:
0406            return z_uRotation(t[0],t[1],**kws)
0407        elif i==14:
0408            return z_uRotation(t[0],t[1],t[2],**kws)
0409
0410        else:
0411            raise Argument_Type_Error(__sigs__,args)