0001"""
0002**point** defined in relation to the the division of a given geoemtric object
0003in a given ratio or metric
0004"""
0005
0006__Def__ = ['Divider']
0007
0008__Classes__ = ['LineDivider', 'LineCut', 'CrossPoint', 'Harmonic',
0009 'CircumPoint']
0010
0011__all__= __Classes__ + __Def__
0012
0013__doc_hints__= {'m_type':'factory'}
0014
0015import pygeo.base.abstracts._real as Real
0016
0017from pygeo.base.support.pygeoopts import DO_TESTS
0018from pygeo.base.analytics.pygeomath import PI
0019
0020
0021class LineDivider(Real._Point):
0022 """
0023*point* dividing the given **line** segment in the given **ratio**
0024
0025 inherits
0026
0027 `_Point`__
0028
0029__ base.abstracts._real._Point.html
0030
0031 """
0032 __doc_hints__= {'factory':'Divider',
0033 'args':['line, ratio=<numeric>'],
0034 'default':'midpoint of segment (i.e., ratio=.5)'}
0035
0036 __opts__= Real._Point.__opts__[:] + ["ratio"]
0037
0038 def __init__(self,line,**kws):
0039 self.line=line
0040 self.ratio=kws.get('ratio',.5)
0041 Real._Point.__init__(self,*[line],**kws)
0042 self.extend=kws.get("extend",True)
0043 self.lines=[self.line]
0044 self.init()
0045
0046 def findSelf(self):
0047 self.toInterpolated(self.line.p1,self.line.p2,self.ratio)
0048 return True
0049
0050
0051class LineCut(Real._Point):
0052 """
0053*point* of given **line** dividing it so the segment equals distance between
0054given **2 points** <or 2nd given **line segments** endpoints>.
0055
0056 inherits
0057
0058 `_Point`__
0059
0060__ base.abstracts._real._Point.html
0061
0062 """
0063 __doc_hints__= {'factory':'Divider',
0064 'args':['line, point1, point2','line1,line2']}
0065
0066 def __init__(self,line,p1,p2,**kws):
0067 self.line=line
0068 self.p1=p1
0069 self.p2=p2
0070 Real._Point.__init__(self,*[line,p1,p2],**kws)
0071 self.extend=kws.get("extend",True)
0072 self.lines=[self.line]
0073 self.init()
0074
0075 def findSelf(self):
0076 v=(self.line.p2-self.line.p1).norm()
0077 d=self.p1.distance(self.p2)
0078 self.set(v*d + self.line.p1)
0079 return True
0080
0081
0082class CrossPoint(Real._Point):
0083 """
0084point equalizing cross ratio of second **3 point list** to first **4 point list**
0085
0086 inherits
0087
0088 `_Point`__
0089
0090__ base.abstracts._real._Point.html
0091
0092 """
0093 __doc_hints__= {'factory':'Divider',
0094 'args':['[p1a,p1b,p1c,p1d],[p2a,p2a,p2b,p2c]'],
0095 'conditions': ['4 point set collinear and 3 point set collinear'],
0096 'otherwise': 'undefined'}
0097
0098 def __init__(self,list1,list2,**kws):
0099 self.p1=list1[0]
0100 self.p2=list1[1]
0101 self.p3=list1[2]
0102 self.p4=list1[3]
0103 self.p1a=list2[0]
0104 self.p2a=list2[1]
0105 self.p3a=list2[2]
0106 args=list1+list2
0107 Real._Point.__init__(self, *args,**kws)
0108 self.init()
0109
0110 def findSelf(self):
0111 if DO_TESTS:
0112 t= (self.p1.coLinear(self.p2,self.p3)
0113 and self.p1.coLinear(self.p3,self.p4)
0114 and self.p1a.coLinear(self.p2a,self.p3a))
0115 else:
0116 t=True
0117 if t:
0118 return self.toCrossPoint(self.p1,self.p2,self.p3,
0119 self.p4,self.p1a,self.p2a,self.p3a)
0120 else:
0121 print self.__class__.__name__
0122 print """reference or target points are not collinear, crosspoint
0123 undefined, returned False"""
0124 return False
0125
0126class Harmonic(Real._Point):
0127 """
0128*point* that is harmonic conjugate of 1st given **point** with respect
0129to succeeding given **2 points**
0130
0131 inherits
0132
0133 `_Point`__
0134
0135__ base.abstracts._real._Point.html
0136
0137 """
0138
0139 __doc_hints__= {'factory':'Divider',
0140 'args':['point1, point2, point3'],
0141 'conditions': ['points collinear'],
0142 'otherwise': 'undefined'}
0143
0144 def __init__(self,p1,p2,p3,**kws):
0145 self.p1=p1
0146 self.p2=p2
0147 self.p3=p3
0148 Real._Point.__init__(self,*[p1,p2,p3],**kws)
0149 self.init()
0150
0151 def findSelf(self):
0152 if DO_TESTS:
0153 t = self.p1.coLinear(self.p2,self.p3)
0154 else:
0155 t =True
0156 if t:
0157 self.toHarmonic(self.p1,self.p2,self.p3)
0158 return True
0159 else:
0160 print self.__class__.__name__
0161 print """points are not collinear, harmonic not defined,
0162 returned False"""
0163 return False
0164
0165class CircumPoint(Real._Point):
0166 """
0167*point* on **circle** circumference rotated by the given **angle**
0168
0169 inherits
0170
0171 `_Point`__
0172
0173__ base.abstracts._real._Point.html
0174
0175 """
0176 __doc_hints__= {'factory':'Divider',
0177 'args':['circle, <angle = numeric>'],
0178 'default':'angle=PI'}
0179
0180 __opts__= Real._Point.__opts__[:] + ["angle"]
0181
0182 def __init__(self,circle,**kws):
0183 self.circle=circle
0184 self.angle=kws.get('angle',PI)
0185 Real._Point.__init__(self,*[circle],**kws)
0186 self.init()
0187
0188 def findSelf(self):
0189 self.set(self.circle._cpoint)
0190 return self.toCircumPoint(self.circle,self.angle)
0191
0192def Divider(*args,**kws):
0193 """
0194'class factory' function returns instance of object derived from the
0195*_Point* abstract class defined in relation to the the division of
0196a given geoemtric object in a given ratio or metric
0197 """
0198
0199 from pygeo.base.abstracts._element import method_get
0200 from pygeo.base.support.pygeoexceptions import Argument_Type_Error
0201 from pygeo.base.analytics.pygeomath import vector
0202
0203 __sigs__ = [[Real._Line],[Real._Line,float],[Real._Line,vector,vector],
0204 [Real._Line,Real._Line], [vector, vector,vector],
0205 [list,list], [Real._Circle]]
0206
0207 t,i = method_get(__sigs__,args)
0208
0209 if t is None:
0210 raise Argument_Type_Error(__sigs__,args)
0211 else:
0212 if i == 0:
0213 return LineDivider(t[0],**kws)
0214 elif i == 1:
0215 return LineDivider(t[0],t[1],**kws)
0216 elif i == 2:
0217 return LineCut(t[0],t[1],t[2],**kws)
0218 elif i == 3:
0219 return LineCut(t[0],t[1].p1,t[1].p2,**kws)
0220 elif i == 4:
0221 return Harmonic(t[0],t[1],t[2],**kws)
0222 elif i == 5:
0223 if (len(t[0])==4 and len(t[1])==3):
0224 return CrossPoint(t[0],t[1],**kws)
0225 else:
0226 raise Argument_Type_Error(__sigs__,args)
0227 elif i == 6:
0228 return CircumPoint(t[0],**kws)
0229 else:
0230 raise Argument_Type_Error(__sigs__,args)