Parametric curves and surfaces
Sample code to draw a Bezier curve
P: a list of points.
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
import math
dim=len(P)-1
def u(x,nu):
return x**nu
def v(x,nu):
return (1-x)**(dim-nu)
def nv(nu):
return math.factorial(dim)/(math.factorial(dim-nu)*math.factorial(nu))
tt=list()
for i in rs.frange(0,1.0,0.01):
f=list()
tt.append(f)
for j in range(0,dim+1):
f.append(nv(j)*u(i,j)*v(i,j))
a=list()
print tt
for s in tt:
PP=rg.Point3d(0,0,0)
for d in range(0,dim+1):
PP=PP+s[d]*P[d]
a.append(PP)
Sample code to draw a NURBS curve
P: a list of points.
import rhinoscriptsyntax as rs
import Rhino.Geometry as rg
import math
ddim=dim-1
N=len(P)
nSeg=N-1
knot=range(N-ddim+1)
startK=knot[0]
endK=knot[knot.Count-1]
for i in range(ddim):
knot.insert(0,startK)
for i in range(ddim):
knot.insert(knot.Count,endK)
def binominal(m,n):
return math.factorial(m)/math.factorial(m-n)/math.factorial(n)
def func(i,j):
k=dim
T=binominal(k-1,i)/math.factorial(k-1)
value=0
for l in range(j,k):
value+=binominal(k,l-j)*(k-(l+1))**i*(-1)**(l-j)
return value*T
def fN(_i,_k,_dim):
if _dim==1:
F=list()
for i in range(dim):
F.append(0)
if _k==_i:
F[dim-1]=1
return F
S1=fN(_i,_k,_dim-1)
S2=fN(_i,_k+1,_dim-1)
E1=knot[_k+_dim-2]-knot[_k-1]
E2=knot[_k+_dim-1]-knot[_k]
D1=list()
D2=list()
D1.append(0)
D1.append(0)
D2.append(0)
D2.append(0)
if E1>0:
D1[0]=1/E1
D1[1]=-knot[_k-1]/E1
if E2>0:
D2[0]=-1/E2
D2[1]=knot[_k+_dim-1]/E2
F=list()
for i in range(dim):
F.append(0)
for i in range(1,dim):
F[i-1]=F[i-1]+S1[i]*D1[0];
F[i]=F[i]+S1[i]*D1[1];
F[i-1]=F[i-1]+S2[i]*D2[0];
F[i]=F[i]+S2[i]*D2[1];
return F
def fM(i):
M=rg.Matrix(dim,dim)
M.Zero()
for k in range(i,dim+i):
D=fN(i+ddim,k,dim)
for n in range(dim):
M[n,k-i]=D[n]
S=rg.Matrix(dim,dim)
S.Zero()
for n in range(1,dim+1):
for k in range(1+n,dim+2):
if n==dim:
for t in range(n-1):
S[t,n-1]=0
S[n-1,n-1]=1
else:
S[k-2,n-1]=binominal(dim-n,dim+1-k)*((i-1)**(k-1-n))
G=S*M
return G
def draw():
out=list()
segment=list()
for i in range(1,N-ddim+1):
M=fM(i)
points=list()
for n in range(dim):
points.append(P[i-1+n])
segment.append((M,points))
T=rg.Matrix(1,dim)
for seg in segment:
M=seg[0]
points=seg[1]
for t in rs.frange(0,1.0,0.02):
for i in range(dim):
T[0,i]=t**(ddim-i)
F=T*M
PP=rg.Point3d(0,0,0)
for i in range(dim):
PP=PP+F[0,i]*points[i]
out.append(PP)
return out
if N>dim-1:
a=draw()