0001"""
0002**array of points** on a defined curve in space
0003"""
0004
0005__Def__ = ['Curve']
0006
0007__Classes__ = ['Bezier', 'PcCurve']
0008
0009__all__= __Classes__+ __Def__
0010
0011__doc_hints__={'m_type':'factory'}
0012
0013import pygeo.base.abstracts._real as Real
0014
0015from pygeo.base.support.pygeoconstants import *
0016from pygeo.base.analytics.pygeomath import reshape, array, vector, transpose, matrixmultiply, ones
0018
0019
0020
0021class Bezier(Real._PointArray):
0022 """
0023*Bezier curve* with the **ordered list of points** as control points
0024
0025 inherits
0026
0027 `_PointArray`__
0028
0029__ class-base.abstracts._real._PointArray.html
0030
0031 """
0032 __doc_hints__= {'factory':'Curve',
0033 'args':['[list of points]']}
0034
0035 def __init__(self,inpoints,**kws):
0036 self.inpoints = inpoints
0037 Real._PointArray.__init__(self,*inpoints,**kws)
0038 coefs = self.getCoefs(len(self.inpoints)-1)
0039 bn = len(coefs)
0040 val=[]
0041 append=val.append
0042 for i in range (self.density+1):
0043 u=i/float(self.density)
0044 t =(1-u)
0045 for j in range(bn):
0046 cval = [coefs[j]*(t**(bn-j-1))*(u**j)]
0047 append(cval)
0048 self.U = reshape(array((val)),(self.density+1,bn))
0049 self.items =reshape(ones(3*len(self.inpoints),'d'),
0050 (len(self.inpoints),3))
0051 self.density=kws.get('density',25)
0052 self.color=kws.get('color',RED)
0053 self.linewidth=kws.get('linewidth',.3)
0054 self.drawpoints=kws.get("drawpoints",False)
0055 self.drawcurve=kws.get("drawcurve",True)
0056 self.density+=1
0057 self.init()
0058
0059 def getCoefs(self,fact):
0060 facts = []
0061 coefs = []
0062 nom=1
0063 f_append=facts.append
0064 c_append=coefs.append
0065 for i in range(fact):
0066 nom*=(i+1)
0067 f_append(nom)
0068 c_append(1.0)
0069 for i in range(1,fact):
0070 c_append(float(facts[fact-1]/(facts[i-1]*facts[fact-1-i])))
0071 c_append(1.0)
0072 return coefs
0073
0074 def findSelf(self):
0075 for i,inpoint in enumerate(self.inpoints):
0076 self.items[i] = inpoint
0077 for i,point in enumerate(self):
0078 r=matrixmultiply(
0079 transpose(self.items),self.U[i])
0080 point.set(vector(r))
0081 return True
0082
0083
0084class PcCurve(Real._PointArray):
0085 """
0086*cubic BSpline curve* with **1st and 2nd given points** as end points
0087and **3rd and 4th points** as control points
0088
0089 inherits
0090
0091 `_PointArray`__
0092
0093__ class-base.abstracts._real._PointArray.html
0094
0095 """
0096 __doc_hints__= {'factory':'Curve',
0097 'args':['point1,point2,point3,point4']}
0098
0099 def __init__(self,p1,p2,p1u,p2u,**kws):
0100 self.p1=p1
0101 self.p2=p2
0102 self.p1u=p1u
0103 self.p2u=p2u
0104 self.M = array([[2.,-2.,1.,1.],[-3.,3.,-2.,-1.],[0.,0.,1.,0.],
0105 [1.,0.,0.,0.]],'d')
0106 Real._PointArray.__init__(self,*[p1,p2,p1u,p2u],**kws)
0107 self.linewidth=kws.get('linewidth',.3)
0108 self.drawpoints=kws.get("drawpoints",False)
0109 self.drawcurve=kws.get("drawcurve",True)
0110 self.init()
0111
0112 def findSelf(self):
0113 pu1=self.p1u-self.p1
0114 pu2=self.p2-self.p2u
0115 B=array((self.p1,self.p2,pu1,pu2),'d')
0116 for i in range(self.density):
0117 u=i/float(self.density)
0118 U = array((u**3,u**2,u,1),'d')
0119 m= matrixmultiply(U,self.M)
0120 r = matrixmultiply(m,B)
0121 self.points[i].set(vector(r))
0122 return True
0123
0124def Curve(*args,**kws):
0125 """
0126'class factory' function returns instance of object derived from
0127the _PointArray abstract class representing an array of points on
0128a defined curve
0129 """
0130
0131 from pygeo.base.abstracts._element import method_get
0132 from pygeo.base.support.pygeoexceptions import Argument_Type_Error
0133
0134 __sigs__=[[list],[tuple],[vector,vector,vector,vector]]
0135
0136 t,i = method_get(__sigs__,args)
0137
0138 if t is None:
0139 raise Argument_Type_Error(__sigs__,args)
0140 else:
0141 if i==0 or i==1:
0142 return Bezier(t[0],drawcurve=True,**kws)
0143 elif i==2:
0144 return PcCurve(t[0],t[1],t[2],t[3],drawcurve=True,**kws)
0145 else:
0146 raise Argument_Type_Error(__sigs__,args)