0001"""
0002**circle** oriented in space
0003"""
0004__Def__ = ['Circle']
0005
0006__Classes__ = ['CircleOnPlane','CircumCircle', 'CenterCircle',
0007 'InscribedCircle','ExscribedCircle', 'OrthoCircle',
0008 'SphereCircle', 'SpheresIntersect']
0009
0010__all__= __Classes__ + __Def__
0011
0012__doc_hints__={'m_type':'factory'}
0013
0014import pygeo.base.abstracts._real as Real
0015
0016from pygeo.base.analytics.pygeomath import sqrt, cross3
0017from pygeo.base.support.pygeoopts import DO_TESTS
0018from pygeo.base.analytics._position3 import Position3
0019
0020
0021class CircumCircle(Real._Circle):
0022 """
0023*circle* passing through the **3 given points**
0024
0025 inherits
0026
0027 `_Circle`__
0028
0029__ class-base.abstracts._real._Circle.html
0030
0031 """
0032
0033 __doc_hints__= {'factory':'Circle',
0034 'args':['point1,point2,point3'],
0035 'qualifier':'CIRCUM',
0036 'conditions':['points distinct'],
0037 'otherwise':'None'}
0038
0039 def __init__(self,p1,p2,p3,**kws):
0040 self.p1=p1
0041 self.p2=p2
0042 self.p3=p3
0043 Real._Circle.__init__(self,*[p1,p2,p3],**kws)
0044 self.deps=[self._center]
0045 self._cpoint=self.p2
0046 self.init()
0047
0048 def findSelf(self):
0049 if self._center.toCircumCenter(self.p1,self.p2,self.p3):
0050 self._radiusSquared=self._center.distanceSquared(self._cpoint)
0051 self._radius=sqrt(self._radiusSquared)
0052 self.set_uds_fromPoints()
0053 return True
0054 else:
0055 self._u=Position3(0,0,1)
0056 self._s=Position3(0,0,1)
0057 self._d=0
0058 return False
0059
0060
0061class CenterCircle(Real._Circle):
0062 """
0063*circle* with first point at center, second on circumference and on the plane
0064of the **3 points**
0065
0066 inherits
0067
0068 `_Circle`__
0069
0070__ class-base.abstracts._real._Circle.html
0071
0072 """
0073
0074 __doc_hints__= {'factory':'Circle',
0075 'args':['point1,point2,point3'],
0076 'conditions':['points distinct'],
0077 'otherwise':'None'}
0078
0079 def __init__(self,p1,p2,p3,**kws):
0080 self.p1=p1
0081 self.p2=p2
0082 self.p3=p3
0083 Real._Circle.__init__(self,*[p1,p2,p3],**kws)
0084 self._cpoint=self.p2
0085 self._center=self.p1
0086 self.init()
0087
0088 def findSelf(self):
0089 self._radiusSquared=self._center.distanceSquared(self._cpoint)
0090 self._radius=sqrt(self._radiusSquared)
0091 try:
0092 self._u=cross3(self.p1,self.p2,self.p3).norm()
0093 self._d=self._u.dot(self.p1)
0094 self._s=(self.p1-self.p2).norm()
0095 return True
0096 except ZeroDivisionError:
0097 print self.__class__.__name__
0098 print "points are not distinct, circle undefined, returned False"
0099 return False
0100
0101
0102class InscribedCircle(Real._Circle):
0103 """
0104*circle* inscribed in the **3 given points'** triangle
0105
0106 inherits
0107
0108 `_Circle`__
0109
0110__ class-base.abstracts._real._Circle.html
0111
0112 """
0113
0114 __doc_hints__= {'factory':'Circle',
0115 'args':['point1,point2,point3'],
0116 'qualifier':'INSCRIBED',
0117 'conditions':['points distinct'],
0118 'otherwise':'None'}
0119
0120 def __init__(self,p1,p2,p3,**kws):
0121 self.p1=p1
0122 self.p2=p2
0123 self.p3=p3
0124 Real._Circle.__init__(self,*[p1,p2,p3],**kws)
0125 self.deps=[self._center,self._cpoint]
0126 self.init()
0127
0128 def findSelf(self):
0129 try:
0130 self._center.toInCenter(self.p1,self.p2,self.p3)
0131 self._cpoint.set(self._center)
0132 self._cpoint.toLine(self.p1,self.p2)
0133 self._radiusSquared=self._center.distanceSquared(self._cpoint)
0134 self._radius=sqrt(self._radiusSquared)
0135 self.set_uds_fromPoints()
0136 return True
0137 except ZeroDivisionError:
0138 print self.__class__.__name__
0139 print "points are not distinct, circle undefined, returned False"
0140 return False
0141
0142
0143class ExscribedCircle(Real._Circle):
0144 """
0145*circle* exscribed in the **3 given points'** triangle,
0146in the side opp the 1st point
0147
0148 inherits
0149
0150 `_Circle`__
0151
0152__ class-base.abstracts._real._Circle.html
0153
0154 """
0155
0156 __doc_hints__= {'factory':'Circle',
0157 'args':['point1,point2,point3'],
0158 'qualifier':'EXSCRIBED',
0159 'conditions':['points distinct'],
0160 'otherwise':'None'}
0161
0162 def __init__(self,p1,p2,p3,**kws):
0163 self.p1=p1
0164 self.p2=p2
0165 self.p3=p3
0166 Real._Circle.__init__(self,*[p1,p2,p3],**kws)
0167 self.deps=[self._center,self._cpoint]
0168 self.init()
0169
0170 def findSelf(self):
0171 try:
0172 self._center.toExCenter(self.p1,self.p2,self.p3)
0173 self._cpoint.set(self._center)
0174 self._cpoint.toLine(self.p1,self.p2)
0175 self._radiusSquared=self._center.distanceSquared(self._cpoint)
0176 self._radius=sqrt(self._radiusSquared)
0177 self.set_uds_fromPoints()
0178 return True
0179 except ZeroDivisionError:
0180 print self.__class__.__name__
0181 print "points are not distinct, circle undefined, returned False"
0182 return False
0183
0184
0185class OrthoCircle(Real._Circle):
0186 """
0187*circle* with center at the given **point** and orthogonal to the
0188given **circle**
0189
0190 inherits
0191
0192 `_Circle`__
0193
0194__ class-base.abstracts._real._Circle.html
0195
0196 """
0197
0198 __doc_hints__= {'factory':'Circle',
0199 'args':['circle,point'],
0200 'conditions':['point and circle are coplanar',
0201 'point exterior to circle'],
0202 'otherwise':'None; None'}
0203
0204 def __init__(self,circle,point,**kws):
0205 self.circle=circle
0206 self.point=point
0207 Real._Circle.__init__(self,*[circle,point],**kws)
0208 self.deps=[self._cpoint]
0209 self._center=self.point
0210 self.init()
0211
0212 def findSelf(self):
0213 if DO_TESTS:
0214 t=self.point.onPlane(self.circle)
0215 else:
0216 t =True
0217 if t:
0218 self._d = self.circle._d
0219 self._u.set(self.circle._u)
0220 self._s.set(self.circle._s)
0221 pdist= self.circle._center.distance(self._center)-self.circle._radius
0222 self._radiusSquared=rsqr = pdist*(2*self.circle._radius+pdist)
0223 if rsqr < 0:
0224 print self.__class__.__name__
0225 print """point is interior to circle, orthocircle through point as
0226 center is undefined, returned False"""
0227 return False
0228 self._radius=rad=sqrt(rsqr)
0229 self._cpoint.set(self._s*rad+self._center)
0230 return True
0231 else:
0232 print self.__class__.__name__
0233 print "circle and point are not coplanar, orthocircle undefined, returned False"
0234 return False
0235
0236
0237class SphereCircle(Real._Circle):
0238 """
0239*circle* section of the intersection of given **sphere** and given **plane**
0240
0241 inherits
0242
0243 `_Circle`__
0244
0245__ class-base.abstracts._real._Circle.html
0246
0247 """
0248 __doc_hints__= {'factory':'Circle',
0249 'args':['sphere,plane'],
0250 'conditions':['sphere and plane intersection is real'],
0251 'otherwise':'None'}
0252
0253 def __init__(self,sphere,plane,**kws):
0254 self.sphere=sphere
0255 self.plane=plane
0256 Real._Circle.__init__(self,*[sphere,plane],**kws)
0257 self.deps=[self._center,self._cpoint]
0258 self.init()
0259
0260 def findSelf(self):
0261 self._d = self.plane._d
0262 self._u.set(self.plane._u)
0263 self._s.set(self.plane._s)
0264 self._center.set(self.sphere._center)
0265 self._center.toPlane(self.plane)
0266 pdist = self._center.distanceSquared(self.sphere._center)
0267 self._radiusSquared = rsqr=self.sphere._radiusSquared-pdist
0268 if rsqr < 0:
0269 print self.__class__.__name__
0270 print "no real plane, sphere intersection, returned false"
0271 return False
0272 self._radius=rad=sqrt(rsqr)
0273 self._cpoint.set(self._s*rad+self._center)
0274 return True
0275
0276
0277class SpheresIntersect(Real._Circle):
0278 """
0279*circle* section determined by the intersection of the **2 given spheres**
0280
0281 inherits
0282
0283 `_Circle`__
0284
0285__ class-base.abstracts._real._Circle.html
0286
0287 """
0288 __doc_hints__= {'factory':'Circle',
0289 'args':['sphere1,sphere2'],
0290 'conditions':['spheres intersection is real',
0291 'spheres are not concentric'],
0292 'otherwise':'None; None'}
0293
0294 def __init__(self,sphere1,sphere2,**kws):
0295 self.sphere1=sphere1
0296 self.sphere2=sphere2
0297 Real._Circle.__init__(self,*[sphere1,sphere2],**kws)
0298 self.deps=[self._center,self._cpoint]
0299 self.init()
0300
0301 def findSelf(self):
0302 sphere1=self.sphere1
0303 sphere2=self.sphere2
0304 tnormal= sphere1._center - sphere2._center
0305 rsum = sphere1._radius+ sphere2._radius
0306 tlen= tnormal.mag2
0307 if tlen > rsum**2:
0308 print self.__class__.__name__
0309 print "spheres do not intersect, not real intersection, returned false"
0310 return False
0311 try:
0312 t = 0.5*(1.0+(sphere1._radiusSquared-sphere2._radiusSquared)/tlen)
0313 except ZeroDivisionError:
0314 print self.__class__.__name__
0315 print "spheres are concentric, no intersection defined, returned false"
0316 return False
0317 normal=tnormal*t
0318 self._d=normal.mag
0319 self._u.set(normal.norm())
0320 self.set_s_from_u(self._u)
0321 self._center.set(sphere1._center-normal)
0322 self._radiusSquared = rsqr=sphere1._radiusSquared - (t**2)*tlen
0323 if rsqr < 0:
0324 print self.__class__.__name__
0325 print "a sphere is interior to the other, not real intersection, returned false"
0326 return False
0327 self._radius=rad=sqrt(rsqr)
0328 self._cpoint.set(self._s*rad+self._center)
0329 return True
0330
0331class CircleOnPlane(Real._Circle):
0332 """
0333*circle* of the given **plane** with 1st given **point** at center, 2nd **point** on
0334circumference
0335
0336 inherits
0337
0338 `_Circle`__
0339
0340__ class-base.abstracts._real._Circle.html
0341
0342 """
0343
0344 __doc_hints__= {'factory':'Circle',
0345 'args':['point1,point2,plane'],
0346 'conditions':['points on plane'],
0347 'otherwise':'None'}
0348
0349 def __init__(self,p1,p2,plane,**kws):
0350 self.plane=plane
0351 self.p1=p1
0352 self.p2=p2
0353 Real._Circle.__init__(self,*[p1,p2,plane],**kws)
0354 self._cpoint=self.p2
0355 self._center=self.p1
0356 self.init()
0357
0358 def findSelf(self):
0359 if DO_TESTS:
0360 t = (self.p1.onPlane(self.plane) and self.p2.onPlane(self.plane))
0361 else:
0362 t = True
0363 if t:
0364 self._radiusSquared=self._center.distanceSquared(self._cpoint)
0365 self._radius=sqrt(self._radiusSquared)
0366 self._u.set(self.plane._u)
0367 self._d = self.plane._d
0368 self._s.set(self.plane._s)
0369 return True
0370 else:
0371 print self.__class__.__name__
0372 print "points not on plane, circle undefined, returned False"
0373 return False
0374
0375
0376
0377def Circle(*args,**kws):
0378 """
0379'class factory' function returns instance of object derived from the _Circle
0380abstract class representing the set of points of a plane equidistant from
0381a given point of the plane
0382 """
0383
0384 from pygeo.base.abstracts._element import method_get
0385 from pygeo.base.support.pygeoexceptions import Argument_Type_Error
0386 from pygeo.base.analytics.pygeomath import vector
0387 from pygeo.base.support.pygeoconstants import CIRCUM, INSCRIBED, EXSCRIBED
0388
0389 __sigs__=[[vector,vector,Real._Plane],
0390 [vector,vector,vector],[Real._Triangle],
0391 [vector,vector,vector,float],
0392 [Real._Triangle,float],[Real._Circle,vector],[Real._Sphere,Real._Plane],
0393 [Real._Sphere,Real._Sphere]]
0394
0395 t,i = method_get(__sigs__,args)
0396
0397 if t is None:
0398 raise Argument_Type_Error(__sigs__,args)
0399 else:
0400 if i ==0:
0401 return CircleOnPlane(t[0],t[1],t[2],**kws)
0402 elif i == 1:
0403 return CircumCircle(t[0],t[1],t[2],**kws)
0404 elif i == 2:
0405 return CircumCircle(t[0].p1,t[0].p2,t[0].p3,**kws)
0406 elif i==3:
0407 if t[3]== CIRCUM:
0408 return CircumCircle(t[0],t[1],t[2],**kws)
0409 elif t[3] == INSCRIBED:
0410 return InscribedCircle(t[0],t[1],t[2],**kws)
0411 elif t[3] == EXSCRIBED:
0412 return ExscribedCircle(t[0],t[1],t[2],**kws)
0413 else:
0414 raise Argument_Type_Error(__sigs__,args)
0415 elif i==4:
0416 if t[1]== CIRCUM:
0417 return CircumCircle(t[0].p1,t[0].p2,t[0].p3,**kws)
0418 elif t[1] == INSCRIBED:
0419 return InscribedCircle(t[0].p1,t[0].p2,t[0].p3,**kws)
0420 elif t[1] == EXSCRIBED:
0421 return ExscribedCircle(t[0].p1,t[0].p2,t[0].p3,**kws)
0422 else:
0423 raise Argument_Type_Error(__sigs__,args)
0424 elif i==5:
0425 return OrthoCircle(t[0],t[1],**kws)
0426 elif i==6:
0427 return SphereCircle(t[0],t[1],**kws)
0428 elif i==7:
0429 return SpheresIntersect(t[0],t[1],**kws)
0430 else:
0431 raise Argument_Type_Error(__sigs__,args)