0001"""
0002**array of lines** with a defined geometric relationship
0003"""
0004
0005__Def__ = ['LineArray']
0006
0007__Classes__ = ['LinePencil', 'Regulus', 'PointMap', 'ArrayMap',
0008 'PlanesPencilIntersect', 'LineMap', 'CorrelationLines']
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._position3 import Position3
0017from pygeo.base.analytics.pygeomath import vector, cross3, array, solve, matrixmultiply, quadratic, transpose, PI, AlgebraError
0019from pygeo.base.support.pygeoopts import DO_TESTS
0020
0021
0022class LinePencil(Real._LineArray):
0023 """
0024*array of equidistant lines* on given **plane** and through given **point**
0025
0026 inherits
0027
0028 `_LineArray`__
0029
0030__ class-base.abstracts._real._LineArray.html
0031
0032 """
0033
0034 __doc_hints__= {'factory':'LineArray',
0035 'args':['point,plane'],
0036 'conditions':['point on the plane'],
0037 'otherwise':'None'}
0038
0039 __opts__ = Real._LineArray.__opts__ + ["start"]
0040
0041 def __init__(self,point,plane,**kws):
0042 self.point=point
0043 self.plane=plane
0044 Real._LineArray.__init__(self,*[point,plane],**kws)
0045 self.v=2*PI/self.density
0046 self.start=kws.get("start",0)
0047 self.init()
0048
0049 def findSelf(self):
0050 if DO_TESTS:
0051 t = self.point.onPlane(self.plane)
0052 else:
0053 t = True
0054 if t:
0055 cpoint = self.plane._s*self.drawradius
0056 for i,line in enumerate(self.lines):
0057 rad=i*self.v/2
0058 line.p1.set(cpoint.rotate(rad+self.start,self.plane._u)
0059 + self.point)
0060 line.p2.set(self.point)
0061 return True
0062 else:
0063 print self.__class__.__name__
0064 print "point not on plane, line array undefined, returned false"
0065 return False
0066
0067
0068class Regulus(Real._LineArray):
0069 """
0070*array of lines* transverse to the given **lines** through given **array of points**
0071
0072 inherits
0073
0074 `_LineArray`__
0075
0076__ class-base.abstracts._real._LineArray.html
0077
0078 """
0079 __doc_hints__= {'factory':'LineArray',
0080 'args':['pointarray,line1,line2'],
0081 'conditions':['lines distinct'],
0082 'otherwise':'None'}
0083
0084 def __init__(self,pointpencil,line1,line2,**kws):
0085 self.pointpencil=pointpencil
0086 self.line1=line1
0087 self.line2=line2
0088 Real._LineArray.__init__(self,*[pointpencil,line1,line2],**kws)
0089 self.extend=kws.get("extend",False)
0090 self.density=self.pointpencil.density
0091 self.init()
0092
0093 def findSelf(self):
0094 for line,point in zip(self,self.pointpencil):
0095 l1=self.line1
0096 l2=self.line2
0097 u1=cross3(l1.p1,l1.p2,point)
0098 d1=u1.dot(l1.p1)
0099 u2=cross3(l2.p1,l2.p2,point)
0100 d2=u2.dot(l2.p1)
0101 dir=u1.cross(u2)
0102 try:
0103 ip1 = vector(solve(
0104 array([u1,u2,dir]),
0105 array([d1,d2,0.])))
0106
0107 except AlgebraError:
0108 print self.__class__.__name__
0109 print """lines are not distinct, quadric undefined,
0110 returned False"""
0111 return False
0112 ip2= dir + ip1
0113 line.p1.toInterSection(ip1,ip2,self.line1.p1,self.line1.p2,
0114 test=False)
0115 line.p2.toInterSection(ip1,ip2,self.line2.p1,self.line2.p2,
0116 test=False)
0117 return True
0118
0119
0120class PointMap(Real._LineArray):
0121 """
0122*array of lines* connecting points of the projective correspondance
0123defined by the **1st list of 3 points** and the **2nd list of 3 points**
0124
0125 inherits
0126
0127 `_LineArray`__
0128
0129__ class-base.abstracts._real._LineArray.html
0130
0131 """
0132 __doc_hints__= {'factory':'LineArray',
0133 'args':['[point1,point2,point3],[point1a,point2a,point3a]']}
0134
0135 def __init__(self,points1,points2,**kws):
0136 self.p1a=points1[0]
0137 self.p1b=points1[1]
0138 self.s1=points1[2]
0139 self.p2a=points2[0]
0140 self.p2b=points2[1]
0141 self.s2=points2[2]
0142 args=points1 + points2
0143 Real._LineArray.__init__(self,*args,**kws)
0144 self.init()
0145
0146 def findSelf(self):
0147 for i, line in enumerate(self.lines):
0148 step=(1/float(len(self.lines)))*i
0149 line.p1.toInterpolated(self.p1a,self.p1b,step)
0150 line.p2.toCrossPoint(self.p1a,self.s1,self.p1b,
0151 line.p1,
0152 self.p2a,self.s2,self.p2b)
0153 return True
0154
0155
0156class ArrayMap(Real._LineArray):
0157 """
0158**array of lines** connecting the points of the **2 given point arrays**
0159
0160 inherits
0161
0162 `_LineArray`__
0163
0164__ class-base.abstracts._real._LineArray.html
0165
0166 """
0167 __doc_hints__= {'factory':'LineArray',
0168 'args':['pointarray1,pointarray2']}
0169
0170 def __init__(self,pointarray1,pointarray2,**kws):
0171 self.pa1=pointarray1
0172 self.pa2=pointarray2
0173 Real._LineArray.__init__(self,*[pointarray1,pointarray2],**kws)
0174 self.density=min(self.pa1.density,self.pa2.density)
0175 self.init()
0176
0177 def findSelf(self):
0178 for line,p1,p2 in zip(self.lines,self.pa1,self.pa2):
0179 line.p1.set(p1)
0180 line.p2.set(p2)
0181 return True
0182
0183
0184class PlanesPencilIntersect(Real._LineArray):
0185 """
0186**array of lines** of intersection of **2 given plane sheaves**
0187
0188 inherits
0189
0190 `_LineArray`__
0191
0192__ class-base.abstracts._real._LineArray.html
0193
0194 """
0195 __doc_hints__= {'factory':'LineArray',
0196 'args':['planepencil1,planepencil2'],
0197 'conditions':['plane pencils distinct'],
0198 'otherwise':'None'}
0199
0200 def __init__(self,planes1,planes2,**kws):
0201 self.planes1=planes1
0202 self.planes2=planes2
0203 Real._LineArray.__init__(self,*[planes1,planes2],**kws)
0204 self.drawlen=kws.get("drawlen",40)
0205 self.density=min(self.planes1.density,self.planes2.density)
0206 self.init()
0207
0208 def findSelf(self):
0209 planes1 =self.planes1
0210 planes2 = self.planes2
0211 for p1,p2,line in zip(planes1,planes2,self.lines):
0212 try:
0213 dir=p1._u.cross(p2._u)
0214 except IndexError:
0215 print self.__class__.__name__
0216 print """plane pencil empty, intersection array undefined,
0217 returned False"""
0218 return False
0219 try:
0220 line.p1.set(vector(solve(
0221 array([p1._u,p2._u,dir]),
0222 array([p1._d,p2._d,0.]))))
0223 except AlgebraError:
0224 print self.__class__.__name__
0225 print """plane pencils not distinct, intersection array
0226 undefined, returned False"""
0227 return False
0228 line.p2.set(dir*self.drawlen+line.p1)
0229 return True
0230
0231
0232class LineMap(Real._LineArray):
0233 """
0234*array of lines* through the points of the **point array** and the **given point**
0235
0236 inherits
0237
0238 `_LineArray`__
0239
0240__ class-base.abstracts._real._LineArray.html
0241
0242 """
0243 __doc_hints__= {'factory':'LineArray',
0244 'args':['pointarray,point']}
0245
0246 def __init__(self,pointarray,point,**kws):
0247 self.pa=pointarray
0248 self.point=point
0249 Real._LineArray.__init__(self,*[pointarray,point],**kws)
0250 self.density=self.pa.density
0251 self.init()
0252
0253 def findSelf(self):
0254 for point,line in zip(self.pa,self.lines):
0255 line.p1.set(point)
0256 line.p2.set(self.point)
0257 return True
0258
0259
0260class CorrelationLines(Real._LineArray):
0261 """
0262*array of lines* polar to the points of the given **point array** with respect
0263to the **given conic**
0264
0265 inherits
0266
0267 `_LineArray`__
0268
0269__ class-base.abstracts._real._LineArray.html
0270
0271 """
0272 __doc_hints__= {'factory':'LineArray',
0273 'args':['conic,pointarray']}
0274
0275 def __init__(self,conic,pointarray,**kws):
0276 self.conic=conic
0277 self.pa=pointarray
0278 self.x1z=Position3()
0279 self.x2z=Position3()
0280 Real._LineArray.__init__(self,*[conic,pointarray],**kws)
0281 self.density=self.pa.density
0282 self.init()
0283
0284 def findSelf(self):
0285 equat=self.conic.getPlane()
0286 C=self.conic.getC()
0287 for point,line in zip(self.pa,self.lines):
0288 L= matrixmultiply(C*2,point)
0289 tp1=array([0.,-L[2]/L[1],1.])
0290 tp2=array([-L[2]/L[0],0.,1.])
0291 cx = matrixmultiply(matrixmultiply(C,tp1),transpose(tp1))
0292 ax = matrixmultiply(matrixmultiply(C,tp2),transpose(tp2))
0293 bx =2*matrixmultiply(matrixmultiply(C,tp2),transpose(tp1))
0294 h=quadratic(ax,bx,cx)
0295 if h[0]:
0296 x1=tp1+tp2*h[0]
0297 x2=tp1+tp2*h[1]
0298 else:
0299 x1=tp1
0300 x2=tp2
0301 self.x1z.set(vector([x1[0]/x1[2],x1[1]/x1[2],0]))
0302 self.x2z.set(vector([x2[0]/x2[2],x2[1]/x2[2],0]))
0303 line.p1.fromXY(equat,self.x1z)
0304 line.p2.fromXY(equat,self.x2z)
0305 return True
0306
0307def LineArray(*args,**kws):
0308 """
0309'class factory' function returns instance of object derived from the _LineArray
0310abstract class representing an array of lines with a defined geoemtric relationship
0311 """
0312
0313 from pygeo.base.abstracts._element import method_get
0314 from pygeo.base.support.pygeoexceptions import Argument_Type_Error
0315 from pygeo.base.geometry_real.pointarrays import Conic
0316
0317 __sigs__=[[Real._PointArray,vector],[vector,Real._Plane],
0318 [vector,Real._Circle],[Real._PointArray,Real._Line,Real._Line],
0319 [list,list],
0320 [Real._PointArray,Real._PointArray],[Real._PlaneArray,Real._PlaneArray],
0321 [Conic,Real._PointArray]]
0322
0323 t,i = method_get(__sigs__,args)
0324
0325 if t is None:
0326 raise Argument_Type_Error(__sigs__,args)
0327 else:
0328 if i ==0:
0329 return LineMap(t[0],t[1],**kws)
0330 elif i==1 or i==2:
0331 return LinePencil(t[0],t[1],**kws)
0332 elif i==3:
0333 return Regulus(t[0],t[1],t[2],**kws)
0334 elif i==4:
0335 return PointMap(t[0],t[1],**kws)
0336 elif i==5:
0337 return ArrayMap(t[0],t[1],**kws)
0338 elif i==6:
0339 return PlanesPencilIntersect(t[0],t[1],**kws)
0340 elif i==7:
0341 return CorrelationLines(t[0],t[1],**kws)
0342 else:
0343 raise Argument_Type_Error(__sigs__,args)