0001"""
0002**point** determined in respect to an inversive relationship with 
0003a given geometric objects
0004"""
0005
0006__Def__ =       ['Inversion']
0007
0008__Classes__ =   ['SpherePole', 'CirclePole', 'CircleInversion',
0009                'SphereInversion','ConicPole']
0010
0011__all__= __Classes__ + __Def__
0012
0013__doc_hints__=  {'m_type':'factory'}
0014
0015import pygeo.base.abstracts._real as Real
0016
0017from pygeo.base.analytics.pygeomath import array,matrixmultiply, inverse
0018from pygeo.base.support.pygeoopts import DO_TESTS
0019
0020
0021class SpherePole(Real._Point):
0022    """
0023*point* polar to given **sphere** with respect to a given **plane**
0024    
0025    inherits
0026    
0027        `_Point`__
0028
0029__ base.abstracts._real._Point.html        
0030    
0031    """
0032
0033    __doc_hints__=  {'factory':'Inversion',
0034                    'args':['plane,sphere'],
0035                    'conditions': ['line not on sphere center'],
0036                    'otherwise': 'point at [MAX,MAX,MAX]'}
0037
0038    def __init__(self,plane,sphere,**kws):
0039        self.plane=plane
0040        self.sphere=sphere
0041        self.tmp=Real._Point()
0042        Real._Point.__init__(self,*[plane,sphere],**kws)
0043        self.init()
0044
0045    def findSelf(self):
0046        self.tmp.set(self.sphere._center)
0047        self.tmp.toPlane(self.plane)
0048        return self.toInvertPoint(self.sphere,self.tmp)
0049
0050
0051class CirclePole(Real._Point):
0052    """
0053*point* polar to given **line** with respect to a given coplanar **circle**
0054    
0055    inherits
0056    
0057        `_Point`__
0058
0059__ base.abstracts._real._Point.html        
0060    
0061    """
0062
0063    __doc_hints__=  {'factory':'Inversion',
0064                    'args':['line,circle'],
0065                    'conditions': ['line and circle are coplanar'],
0066                    'otherwise': 'Undefined'}
0067
0068    def __init__(self,line,circle,**kws):
0069        self.line=line
0070        self.circle=circle
0071        self.tmp=Real._Point()
0072        Real._Point.__init__(self,*[line,circle],**kws)
0073        self.init()
0074
0075    def findSelf(self):
0076        self.tmp.set(self.circle._center)
0077        if DO_TESTS:
0078            t=(self.line.p1.onPlane(self.circle) and
0079                self.line.p2.onPlane(self.circle))
0080        else:
0081            t=True
0082        if t:
0083            self.tmp.toLine(self.line.p1,self.line.p2)
0084            return self.toInvertPoint(self.circle,self.tmp)
0085        else:
0086            print self.__class__
0087            print """circle and line not coplanar, no Pole defined, 
0088                    returned False"""
0089            return False
0090
0091
0092class ConicPole(Real._Point):
0093    """
0094*point* polar to given **line** with respect to a given coplanar **conic**
0095    
0096    inherits
0097    
0098        `_Point`__
0099
0100__ base.abstracts._real._Point.html        
0101    
0102    """
0103
0104    __doc_hints__=  {'factory':'Inversion',
0105                    'args':['line,conic'],
0106                    'conditions': ['line and conic are coplanar'],
0107                    'otherwise': 'None'}
0108
0109    def __init__(self,line,conic,**kws):
0110        self.conic=conic
0111        self.line=line
0112        Real._Point.__init__(self,*[line,conic],**kws)
0113        self.init()
0114
0115    def findSelf(self):
0116        if DO_TESTS:
0117            t=(self.line.p1.coPlanar(self.conic.p1,self.conic.p2,
0118                                    self.conic.p3)
0119               and self.line.p2.coPlanar(self.conic.p1,self.conic.p2,
0120                                    self.conic.p3))
0121        else:
0122            t=True
0123        if t:
0124            C=self.conic.getC()
0125            h=self.line.homogenous_XY()
0126            equat=self.conic.getPlane()
0127            tp = matrixmultiply(inverse(C),h)
0128            tpz=array([tp[0]/tp[2],tp[1]/tp[2],0])
0129            return self.fromXY(equat,tpz)
0130        else:
0131            print self.__class__
0132            print """conic and line not coplanar, no Pole defined, 
0133                    returned False"""
0134            return False
0135
0136
0137class CircleInversion(Real._Point):
0138    """
0139*point* inverse to given **point** with respect to a given coplanar **circle**
0140    
0141    inherits
0142    
0143        `_Point`__
0144
0145__ base.abstracts._real._Point.html        
0146    
0147    """
0148
0149    __doc_hints__=  {'factory':'Inversion',
0150                    'args':['point,circle'],
0151                    'conditions': ['line and circle are coplanar'],
0152                    'otherwise': 'None'}
0153
0154    def __init__(self,point,circle,**kws):
0155        self.point=point
0156        self.circle=circle
0157        Real._Point.__init__(self,*[point,circle],**kws)
0158        self.init()
0159
0160    def findSelf(self):
0161        if DO_TESTS:
0162            t=self.point.onPlane(self.circle)
0163        else:
0164            t=True
0165        if t:
0166             return self.toInvertPoint(self.circle,self.point)
0167        else:
0168             print self.__class__
0169             print """point not on plane of circle, inversion failed, 
0170                  returned False"""
0171             return False
0172
0173
0174class SphereInversion(Real._Point):
0175    """
0176*point* inverse to given **point** with respect to a given **sphere**
0177
0178    inherits
0179    
0180        `_Point`__
0181
0182__ base.abstracts._real._Point.html        
0183
0184    """
0185
0186    __doc_hints__=  {'factory':'Inversion',
0187                    'args':['point,sphere'],
0188                    'conditions': ['point not sphere center'],
0189                    'otherwise': 'point at [MAX,MAX,MAX]'}
0190
0191    def __init__(self,point,sphere,**kws):
0192        self.point=point
0193        self.sphere=sphere
0194        Real._Point.__init__(self,*[point,sphere],**kws)
0195        self.init()
0196
0197    def findSelf(self):
0198        return self.toInvertPoint(self.sphere,self.point)
0199
0200def Inversion(*args,**kws):
0201    """
0202'class factory' function returns instance of object derived from the _Point 
0203abstract class determined in respect to an inversive relationship with a 
0204given geometric objects
0205    """
0206
0207    from pygeo.base.abstracts._element import method_get
0208    from pygeo.base.support.pygeoexceptions import Argument_Type_Error
0209    from pygeo.base.analytics.pygeomath import vector
0210    from pygeo.base.geometry_real.pointarrays import Conic
0211
0212    __sigs__=[[Real._Plane,Real._Sphere],[Real._Circle,Real._Sphere],
0213              [Real._Line,Real._Circle], [Real._Line,Conic],
0214              [vector,Real._Circle],[vector,Real._Sphere]]
0215
0216    t,i=method_get(__sigs__,args)
0217
0218    if t is  None:
0219        raise Argument_Type_Error(__sigs__,args)
0220    else:
0221        if i==0 or i==1:
0222            return SpherePole(t[0],t[1],**kws)
0223        elif i==2:
0224            return CirclePole(t[0],t[1],**kws)
0225        elif i==2:
0226            return CirclePole(t[0],t[1],**kws)
0227        elif i==3:
0228            return ConicPole(t[0],t[1],**kws)
0229        elif i==4:
0230            return CircleInversion(t[0],t[1],**kws)
0231        elif i==5:
0232            return SphereInversion(t[0],t[1],**kws)
0233        else:
0234            raise Argument_Type_Error(__sigs__,args)