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)