0001"""
0002**circles** of the *complex plane*  
0003"""
0004
0005__Def__ = [ 'zCircle']
0006
0007
0008__Classes__ = ['zUnitCircle','zCircleFromPoints', 'zCircumCircle', 'zOrthoCircle',
0009 'zOrthoCircle_Circum', 'zInverseCircle', 'u_to_zCircle',
0010 'zFundamentalCircle']
0011
0012__all__ = __Classes__ + __Def__
0013
0014__doc_hints__={'m_type':'factory'}
0015
0016
0017import pygeo.base.abstracts._complex as Complex
0018import pygeo.base.abstracts._usphere as USphere
0019
0020from pygeo.base.analytics._cposition import CPosition
0021from pygeo.base.analytics.pygeomath import sqrt, determinant, Hermitian
0022
0023
0024class zUnitCircle(Complex._zCircle):
0025    """"
0026*complex circle* with center at origin center and unit radius
0027    
0028    inherits
0029    
0030        `_zCircle`__
0031
0032__ class-base.abstracts._complex._zCircle.html        
0033    
0034    """
0035
0036    __doc_hints__=  {'factory':'zCircle',
0037                    'args':['None']}
0038
0039    def __init__(self,**kws):
0040        Complex._zCircle.__init__(self,**kws)
0041        self._center = CPosition()
0042        self._radius=1
0043        self.set_hermitian_from_radius()
0044        self.init()
0045
0046
0047class zCircleFromPoints(Complex._zCircle):
0048    """
0049*complex circle* with the first given **zpoint** as center
0050and the second given **zpoint** on the circumference
0051    
0052    inherits
0053    
0054        `_zCircle`__
0055
0056__ class-base.abstracts._complex._zCircle.html        
0057    
0058    """
0059    __doc_hints__=  {'factory':'zCircle',
0060                    'args':['zpoint1,zpoint2'],
0061                    'conditions':['points distince'],
0062                    'otherwise': 'None'}
0063
0064    def __init__(self,center,circum,**kws):
0065        Complex._zCircle.__init__(self,*[center,circum],**kws)
0066        self._center = center
0067        self._cpoint = circum
0068        self.fixed=kws.get('fixed',False)
0069        if self.fixed:
0070            self.set_radius_from_cpoint()
0071        self.init()
0072
0073    def findSelf(self):
0074        if not self.fixed:
0075            self.set_radius_from_cpoint()
0076        self.set_hermitian_from_radius()
0077        return True
0078
0079
0080class zCircumCircle(Complex._zCircle):
0081    """
0082*complex circle* through the given **3 zpoints**
0083    
0084    inherits
0085    
0086        `_zCircle`__
0087
0088__ class-base.abstracts._complex._zCircle.html        
0089    
0090    """
0091
0092    __doc_hints__=  {'factory':'zCircle',
0093                    'args':['zpoint1,zpoint2, zpoint3'],
0094                    'conditions':['points distince'],
0095                    'otherwise': 'None'}
0096
0097    def __init__(self,z1,z2,z3,**kws):
0098        Complex._zCircle.__init__(self,*[z1,z2,z3],**kws)
0099        self.c1=z1
0100        self.c2=z2
0101        self.c3=z3
0102        self._cpoint=self.c3
0103        self.deps=[self._center]
0104        self.init()
0105
0106    def findSelf(self):
0107      vxs = self.c3 - self.c1
0108      vxt = self.c2 - self.c1
0109      try:
0110         v=vxs/vxt
0111      except ZeroDivisionError:
0112         print self.__class__.__name__
0113         print "refence points not distinct,returning false"
0114         return False
0115      d=v.mod2()
0116      try:
0117         c=(v-d)/(v-v.conjugate())
0118      except ZeroDivisionError:
0119         print self.__class__.__name__
0120         print "refence points colinear,returning false"
0121         return False
0122      self._center.set(vxt*c+self.c1)
0123      self._radiusSquared=self._center.distanceSquared(self._cpoint)
0124      self._radius=sqrt(self._radiusSquared)
0125      self.set_hermitian_from_radius()
0126      return True
0127
0128class zOrthoCircle(Complex._zCircle):
0129    """
0130*complex circle* orthogonal to the given **complex circle** , with
0131given **zpoint** as center
0132    
0133    inherits
0134    
0135        `_zCircle`__
0136
0137__ class-base.abstracts._complex._zCircle.html        
0138    
0139    """
0140
0141    __doc_hints__=  {'factory':'zCircle',
0142                    'args':['zcircle,zpoint']}
0143
0144    def __init__(self,circle,center,**kws):
0145        Complex._zCircle.__init__(self,*[circle,center],**kws)
0146        self.circle=circle
0147        self._center=center
0148        self.deps=[self._cpoint]
0149        self.init()
0150
0151    def findSelf(self):
0152        self._radiusSquared=(self.circle._center-self._center).mod2()-self.circle._radiusSquared
0153        try:
0154            self._radius=sqrt(self._radiusSquared)
0155        except ValueError:
0156            self._radius=0
0157        self.set_hermitian_from_radius()
0158        return True
0159
0160class zOrthoCircle_Circum(Complex._zCircle):
0161    """
0162*complex circle* orthogonal to the given **complex circle**, 
0163and through the given **2 zpoint** arguments.
0164    
0165    inherits
0166    
0167        `_zCircle`__
0168
0169__ class-base.abstracts._complex._zCircle.html        
0170    
0171    """
0172
0173    __doc_hints__=  {'factory':'zCircle',
0174                    'args':['zcircle,zpoint1,zpoint2'],
0175                    'conditions':['points distince'],
0176                    'otherwise': 'None'}
0177
0178    def __init__(self,circle,z1,z2,**kws):
0179        Complex._zCircle.__init__(self,*[circle,z1,z2],**kws)
0180        self.circle=circle
0181        self.c1=c1=z1
0182        self.c2=c2=z2
0183        self._cpoint=c2
0184        self.deps=[self._center]
0185        self.init()
0186
0187    def findSelf(self):
0188        h=self.circle._hermitian
0189        c=self.c1.conjugate()
0190        ipoint= (h.C*c+h.D)/(h.A*c+h.B)*-1
0191        vxs = self.c1 - ipoint
0192        vxt = self.c2 - ipoint
0193        d1  = vxs.real*vxt.real+vxs.imag*vxt.imag
0194        d2  = vxs.mod2()
0195        d3  = vxt.mod2()
0196        den = 2.0*(d2*d3-d1*d1)
0197        try:
0198            f1=(d2-d1)/den*d3
0199        except ZeroDivisionError:
0200            print self.__class__.__name__
0201            print "cirumference points at not unique, returning False"
0202            return False
0203        try:
0204            f2=(d3-d1)/den*d2
0205        except:
0206            return False
0207        vxs *= f1
0208        vxt *= f2
0209        self._center.set(vxs+vxt+ ipoint)
0210        self.set_radius_from_cpoint()
0211        self.set_hermitian_from_radius()
0212        return True
0213
0214class zInverseCircle(Complex._zCircle):
0215    """
0216*complex circle* inverse to the second given **zcircle** argument with respect
0217to the first given **zcircle**
0218    
0219    inherits
0220    
0221        `_zCircle`__
0222
0223__ class-base.abstracts._complex._zCircle.html        
0224    
0225    """
0226
0227    __doc_hints__=  {'factory':'zCircle',
0228                    'args':['zcircle1,zcircle2'],
0229                    'qualifier':'INVERSE'}
0230
0231    def __init__(self,base_circle,i_circle,**kws):
0232        Complex._zCircle.__init__(self,*[base_circle,i_circle],**kws)
0233        self.circle1=base_circle
0234        self.circle2=i_circle
0235        self.deps=[self._center,self._cpoint]
0236        self.init()
0237
0238    def findSelf(self):
0239        h0=self.circle1._hermitian
0240        h1=self.circle2._hermitian
0241        d0=h0.A*h1.D+h1.A*h0.D - h0.B*h1.C-h1.B*h0.C
0242        d1=h0.B*h0.C-h0.A*h0.D
0243        self._hermitian=h0*d0+h1*d1
0244        self.set_radius_from_hermitian()
0245        return True
0246
0247
0248class u_to_zCircle(Complex._zCircle):
0249    """
0250*complex circle* as the stereographic projection of the given **spheric section 
0251of the Riemann sphere** to the complex plane
0252    
0253    inherits
0254    
0255        `_zCircle`__
0256
0257__ class-base.abstracts._complex._zCircle.html        
0258    
0259    """
0260
0261    __doc_hints__=  {'factory':'zCircle',
0262                    'args':['ucircle']}
0263
0264    def __init__(self,ucircle,**kws):
0265        Complex._zCircle.__init__(self,*[ucircle],**kws)
0266        self.rcircle=ucircle
0267        self.deps=[self._center,self._cpoint]
0268        self.init()
0269
0270    def findSelf(self):
0271       a=self.rcircle._u.x
0272       b=self.rcircle._u.y
0273       c=self.rcircle._u.z
0274       d=self.rcircle._d
0275       A=(d-c)*.5
0276       B=(a-b*complex(0,1))*-.5
0277       C=B.conjugate()
0278       D=(d+c)*.5
0279       self._hermitian=Hermitian([[A,B],[C,D]])
0280       self.set_radius_from_hermitian()
0281       return True
0282
0283class zFundamentalCircle(Complex._zCircle):
0284    """
0285*complex circle*  by which the first **zcircle** argument is tranformed to 
0286second **zcircle** argument by inversion . required 'alt=FUNDAMENTAL' keyword 
0287    
0288    inherits
0289    
0290        `_zCircle`__
0291
0292__ class-base.abstracts._complex._zCircle.html        
0293    
0294    """
0295
0296    __doc_hints__=  {'factory':'zCircle',
0297                    'args':['zcircle1,zcircle2'],
0298                    'qualifier':'FUNDAMENTAL'}
0299
0300    __opts__= USphere._uFreePosition.__opts__[:] + ["alt"]
0301
0302    def __init__(self,circle1,circle2,**kws):
0303        Complex._zCircle.__init__(self,*[circle1,circle2],**kws)
0304        self.circle1=circle1
0305        self.circle2=circle2
0306        self.deps=[self._center,self._cpoint]
0307        self.init()
0308
0309    def findSelf(self):
0310        h1=self.circle1._hermitian
0311        h2=self.circle2._hermitian
0312        d1=determinant(h1)
0313        d2=determinant(h2)
0314        y=-sqrt(d1/d2)
0315        self._hermitian=h1+h2*y
0316        self.set_radius_from_hermitian()
0317        return True
0318
0319def zCircle(*args,**kws):
0320    """
0321'class factory' function returns instance of object derived from the 
0322_zCircle abstract class representing the locus of points equidistant 
0323from a given point of the complex plane
0324    """
0325
0326    from pygeo.base.abstracts._element import method_get
0327    from pygeo.base.support.pygeoexceptions import Argument_Len_Error,Argument_Type_Error
0328    from pygeo.base.support.pygeoconstants import FUNDAMENTAL, INVERSE
0329
0330    __sigs__=[[Complex._zPoint,Complex._zPoint],
0331             [Complex._zPoint,Complex._zPoint,Complex._zPoint],
0332             [Complex._zCircle,Complex._zPoint],
0333             [Complex._zCircle,Complex._zPoint,Complex._zPoint],
0334             [Complex._zCircle,Complex._zCircle],
0335             [USphere._uCircle],[]]
0336    t,i = method_get(__sigs__,args)
0337
0338    if t is None:
0339        raise Argument_Type_Error(__sigs__,args)
0340    else:
0341        if i==0:
0342            return zCircleFromPoints(t[0],t[1],**kws)
0343        elif i==1:
0344            return zCircumCircle(t[0],t[1],t[2],**kws)
0345        elif i==2:
0346            return zOrthoCircle(t[0],t[1],**kws)
0347        elif i==3:
0348            return zOrthoCircle_Circum(t[0],t[1],t[2],**kws)
0349        elif i==4:
0350            alt=kws.get("alt")
0351            if alt:
0352                if alt==FUNDAMENTAL:
0353                    return zFundamentalCircle(t[0],t[1],**kws)
0354                elif alt==INVERSE:
0355                    return zInverseCircle(t[0],t[1],**kws)
0356                else:
0357                    raise Argument_Type_Error(__sigs__,args)
0358            else:
0359                return zInverseCircle(t[0],t[1],**kws)
0360        elif i==5:
0361            return u_to_zCircle(t[0],**kws)
0362        elif i==6:
0363            return zUnitCircle(**kws)
0364        else:
0365            raise Argument_Type_Error(__sigs__,args)