def __init__(self, cntrl, uknots, vknots): self._bezier = None cntrl = numerix.asarray(cntrl, numerix.Float) (dim, nu, nv) = cntrl.shape if dim < 2 or dim > 4: raise NURBSError, 'Illegal control point format' elif dim < 4: self.cntrl = numerix.zeros((4, nu, nv), numerix.Float) self.cntrl[0:dim,:,:] = cntrl self.cntrl[-1,:,:] = numerix.ones((nu,nv), numerix.Float) else: self.cntrl = cntrl # Force the u knot sequence to be a vector in ascending order # and normalise between [0.0,1.0] uknots = numerix.sort(numerix.asarray(uknots, numerix.Float)) nku = uknots.shape[0] uknots = (uknots - uknots[0])/(uknots[-1] - uknots[0]) if uknots[0] == uknots[-1]: raise NURBSError, 'Illegal uknots sequence' self.uknots = uknots # Force the v knot sequence to be a vector in ascending order # and normalise between [0.0,1.0] vknots = -numerix.sort(-numerix.asarray(vknots, numerix.Float)) nkv = vknots.shape[0] vknots = (vknots - vknots[0])/(vknots[-1] - vknots[0]) if vknots[0] == vknots[-1]: raise NURBSError, 'Illegal vknots sequence' self.vknots = vknots # Spline Degree self.degree = [nku-nu-1, nkv-nv-1] if self.degree[0] < 0 or self.degree[1] < 0: raise NURBSError, 'NURBS order must be a positive integer'
def __init__(self, cntrl, uknots, vknots): self._bezier = None cntrl = numerix.asarray(cntrl, numerix.Float) (dim, nu, nv) = cntrl.shape if dim < 2 or dim > 4: raise NURBSError, 'Illegal control point format' elif dim < 4: self.cntrl = numerix.zeros((4, nu, nv), numerix.Float) self.cntrl[0:dim, :, :] = cntrl self.cntrl[-1, :, :] = numerix.ones((nu, nv), numerix.Float) else: self.cntrl = cntrl # Force the u knot sequence to be a vector in ascending order # and normalise between [0.0,1.0] uknots = numerix.sort(numerix.asarray(uknots, numerix.Float)) nku = uknots.shape[0] uknots = (uknots - uknots[0]) / (uknots[-1] - uknots[0]) if uknots[0] == uknots[-1]: raise NURBSError, 'Illegal uknots sequence' self.uknots = uknots # Force the v knot sequence to be a vector in ascending order # and normalise between [0.0,1.0] vknots = -numerix.sort(-numerix.asarray(vknots, numerix.Float)) nkv = vknots.shape[0] vknots = (vknots - vknots[0]) / (vknots[-1] - vknots[0]) if vknots[0] == vknots[-1]: raise NURBSError, 'Illegal vknots sequence' self.vknots = vknots # Spline Degree self.degree = [nku - nu - 1, nkv - nv - 1] if self.degree[0] < 0 or self.degree[1] < 0: raise NURBSError, 'NURBS order must be a positive integer'
def kntins(self, uknots, vknots=None): """Insert new knots into the surface uknots - knots to be inserted along u direction vknots - knots to be inserted along v direction NOTE: No knot multiplicity will be increased beyond the order of the spline""" if len(vknots): # Force the v knot sequence to be a vector in ascending order vknots = numerix.sort(numerix.asarray(vknots, numerix.Float)) if numerix.any(vknots < 0.) or numerix.any(vknots > 1.): raise NURBSError, 'Illegal vknots sequence' coefs = numerix.resize( self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2])) coefs, self.vknots = bspkntins(self.degree[1], coefs, self.vknots, vknots) self.cntrl = numerix.resize( coefs, (4, self.cntrl.shape[1], coefs.shape[1])) if len(uknots): # Force the u knot sequence to be a vector in ascending order uknots = numerix.sort(numerix.asarray(uknots, numerix.Float)) if numerix.any(uknots < 0.) or numerix.any(uknots > 1.): raise NURBSError, 'Illegal uknots sequence' coefs = numerix.transpose(self.cntrl, (0, 2, 1)) coefs = numerix.resize( coefs, (4 * self.cntrl.shape[2], self.cntrl.shape[1])) coefs, self.uknots = bspkntins(self.degree[0], coefs, self.uknots, uknots) coefs = numerix.resize(coefs, (4, self.cntrl.shape[2], coefs.shape[1])) self.cntrl = numerix.transpose(coefs, (0, 2, 1))
def bounds(self): "Return the bounding box for the surface." w = self.cntrl[3, :, :] cx = numerix.sort(numerix.ravel(self.cntrl[0, :, :] / w)) cy = numerix.sort(numerix.ravel(self.cntrl[1, :, :] / w)) cz = numerix.sort(numerix.ravel(self.cntrl[2, :, :] / w)) return numerix.asarray([cx[0], cy[0], cz[0], cx[-1], cy[-1], cz[-1]], numerix.Float)
def bounds(self): "Return the bounding box for the surface." w = self.cntrl[3,:,:] cx = numerix.sort(numerix.ravel(self.cntrl[0,:,:]/w)) cy = numerix.sort(numerix.ravel(self.cntrl[1,:,:]/w)) cz = numerix.sort(numerix.ravel(self.cntrl[2,:,:]/w)) return numerix.asarray([cx[0], cy[0], cz[0], cx[-1], cy[-1], cz[-1]], numerix.Float)
def lowess2(x, y, xest, f=2./3., iter=3): """Returns estimated values of y in data points xest (or None if estimation fails). Lowess smoother: Robust locally weighted regression. The lowess function fits a nonparametric regression curve to a scatterplot. The arrays x and y contain an equal number of elements; each pair (x[i], y[i]) defines a data point in the scatterplot. The function returns the estimated (smooth) values of y. The smoothing span is given by f. A larger value for f will result in a smoother curve. The number of robustifying iterations is given by iter. The function will run faster with a smaller number of iterations.""" x = Numeric.asarray(x, 'd') y = Numeric.asarray(y, 'd') xest = Numeric.asarray(xest, 'd') n = len(x) nest = len(xest) r = min(int(Numeric.ceil(f*n)),n-1) # radius: num. of points to take into LR h = [Numeric.sort(abs(x-x[i]))[r] for i in range(n)] # distance of the r-th point from x[i] w = Numeric.clip(abs(([x]-Numeric.transpose([x]))/h),0.0,1.0) w = 1-w*w*w w = w*w*w hest = [Numeric.sort(abs(x-xest[i]))[r] for i in range(nest)] # r-th min. distance from xest[i] to x west = Numeric.clip(abs(([xest]-Numeric.transpose([x]))/hest),0.0,1.0) # shape: (len(x), len(xest) west = 1-west*west*west west = west*west*west yest = Numeric.zeros(n,'d') yest2 = Numeric.zeros(nest,'d') delta = Numeric.ones(n,'d') try: for iteration in range(iter): # fit xest for i in range(nest): weights = delta * west[:,i] b = Numeric.array([sum(weights*y), sum(weights*y*x)]) A = Numeric.array([[sum(weights), sum(weights*x)], [sum(weights*x), sum(weights*x*x)]]) beta = LinearAlgebra.solve_linear_equations(A,b) yest2[i] = beta[0] + beta[1]*xest[i] # fit x (to calculate residuals and delta) for i in range(n): weights = delta * w[:,i] b = Numeric.array([sum(weights*y), sum(weights*y*x)]) A = Numeric.array([[sum(weights), sum(weights*x)], [sum(weights*x), sum(weights*x*x)]]) beta = LinearAlgebra.solve_linear_equations(A,b) yest[i] = beta[0] + beta[1]*x[i] residuals = y-yest s = MLab.median(abs(residuals)) delta = Numeric.clip(residuals/(6*s),-1,1) delta = 1-delta*delta delta = delta*delta except LinearAlgebra.LinAlgError: print "Warning: NumExtn.lowess2: LinearAlgebra.solve_linear_equations: Singular matrix" yest2 = None return yest2
def __init__(self, traj=None, recChains=[0], n_members=10, rec=None): """ Use:: ComplexTraj( traj, recChains=[0], n_members=10 ) @param traj: Trajectory (default: 0) @type traj: Trajectory @param recChains: list of chain indices defining receptor (default: [0]) @type recChains: [int] @param n_members: number of ensemble members (for multi-copy MD) (default: 10) @type n_members: int @param rec: instead of using recChains, autodetect rec chains by comparing traj.ref with the model given as rec (default: None) @type rec: PDBModel """ EnsembleTraj.__init__( self ) if traj: self.__dict__.update( traj.__dict__ ) if rec: self.cr = self.ref.compareChains( rec )[0] else: self.cr = N.sort( recChains ).tolist() self.cl = range( 0, self.getRef().lenChains() ) for c in self.cr: self.cl.remove(c) else: self.cr = self.cl = None
def kntins(self, uknots): """Insert new knots into the curve NOTE: No knot multiplicity will be increased beyond the order of the spline""" if len(uknots): uknots = numerix.sort(numerix.asarray(uknots, numerix.Float)) if numerix.any(uknots < 0.) or numerix.any(uknots > 1.): raise NURBSError, 'NURBS curve parameter out of range [0,1]' self.cntrl, self.uknots = bspkntins(self.degree, self.cntrl, self.uknots, uknots)
def bounds(self): "Return the boundingbox for the curve" ww = numerix.resize(self.cntrl[-1, :], (3, self.cntrl.shape[1])) cntrl = numerix.sort(self.cntrl[0:3, :] / ww) return numerix.asarray([ cntrl[0, 0], cntrl[1, 0], cntrl[2, 0], cntrl[0, -1], cntrl[1, -1], cntrl[2, -1] ], numerix.Float)
def kntins(self, uknots, vknots = None): """Insert new knots into the surface uknots - knots to be inserted along u direction vknots - knots to be inserted along v direction NOTE: No knot multiplicity will be increased beyond the order of the spline""" if len(vknots): # Force the v knot sequence to be a vector in ascending order vknots = numerix.sort(numerix.asarray(vknots, numerix.Float)) if numerix.any(vknots < 0.) or numerix.any(vknots > 1.): raise NURBSError, 'Illegal vknots sequence' coefs = numerix.resize(self.cntrl,(4*self.cntrl.shape[1], self.cntrl.shape[2])) coefs, self.vknots = bspkntins(self.degree[1], coefs, self.vknots, vknots) self.cntrl = numerix.resize(coefs, (4, self.cntrl.shape[1], coefs.shape[1])) if len(uknots): # Force the u knot sequence to be a vector in ascending order uknots = numerix.sort(numerix.asarray(uknots, numerix.Float)) if numerix.any(uknots < 0.) or numerix.any(uknots > 1.): raise NURBSError, 'Illegal uknots sequence' coefs = numerix.transpose(self.cntrl,(0, 2, 1)) coefs = numerix.resize(coefs,(4*self.cntrl.shape[2], self.cntrl.shape[1])) coefs, self.uknots = bspkntins(self.degree[0], coefs, self.uknots, uknots) coefs = numerix.resize(coefs, (4, self.cntrl.shape[2], coefs.shape[1])) self.cntrl = numerix.transpose(coefs,(0,2,1))
def drawLines(self): # angle has to be provided in radians angle = self.angle self.circlePtsAngles = self.circlePtsAngles+angle self.circlePtsAngles = Numeric.remainder(self.circlePtsAngles, 2*math.pi) xcoords = Numeric.cos(self.circlePtsAngles) xsin = Numeric.sin(self.circlePtsAngles) if self.orient=='horizontal': w = self.innerbox[2] - self.innerbox[0] r = w/2 c = self.innerbox[0] + r y1 = self.innerbox[1] y2 = self.innerbox[3] else: w = self.innerbox[3] - self.innerbox[1] r = w/2 c = self.innerbox[1] + r y1 = self.innerbox[0] y2 = self.innerbox[2] cl = self.canvas.create_line setCoords = self.canvas.coords setOpt = self.canvas.itemconfigure pi2 = math.pi/2. drawLines = 0 co = Numeric.take(xcoords, Numeric.nonzero(Numeric.greater_equal(xsin, 0.0))) co = Numeric.sort(co) co = [-1]+list(co) for i in range(len(co)): x = c - int(co[i]*r) if self.orient=='horizontal': setCoords(self.linesIds[i], x, y1, x, y2) else: setCoords(self.linesIds[i], y1, x, y2, x) shopt = self.shadowLinesOptions[i] x = x + shopt[0] if self.orient=='horizontal': setCoords(self.shLinesIds[i], x, y1, x, y2) else: setCoords(self.shLinesIds[i], y1, x, y2, x) setOpt(self.shLinesIds[i], fill = shopt[1], width=shopt[2])
def drawLines(self): # angle has to be provided in radians angle = self.angle self.circlePtsAngles = self.circlePtsAngles + angle self.circlePtsAngles = Numeric.remainder(self.circlePtsAngles, 2 * math.pi) xcoords = Numeric.cos(self.circlePtsAngles) xsin = Numeric.sin(self.circlePtsAngles) if self.orient == 'horizontal': w = self.innerbox[2] - self.innerbox[0] r = w / 2 c = self.innerbox[0] + r y1 = self.innerbox[1] y2 = self.innerbox[3] else: w = self.innerbox[3] - self.innerbox[1] r = w / 2 c = self.innerbox[1] + r y1 = self.innerbox[0] y2 = self.innerbox[2] cl = self.canvas.create_line setCoords = self.canvas.coords setOpt = self.canvas.itemconfigure pi2 = math.pi / 2. drawLines = 0 co = Numeric.take(xcoords, Numeric.nonzero(Numeric.greater_equal(xsin, 0.0))) co = Numeric.sort(co) co = [-1] + list(co) for i in range(len(co)): x = c - int(co[i] * r) if self.orient == 'horizontal': setCoords(self.linesIds[i], x, y1, x, y2) else: setCoords(self.linesIds[i], y1, x, y2, x) shopt = self.shadowLinesOptions[i] x = x + shopt[0] if self.orient == 'horizontal': setCoords(self.shLinesIds[i], x, y1, x, y2) else: setCoords(self.shLinesIds[i], y1, x, y2, x) setOpt(self.shLinesIds[i], fill=shopt[1], width=shopt[2])
def __init__(self, crv1, crv2): if not isinstance(crv1, Crv.Crv): raise NURBSError, 'Parameter crv1 not derived from Crv class!' if not isinstance(crv2, Crv.Crv): raise NURBSError, 'Parameter crv2 not derived from Crv class!' # ensure both curves have a common degree d = max(crv1.degree, crv2.degree) crv1.degelev(d - crv1.degree) crv2.degelev(d - crv2.degree) # merge the knot vectors, to obtain a common knot vector k1 = crv1.uknots k2 = crv2.uknots ku = [] for item in k1: if not numerix.sometrue(numerix.equal(k2, item)): if item not in ku: ku.append(item) for item in k2: if not numerix.sometrue(numerix.equal(k1, item)): if item not in ku: ku.append(item) ku = numerix.sort(numerix.asarray(ku, numerix.Float)) n = ku.shape[0] ka = numerix.array([], numerix.Float) kb = numerix.array([], numerix.Float) for i in range(0, n): i1 = numerix.compress(numerix.equal(k1, ku[i]), k1).shape[0] i2 = numerix.compress(numerix.equal(k2, ku[i]), k2).shape[0] m = max(i1, i2) ka = numerix.concatenate((ka, ku[i] * numerix.ones( (m - i1, ), numerix.Float))) kb = numerix.concatenate((kb, ku[i] * numerix.ones( (m - i2, ), numerix.Float))) crv1.kntins(ka) crv2.kntins(kb) coefs = numerix.zeros((4, crv1.cntrl.shape[1], 2), numerix.Float) coefs[:, :, 0] = crv1.cntrl coefs[:, :, 1] = crv2.cntrl Srf.__init__(self, coefs, crv1.uknots, [0., 0., 1., 1.])
def __init__(self, crv1, crv2): if not isinstance(crv1, Crv.Crv): raise NURBSError, 'Parameter crv1 not derived from Crv class!' if not isinstance(crv2, Crv.Crv): raise NURBSError, 'Parameter crv2 not derived from Crv class!' # ensure both curves have a common degree d = max(crv1.degree, crv2.degree) crv1.degelev(d - crv1.degree) crv2.degelev(d - crv2.degree) # merge the knot vectors, to obtain a common knot vector k1 = crv1.uknots k2 = crv2.uknots ku = [] for item in k1: if not numerix.sometrue(numerix.equal(k2, item)): if item not in ku: ku.append(item) for item in k2: if not numerix.sometrue(numerix.equal(k1, item)): if item not in ku: ku.append(item) ku = numerix.sort(numerix.asarray(ku, numerix.Float)) n = ku.shape[0] ka = numerix.array([], numerix.Float) kb = numerix.array([], numerix.Float) for i in range(0, n): i1 = numerix.compress(numerix.equal(k1, ku[i]), k1).shape[0] i2 = numerix.compress(numerix.equal(k2, ku[i]), k2).shape[0] m = max(i1, i2) ka = numerix.concatenate((ka , ku[i] * numerix.ones((m - i1,), numerix.Float))) kb = numerix.concatenate((kb , ku[i] * numerix.ones((m - i2,), numerix.Float))) crv1.kntins(ka) crv2.kntins(kb) coefs = numerix.zeros((4, crv1.cntrl.shape[1], 2), numerix.Float) coefs[:,:,0] = crv1.cntrl coefs[:,:,1] = crv2.cntrl Srf.__init__(self, coefs, crv1.uknots, [0., 0., 1., 1.])
def wavenumber_integration(tb, wl, response): x = [] y = [] for i in range(len(wl)): x.append(1. / wl[i]) #print "wavelength,wavenumber: ",wl[i],1./wl[i] yval_length = blackbody(wl[i], tb) * response[i] * (wl[i] * wl[i]) yval = blackbody(1. / wl[i], tb, "wavenumber") * response[i] #print "YVAL: ",yval,yval_length y.append(yval) x = Numeric.array(x) y = Numeric.array(y) y = Numeric.choose(Numeric.argsort(x), y) x = Numeric.sort(x) response = Numeric.array(response) res = integral(x, y) # Normalisation: norm = integral(x, response) #print "Norm: ",norm return res / norm
n_one = 0 while n_one < 21: one_sigma_mags = Numeric.compress( Numeric.less_equal(abs(em[i, :] - 0.7526), dm), m[i, :]) n_one = len(one_sigma_mags) dm += 0.01 if dm > 0.03 and dm < 1.1: message = "Warning: not enough 1-sigma objects in the catalog. Using dm=+-%.2f" % dm self.logfile.write(message) if dm >= 1.1: message = "Warning: Stopped searching for 1-sigma objects at dm=+-%.2f" % dm self.logfile.write(message) break try: limMag = MLab.median(Numeric.sort(one_sigma_mags)[-20:]) self.logfile.write("Limiting Mag " + basefits + ":" + str(limMag)) print "Limiting Mag " + basefits + ":" + str(limMag) except Exception, err: print "Exception raised: could not determine limiting magnitude." print err #---------------------- End Limiting Magnitude Section ----------------------# #self.outColumns.append(imfilter +'_MAG_ISO') #self.outColumns.append(imfilter +'_MAGERR_ISO') self.outColumns.append(imfilter + '_MAGCORR_ISO') self.outColumns.append(imfilter + '_MAGERRCORR_ISO') self.outColumns.append(imfilter + '_APER_CORR') self.outColumns.append(imfilter + '_MAG_BPZ')
def lowessW(x, y, xest, f=2./3., iter=3, dWeights=None, callback=None): """Returns estimated values of y in data points xest (or None if estimation fails). Lowess smoother: Robust locally weighted regression. The lowess function fits a nonparametric regression curve to a scatterplot. The arrays x and y contain an equal number of elements; each pair (x[i], y[i]) defines a data point in the scatterplot. The function returns the estimated (smooth) values of y. The smoothing span is given by f. A larger value for f will result in a smoother curve. The number of robustifying iterations is given by iter. The function will run faster with a smaller number of iterations. Data points may be assigned weights; if None, all weights equal 1. """ x = Numeric.asarray(x, 'd') y = Numeric.asarray(y, 'd') xest = Numeric.asarray(xest, 'd') n = len(x) if n <> len(y): raise AttributeError, "Error: lowessW(x,y,xest,f,iter,dWeights): len(x)=%i not equal to len(y)=%i" % (len(x), len(y)) nest = len(xest) # weights of data points (optional) if dWeights <> None: dWeights = Numeric.asarray(dWeights, 'd') if len(dWeights) <> n: raise AttributeError, "Error: lowessW(x,y,xest,f,iter,dWeights): len(dWeights)=%i not equal to len(x)=%i" % (len(dWeights), len(x)) ## dWeights = dWeights.reshape((n,1)) else: ## dWeights = Numeric.ones((n,1)) dWeights = Numeric.ones((n,)) r = min(int(Numeric.ceil(f*n)),n-1) # radius: num. of points to take into LR h = [Numeric.sort(abs(x-x[i]))[r] for i in range(n)] # distance of the r-th point from x[i] w = Numeric.clip(abs(([x]-Numeric.transpose([x]))/h),0.0,1.0) w = 1-w*w*w w = w*w*w hest = [Numeric.sort(abs(x-xest[i]))[r] for i in range(nest)] # r-th min. distance from xest[i] to x west = Numeric.clip(abs(([xest]-Numeric.transpose([x]))/hest),0.0,1.0) # shape: (len(x), len(xest)) west = 1-west*west*west west = west*west*west yest = Numeric.zeros(n,'d') yest2 = Numeric.zeros(nest,'d') delta = Numeric.ones(n,'d') try: for iteration in range(int(iter)): # fit xest for i in range(nest): ## print delta.shape, west[:,i].shape, dWeights.shape weights = delta * west[:,i] * dWeights b = Numeric.array([sum(weights*y), sum(weights*y*x)]) A = Numeric.array([[sum(weights), sum(weights*x)], [sum(weights*x), sum(weights*x*x)]]) beta = LinearAlgebra.solve_linear_equations(A,b) yest2[i] = beta[0] + beta[1]*xest[i] # fit x (to calculate residuals and delta) for i in range(n): weights = delta * w[:,i] * dWeights b = Numeric.array([sum(weights*y), sum(weights*y*x)]) A = Numeric.array([[sum(weights), sum(weights*x)], [sum(weights*x), sum(weights*x*x)]]) beta = LinearAlgebra.solve_linear_equations(A,b) yest[i] = beta[0] + beta[1]*x[i] residuals = y-yest s = MLab.median(abs(residuals)) delta = Numeric.clip(residuals/(6*s),-1,1) delta = 1-delta*delta delta = delta*delta if callback: callback() except LinearAlgebra.LinAlgError: print "Warning: NumExtn.lowessW: LinearAlgebra.solve_linear_equations: Singular matrix" yest2 = None return yest2
def __init__(self, u1, u2, v1, v2): if not isinstance(u1, Crv.Crv): raise NURBSError, 'Parameter u1 not derived from Crv class!' if not isinstance(u2, Crv.Crv): raise NURBSError, 'Parameter u2 not derived from Crv class!' if not isinstance(v1, Crv.Crv): raise NURBSError, 'Parameter v1 not derived from Crv class!' if not isinstance(v2, Crv.Crv): raise NURBSError, 'Parameter v2 not derived from Crv class!' r1 = Ruled(u1, u2) r2 = Ruled(v1, v2) r2.swapuv() t = Bilinear(u1.cntrl[:,0], u1.cntrl[:,-1], u2.cntrl[:,0], u2.cntrl[:,-1]) # Raise all surfaces to a common degree du = max(r1.degree[0], r2.degree[0], t.degree[0]) dv = max(r1.degree[1], r2.degree[1], t.degree[1]) r1.degelev(du - r1.degree[0], dv - r1.degree[1]) r2.degelev(du - r2.degree[0], dv - r2.degree[1]) t.degelev(du - t.degree[0], dv - t.degree[1]) # Merge the knot vectors, to obtain a common knot vector # uknots: k1 = r1.uknots k2 = r2.uknots k3 = t.uknots k = [] for item in k1: if not numerix.sometrue(numerix.equal(k2, item)): if not numerix.sometrue(numerix.equal(k3, item)): if item not in k: k.append(item) for item in k2: if not numerix.sometrue(numerix.equal(k1, item)): if not numerix.sometrue(numerix.equal(k3, item)): if item not in k: k.append(item) for item in k3: if not numerix.sometrue(numerix.equal(k1, item)): if not numerix.sometrue(numerix.equal(k2, item)): if item not in k: k.append(item) k = numerix.sort(numerix.asarray(k, numerix.Float)) n = k.shape[0] kua = numerix.array([], numerix.Float) kub = numerix.array([], numerix.Float) kuc = numerix.array([], numerix.Float) for i in range(0, n): i1 = numerix.compress(numerix.equal(k1, k[i]), k1).shape[0] i2 = numerix.compress(numerix.equal(k2, k[i]), k2).shape[0] i3 = numerix.compress(numerix.equal(k3, k[i]), k3).shape[0] m = max(i1, i2, i3) kua = numerix.concatenate((kua , k[i] * numerix.ones((m - i1,), numerix.Float))) kub = numerix.concatenate((kub , k[i] * numerix.ones((m - i2,), numerix.Float))) kuc = numerix.concatenate((kuc , k[i] * numerix.ones((m - i3,), numerix.Float))) # vknots: k1 = r1.vknots k2 = r2.vknots k3 = t.vknots k = [] for item in k1: if not numerix.sometrue(numerix.equal(k2, item)): if not numerix.sometrue(numerix.equal(k3, item)): if item not in k: k.append(item) for item in k2: if not numerix.sometrue(numerix.equal(k1, item)): if not numerix.sometrue(numerix.equal(k3, item)): if item not in k: k.append(item) for item in k3: if not numerix.sometrue(numerix.equal(k1, item)): if not numerix.sometrue(numerix.equal(k2, item)): if item not in k: k.append(item) k = numerix.sort(numerix.asarray(k, numerix.Float)) n = k.shape[0] kva = numerix.array([], numerix.Float) kvb = numerix.array([], numerix.Float) kvc = numerix.array([], numerix.Float) for i in range(0, n): i1 = numerix.compress(numerix.equal(k1, k[i]), k1).shape[0] i2 = numerix.compress(numerix.equal(k2, k[i]), k2).shape[0] i3 = numerix.compress(numerix.equal(k3, k[i]), k3).shape[0] m = max(i1, i2, i3) kva = numerix.concatenate((kva , k[i] * numerix.ones((m - i1,), numerix.Float))) kvb = numerix.concatenate((kvb , k[i] * numerix.ones((m - i2,), numerix.Float))) kvc = numerix.concatenate((kvc , k[i] * numerix.ones((m - i3,), numerix.Float))) r1.kntins(kua, kva) r2.kntins(kub, kvb) t.kntins(kuc, kvc) coefs = numerix.zeros((4 , t.cntrl.shape[1], t.cntrl.shape[2]), numerix.Float) coefs[0,:,:] = r1.cntrl[0,:,:] + r2.cntrl[0,:,:] - t.cntrl[0,:,:] coefs[1,:,:] = r1.cntrl[1,:,:] + r2.cntrl[1,:,:] - t.cntrl[1,:,:] coefs[2,:,:] = r1.cntrl[2,:,:] + r2.cntrl[2,:,:] - t.cntrl[2,:,:] coefs[3,:,:] = r1.cntrl[3,:,:] + r2.cntrl[3,:,:] - t.cntrl[3,:,:] Srf.__init__(self, coefs, r1.uknots, r1.vknots)
def bounds(self): "Return the boundingbox for the curve" ww = numerix.resize(self.cntrl[-1,:], (3, self.cntrl.shape[1])) cntrl = numerix.sort(self.cntrl[0:3,:]/ww) return numerix.asarray([cntrl[0,0], cntrl[1,0], cntrl[2,0], cntrl[0,-1], cntrl[1,-1], cntrl[2,-1]], numerix.Float)
def pcMovie(self, ev, steps, factor=1., ref=0, morph=1): """ Morph between the two extreme values of a single principal component. @param ev: EigenVector to visualize @type ev: int @param steps: number of intermediate frames @type steps: int @param factor: exageration factor (default: 1 = No exageration) @type factor: float @param ref: take other eigenvecors from this frame (default: 1) @type ref: int @param morph: morph between min and max (1) or take real values (0) (default: 1) @type morph: 1|0 @return: Trajectory with frames visualizing the morphing. @rtype: Trajectory """ fit = 1 if self.pc is not None: fit = self.pc['fit'] pc = self.getPca(fit=fit) ## eigenvectors (rows) U = pc['u'] ## raveled and centered frames x_avg = N.average(self.frames, 0) X = N.array([N.ravel(x) for x in self.frames - x_avg]) ## ev'th eigenvector of reference frame alpha_0 = N.dot(X[ref], U[ev]) ## list of deviations of ev'th eigenvector of each frame from ref alpha_range = N.dot(X, U[ev]) - alpha_0 ## get some representative alphas... if morph: a_min = factor * min(alpha_range) a_max = factor * max(alpha_range) delta = (a_max - a_min) / steps alpha_range = [a_min + i * (delta) for i in range(0, steps)] else: alpha_range = N.sort(alpha_range) delta = len(alpha_range) / (steps * 1.0) alpha_range = [ alpha_range[int(round(i * delta))] for i in range(0, steps) ] ## scale ev'th eigenvector of ref with different alphas Y = N.array([X[ref] + alpha * U[ev] for alpha in alpha_range]) ## back convert to N x 3 coordinates Y = N.reshape(Y, (Y.shape[0], -1, 3)) Y = x_avg + Y result = self.__class__() result.ref = self.ref result.frames = Y return result
def __init__(self, u1, u2, v1, v2): if not isinstance(u1, Crv.Crv): raise NURBSError, 'Parameter u1 not derived from Crv class!' if not isinstance(u2, Crv.Crv): raise NURBSError, 'Parameter u2 not derived from Crv class!' if not isinstance(v1, Crv.Crv): raise NURBSError, 'Parameter v1 not derived from Crv class!' if not isinstance(v2, Crv.Crv): raise NURBSError, 'Parameter v2 not derived from Crv class!' r1 = Ruled(u1, u2) r2 = Ruled(v1, v2) r2.swapuv() t = Bilinear(u1.cntrl[:, 0], u1.cntrl[:, -1], u2.cntrl[:, 0], u2.cntrl[:, -1]) # Raise all surfaces to a common degree du = max(r1.degree[0], r2.degree[0], t.degree[0]) dv = max(r1.degree[1], r2.degree[1], t.degree[1]) r1.degelev(du - r1.degree[0], dv - r1.degree[1]) r2.degelev(du - r2.degree[0], dv - r2.degree[1]) t.degelev(du - t.degree[0], dv - t.degree[1]) # Merge the knot vectors, to obtain a common knot vector # uknots: k1 = r1.uknots k2 = r2.uknots k3 = t.uknots k = [] for item in k1: if not numerix.sometrue(numerix.equal(k2, item)): if not numerix.sometrue(numerix.equal(k3, item)): if item not in k: k.append(item) for item in k2: if not numerix.sometrue(numerix.equal(k1, item)): if not numerix.sometrue(numerix.equal(k3, item)): if item not in k: k.append(item) for item in k3: if not numerix.sometrue(numerix.equal(k1, item)): if not numerix.sometrue(numerix.equal(k2, item)): if item not in k: k.append(item) k = numerix.sort(numerix.asarray(k, numerix.Float)) n = k.shape[0] kua = numerix.array([], numerix.Float) kub = numerix.array([], numerix.Float) kuc = numerix.array([], numerix.Float) for i in range(0, n): i1 = numerix.compress(numerix.equal(k1, k[i]), k1).shape[0] i2 = numerix.compress(numerix.equal(k2, k[i]), k2).shape[0] i3 = numerix.compress(numerix.equal(k3, k[i]), k3).shape[0] m = max(i1, i2, i3) kua = numerix.concatenate((kua, k[i] * numerix.ones( (m - i1, ), numerix.Float))) kub = numerix.concatenate((kub, k[i] * numerix.ones( (m - i2, ), numerix.Float))) kuc = numerix.concatenate((kuc, k[i] * numerix.ones( (m - i3, ), numerix.Float))) # vknots: k1 = r1.vknots k2 = r2.vknots k3 = t.vknots k = [] for item in k1: if not numerix.sometrue(numerix.equal(k2, item)): if not numerix.sometrue(numerix.equal(k3, item)): if item not in k: k.append(item) for item in k2: if not numerix.sometrue(numerix.equal(k1, item)): if not numerix.sometrue(numerix.equal(k3, item)): if item not in k: k.append(item) for item in k3: if not numerix.sometrue(numerix.equal(k1, item)): if not numerix.sometrue(numerix.equal(k2, item)): if item not in k: k.append(item) k = numerix.sort(numerix.asarray(k, numerix.Float)) n = k.shape[0] kva = numerix.array([], numerix.Float) kvb = numerix.array([], numerix.Float) kvc = numerix.array([], numerix.Float) for i in range(0, n): i1 = numerix.compress(numerix.equal(k1, k[i]), k1).shape[0] i2 = numerix.compress(numerix.equal(k2, k[i]), k2).shape[0] i3 = numerix.compress(numerix.equal(k3, k[i]), k3).shape[0] m = max(i1, i2, i3) kva = numerix.concatenate((kva, k[i] * numerix.ones( (m - i1, ), numerix.Float))) kvb = numerix.concatenate((kvb, k[i] * numerix.ones( (m - i2, ), numerix.Float))) kvc = numerix.concatenate((kvc, k[i] * numerix.ones( (m - i3, ), numerix.Float))) r1.kntins(kua, kva) r2.kntins(kub, kvb) t.kntins(kuc, kvc) coefs = numerix.zeros((4, t.cntrl.shape[1], t.cntrl.shape[2]), numerix.Float) coefs[ 0, :, :] = r1.cntrl[0, :, :] + r2.cntrl[0, :, :] - t.cntrl[0, :, :] coefs[ 1, :, :] = r1.cntrl[1, :, :] + r2.cntrl[1, :, :] - t.cntrl[1, :, :] coefs[ 2, :, :] = r1.cntrl[2, :, :] + r2.cntrl[2, :, :] - t.cntrl[2, :, :] coefs[ 3, :, :] = r1.cntrl[3, :, :] + r2.cntrl[3, :, :] - t.cntrl[3, :, :] Srf.__init__(self, coefs, r1.uknots, r1.vknots)
def pcMovie( self, ev, steps, factor=1., ref=0, morph=1 ): """ Morph between the two extreme values of a single principal component. @param ev: EigenVector to visualize @type ev: int @param steps: number of intermediate frames @type steps: int @param factor: exageration factor (default: 1 = No exageration) @type factor: float @param ref: take other eigenvecors from this frame (default: 1) @type ref: int @param morph: morph between min and max (1) or take real values (0) (default: 1) @type morph: 1|0 @return: Trajectory with frames visualizing the morphing. @rtype: Trajectory """ fit = 1 if self.pc is not None: fit = self.pc['fit'] pc = self.getPca( fit=fit ) ## eigenvectors (rows) U = pc['u'] ## raveled and centered frames x_avg = N.average(self.frames, 0) X = N.array( [N.ravel(x) for x in self.frames - x_avg] ) ## ev'th eigenvector of reference frame alpha_0 = N.dot( X[ref], U[ev] ) ## list of deviations of ev'th eigenvector of each frame from ref alpha_range = N.dot(X, U[ev]) - alpha_0 ## get some representative alphas... if morph: a_min = factor * min(alpha_range) a_max = factor * max(alpha_range) delta = (a_max - a_min) / steps alpha_range = [ a_min + i*(delta) for i in range(0, steps) ] else: alpha_range = N.sort( alpha_range ) delta = len(alpha_range) / (steps * 1.0) alpha_range = [ alpha_range[ int(round( i*delta )) ] for i in range(0,steps) ] ## scale ev'th eigenvector of ref with different alphas Y = N.array( [ X[ref] + alpha * U[ev] for alpha in alpha_range] ) ## back convert to N x 3 coordinates Y = N.reshape(Y, (Y.shape[0], -1, 3)) Y = x_avg + Y result = self.__class__() result.ref = self.ref result.frames = Y return result
class Crv: '''Construct a NURB curve and check the format. The NURB curve is represented by a 4 dimensional b-spline. INPUT: cntrl - Control points, homogeneous coordinates (wx,wy,wz,w) [dim,nu] matrix dim is the dimension valid options are: 2 .... (x,y) 2D cartesian coordinates 3 .... (x,y,z) 3D cartesian coordinates 4 .... (wx,wy,wz,w) 4D homogeneous coordinates uknots - Knot sequence along the parametric u direction. NOTES: Its assumed that the input knot sequences span the interval [0.0,1.0] and are clamped to the control points at the end by a knot multiplicity equal to the spline order.''' def __init__(self, cntrl, uknots): self._bezier = None # Force the u knot sequence to be a vector in ascending order # and normalise between [0.0,1.0] uknots = numerix.sort(numerix.asarray(uknots, numerix.Float)) nku = uknots.shape[0] uknots = (uknots - uknots[0]) / (uknots[-1] - uknots[0]) if uknots[0] == uknots[-1]: raise NURBSError, 'Illegal uknots sequence' self.uknots = uknots cntrl = numerix.asarray(cntrl, numerix.Float) (dim, nu) = cntrl.shape if dim < 2 or dim > 4: raise NURBSError, 'Illegal control point format' elif dim < 4: self.cntrl = numerix.zeros((4, nu), numerix.Float) self.cntrl[0:dim, :] = cntrl self.cntrl[-1, :] = numerix.ones((nu, )) else: self.cntrl = cntrl # Spline degree self.degree = nku - nu - 1 if self.degree < 0: raise NURBSError, 'NURBS order must be a positive integer' def trans(self, mat): "Apply the 4D transform matrix to the NURB control points." self.cntrl = numerix.dot(mat, self.cntrl) def reverse(self): "Reverse evaluation direction" self.cntrl = self.cntrl[:, ::-1] self.uknots = 1 - self.uknots[::-1] def kntins(self, uknots): """Insert new knots into the curve NOTE: No knot multiplicity will be increased beyond the order of the spline""" if len(uknots): uknots = numerix.sort(numerix.asarray(uknots, numerix.Float)) if numerix.any(uknots < 0.) or numerix.any(uknots > 1.): raise NURBSError, 'NURBS curve parameter out of range [0,1]' self.cntrl, self.uknots = bspkntins(self.degree, self.cntrl, self.uknots, uknots) def degelev(self, degree): "Degree elevate the curve" if degree < 0: raise NURBSError, 'degree must be a positive number' if degree > 0: cntrl, uknots, nh = bspdegelev(self.degree, self.cntrl, self.uknots, degree) self.cntrl = cntrl[:, :nh + 1] self.uknots = uknots[:nh + self.degree + degree + 2] self.degree += degree def bezier(self, update=None): "Decompose curve to bezier segments and return overlaping control points" if update or not self._bezier: self._bezier = bspbezdecom(self.degree, self.cntrl, self.uknots) return self._bezier def bounds(self): "Return the boundingbox for the curve" ww = numerix.resize(self.cntrl[-1, :], (3, self.cntrl.shape[1])) cntrl = numerix.sort(self.cntrl[0:3, :] / ww) return numerix.asarray([ cntrl[0, 0], cntrl[1, 0], cntrl[2, 0], cntrl[0, -1], cntrl[1, -1], cntrl[2, -1] ], numerix.Float) def pnt3D(self, ut): "Evaluate parametric point[s] and return 3D cartesian coordinate[s]" val = self.pnt4D(ut) return val[0:3, :] / numerix.resize(val[-1, :], (3, val.shape[1])) def pnt4D(self, ut): "Evaluate parametric point[s] and return 4D homogeneous coordinates" ut = numerix.asarray(ut, numerix.Float) if numerix.any(ut < 0.) or numerix.any(ut > 1.): raise NURBSError, 'NURBS curve parameter out of range [0,1]' return bspeval(self.degree, self.cntrl, self.uknots, ut) def plot(self, n=50): """A simple plotting function for debugging purpose n = number of subdivisions. Depends on the matplotlib library.""" try: import pylab as P except ImportError, value: print 'Pylab (matplotlib) plotting library not available' return pnts = self.pnt3D(numerix.linspace(0., 1, n)) knots = self.pnt3D(self.uknots) maxminx = numerix.sort(self.cntrl[0, :] / self.cntrl[3, :]) minx = maxminx[0] maxx = maxminx[-1] if minx == maxx: minx -= 1. maxx += 1. maxminy = numerix.sort(self.cntrl[1, :] / self.cntrl[3, :]) miny = maxminy[0] maxy = maxminy[-1] if miny == maxy: miny -= 1. maxy += 1. maxminz = numerix.sort(self.cntrl[2, :] / self.cntrl[3, :]) minz = maxminz[0] maxz = maxminz[-1] if minz == maxz: minz -= 1. maxz += 1. P.figure() P.plot(pnts[0, :], pnts[1, :]) P.plot(self.cntrl[0, :] / self.cntrl[3, :], self.cntrl[1, :] / self.cntrl[3, :], 'r:o') P.plot(knots[0, :], knots[1, :], 'go') P.xlabel("X-axis") P.ylabel("Y-axis") P.axis("scaled") P.show() P.close()
class Srf: '''Construct a NURB surface structure, and check the format. The NURB surface is represented by a 4 dimensional b-spline. INPUT: cntrl - Control points, homogeneous coordinates (wx,wy,wz,w) For a surface [dim,nu,nv] matrix where nu is along the u direction and nv is along the v direction. dim is the dimension valid options are: 2 .... (x,y) 2D cartesian coordinates 3 .... (x,y,z) 3D cartesian coordinates 4 .... (wx,wy,wz,w) 4D homogeneous coordinates uknots - Knot sequence along the parametric u direction. vknots - Knot sequence along the paramteric v direction. NOTES: Its assumed that the input knot sequences span the interval [0.0,1.0] and are clamped to the control points at the end by a knot multiplicity equal to the spline order.''' def __init__(self, cntrl, uknots, vknots): self._bezier = None cntrl = numerix.asarray(cntrl, numerix.Float) (dim, nu, nv) = cntrl.shape if dim < 2 or dim > 4: raise NURBSError, 'Illegal control point format' elif dim < 4: self.cntrl = numerix.zeros((4, nu, nv), numerix.Float) self.cntrl[0:dim, :, :] = cntrl self.cntrl[-1, :, :] = numerix.ones((nu, nv), numerix.Float) else: self.cntrl = cntrl # Force the u knot sequence to be a vector in ascending order # and normalise between [0.0,1.0] uknots = numerix.sort(numerix.asarray(uknots, numerix.Float)) nku = uknots.shape[0] uknots = (uknots - uknots[0]) / (uknots[-1] - uknots[0]) if uknots[0] == uknots[-1]: raise NURBSError, 'Illegal uknots sequence' self.uknots = uknots # Force the v knot sequence to be a vector in ascending order # and normalise between [0.0,1.0] vknots = -numerix.sort(-numerix.asarray(vknots, numerix.Float)) nkv = vknots.shape[0] vknots = (vknots - vknots[0]) / (vknots[-1] - vknots[0]) if vknots[0] == vknots[-1]: raise NURBSError, 'Illegal vknots sequence' self.vknots = vknots # Spline Degree self.degree = [nku - nu - 1, nkv - nv - 1] if self.degree[0] < 0 or self.degree[1] < 0: raise NURBSError, 'NURBS order must be a positive integer' def trans(self, mat): "Apply the 4D transform matrix to the NURB control points." for v in range(self.cntrl.shape[2]): self.cntrl[:, :, v] = numerix.dot(mat, self.cntrl[:, :, v]) def swapuv(self): "Swap u and v parameters." self.cntrl = numerix.transpose(self.cntrl, (0, 2, 1)) temp = self.uknots[:] self.uknots = self.vknots[:] self.vknots = temp udegree, vdegree = self.degree self.degree[0] = vdegree self.degree[1] = udegree def reverse(self): "Reverse evaluation directions." coefs = self.cntrl[:, :, ::-1] self.cntrl = coefs[:, ::-1, :] self.uknots = 1. - self.uknots[::-1] self.vknots = 1. - self.vknots[::-1] def extractV(self, u): "Extract curve in v-direction at parameter u." if numerix.any(u < 0.) or numerix.any(u > 1.): raise NURBSError, 'Out of parameter range [0,1]' if u == 0.: cntrl = self.cntrl[:, 0, :] knots = self.vknots[:] elif u == 1.: cntrl = self.cntrl[:, -1, :] knots = self.vknots[:] else: uknots = numerix.repeat( numerix.asarray([u], numerix.Float), [self.degree[1] * (self.cntrl.shape[2] + 1)]) coefs = numerix.transpose(self.cntrl, (0, 2, 1)) coefs = numerix.resize( coefs, (4 * self.cntrl.shape[2], self.cntrl.shape[1])) coefs, knots = bspkntins(self.degree[0], coefs, self.uknots, uknots) coefs = numerix.resize(coefs, (4, self.cntrl.shape[2], coefs.shape[1])) cntrl = numerix.transpose(coefs, (0, 2, 1)) i = 0 j = knots[0] for k in knots[1:]: if k == u: break elif k != j: i += 1 j = k return Crv.Crv(cntrl[:, i, :], self.vknots[:]) def extractU(self, v): "Extract curve in u-direction at parameter v." if numerix.any(v < 0.) or numerix.any(v > 1.): raise NURBSError, 'Out of parameter range [0,1]' if v == 0.: cntrl = self.cntrl[:, :, 0] knots = self.uknots[:] elif v == 1.: cntrl = self.cntrl[:, :, -1] knots = self.uknots[:] else: vknots = numerix.repeat( numerix.asarray([v], numerix.Float), [self.degree[0] * (self.cntrl.shape[1] + 1)]) coefs = numerix.resize( self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2])) coefs, knots = bspkntins(self.degree[1], coefs, self.vknots, vknots) cntrl = numerix.resize(coefs, (4, self.cntrl.shape[1], coefs.shape[1])) i = 0 j = knots[0] for k in knots[1:]: if k == v: break elif k != j: i += 1 j = k return Crv.Crv(cntrl[:, :, i], self.uknots[:]) def kntins(self, uknots, vknots=None): """Insert new knots into the surface uknots - knots to be inserted along u direction vknots - knots to be inserted along v direction NOTE: No knot multiplicity will be increased beyond the order of the spline""" if len(vknots): # Force the v knot sequence to be a vector in ascending order vknots = numerix.sort(numerix.asarray(vknots, numerix.Float)) if numerix.any(vknots < 0.) or numerix.any(vknots > 1.): raise NURBSError, 'Illegal vknots sequence' coefs = numerix.resize( self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2])) coefs, self.vknots = bspkntins(self.degree[1], coefs, self.vknots, vknots) self.cntrl = numerix.resize( coefs, (4, self.cntrl.shape[1], coefs.shape[1])) if len(uknots): # Force the u knot sequence to be a vector in ascending order uknots = numerix.sort(numerix.asarray(uknots, numerix.Float)) if numerix.any(uknots < 0.) or numerix.any(uknots > 1.): raise NURBSError, 'Illegal uknots sequence' coefs = numerix.transpose(self.cntrl, (0, 2, 1)) coefs = numerix.resize( coefs, (4 * self.cntrl.shape[2], self.cntrl.shape[1])) coefs, self.uknots = bspkntins(self.degree[0], coefs, self.uknots, uknots) coefs = numerix.resize(coefs, (4, self.cntrl.shape[2], coefs.shape[1])) self.cntrl = numerix.transpose(coefs, (0, 2, 1)) def degelev(self, utimes, vtimes=None): """Degree elevate the surface. utimes - degree elevate utimes along u direction. vtimes - degree elevate vtimes along v direction.""" if vtimes: if vtimes < 0: raise NURBSError, 'Degree must be positive' coefs = numerix.resize( self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2])) coefs, vknots, nh = bspdegelev(self.degree[1], coefs, self.vknots, vtimes) coefs = coefs[:, :nh + 1] self.vknots = vknots[:nh + self.degree[1] + vtimes + 2] self.degree[1] += vtimes self.cntrl = numerix.resize( coefs, (4, self.cntrl.shape[1], coefs.shape[1])) if utimes: if utimes < 0: raise NURBSError, 'Degree must be positive' coefs = numerix.transpose(self.cntrl, (0, 2, 1)) coefs = numerix.resize( coefs, (4 * self.cntrl.shape[2], self.cntrl.shape[1])) coefs, uknots, nh = bspdegelev(self.degree[0], coefs, self.uknots, utimes) coefs = coefs[:, :nh + 1] self.uknots = uknots[:nh + self.degree[0] + utimes + 2] self.degree[0] += utimes coefs = numerix.resize(coefs, (4, self.cntrl.shape[2], coefs.shape[1])) self.cntrl = numerix.transpose(coefs, (0, 2, 1)) def bezier(self, update=None): "Decompose surface to bezier patches and return overlaping control points." if update or not self._bezier: cntrl = numerix.resize( self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2])) cntrl = bspbezdecom(self.degree[1], cntrl, self.vknots) cntrl = numerix.resize(cntrl, (4, self.cntrl.shape[1], cntrl.shape[1])) temp1 = cntrl.shape[1] temp2 = cntrl.shape[2] cntrl = numerix.transpose(cntrl, (0, 2, 1)) cntrl = numerix.resize(cntrl, (4 * temp2, temp1)) cntrl = bspbezdecom(self.degree[0], cntrl, self.uknots) cntrl = numerix.resize(cntrl, (4, temp2, cntrl.shape[1])) self._bezier = numerix.transpose(cntrl, (0, 2, 1)) return self._bezier def bounds(self): "Return the bounding box for the surface." w = self.cntrl[3, :, :] cx = numerix.sort(numerix.ravel(self.cntrl[0, :, :] / w)) cy = numerix.sort(numerix.ravel(self.cntrl[1, :, :] / w)) cz = numerix.sort(numerix.ravel(self.cntrl[2, :, :] / w)) return numerix.asarray([cx[0], cy[0], cz[0], cx[-1], cy[-1], cz[-1]], numerix.Float) def pnt3D(self, ut, vt=None): """Evaluate parametric point[s] and return 3D cartesian coordinate[s] If only ut is given then we will evaluate at scattered points. ut(0,:) represents the u direction. ut(1,:) represents the v direction. If both parameters are given then we will evaluate over a [u,v] grid.""" val = self.pnt4D(ut, vt) if len(val.shape) < 3: return val[0:3, :] / numerix.resize(val[-1, :], (3, val.shape[1])) else: #FIX! return val[0:3, :, :] / numerix.resize( val[-1, :, :], (3, val.shape[1], val.shape[2])) def pnt4D(self, ut, vt=None): """Evaluate parametric point[s] and return 4D homogeneous coordinates. If only ut is given then we will evaluate at scattered points. ut(0,:) represents the u direction. ut(1,:) represents the v direction. If both parameters are given then we will evaluate over a [u,v] grid.""" ut = numerix.asarray(ut, numerix.Float) if numerix.any(ut < 0.) or numerix.any(ut > 1.): raise NURBSError, 'NURBS curve parameter out of range [0,1]' if vt: #FIX! # Evaluate over a [u,v] grid vt = numerix.asarray(vt, numerix.Float) if numerix.any(vt < 0.) or numerix.any(vt > 1.): raise NURBSError, 'NURBS curve parameter out of range [0,1]' val = numerix.resize( self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2])) val = bspeval(self.degree[1], val, self.vknots, vt) val = numerix.resize(val, (4, self.cntrl.shape[1], vt.shape[0])) val = numerix.transpose(val, (0, 2, 1)) val = numerix.resize(self.cntrl, (4 * vt.shape[0], self.cntrl.shape[1])) val = bspeval(self.degree[0], val, self.uknots, ut) val = numerix.resize(val, (4, vt.shape[0], ut.shape[0])) return numerix.transpose(val, (0, 2, 1)) # Evaluate at scattered points nt = ut.shape[1] uval = numerix.resize(self.cntrl, (4 * self.cntrl.shape[1], self.cntrl.shape[2])) uval = bspeval(self.degree[1], uval, self.vknots, ut[1, :]) uval = numerix.resize(uval, (4, self.cntrl.shape[1], nt)) val = numerix.zeros((4, nt), numerix.Float) for v in range(nt): val[:, v] = bspeval( self.degree[0], numerix.resize(uval[:, :, v], (4, self.cntrl.shape[1])), self.uknots, (ut[0, v], ))[:, 0] return val def plot(self, n=50, iso=8): """A simple plotting function based on dislin for debugging purpose. n = number of subdivisions. iso = number of iso line to plot in each dir. TODO: plot ctrl poins and knots.""" try: import dislin except ImportError, value: print 'dislin plotting library not available' return maxminx = numerix.sort( numerix.ravel(self.cntrl[0, :, :]) / numerix.ravel(self.cntrl[3, :, :])) minx = maxminx[0] maxx = maxminx[-1] if minx == maxx: minx -= 1. maxx += 1. maxminy = numerix.sort( numerix.ravel(self.cntrl[1, :, :]) / numerix.ravel(self.cntrl[3, :, :])) miny = maxminy[0] maxy = maxminy[-1] if miny == maxy: miny -= 1. maxy += 1. maxminz = numerix.sort( numerix.ravel(self.cntrl[2, :, :]) / numerix.ravel(self.cntrl[3, :, :])) minz = maxminz[0] maxz = maxminz[-1] if minz == maxz: minz -= 1. maxz += 1. dislin.metafl('cons') dislin.disini() dislin.hwfont() dislin.pagera() dislin.name('X-axis', 'X') dislin.name('Y-axis', 'Y') dislin.name('Z-axis', 'Z') dislin.graf3d(minx, maxx, 0, abs((maxx - minx) / 4.), miny, maxy, 0, abs((maxy - miny) / 4.), minz, maxz, 0, abs((maxz - minz) / 4.)) dislin.color('yellow') pnts0 = self.pnt3D([ numerix.arange(n + 1, typecode=numerix.Float) / n, numerix.zeros(n + 1, numerix.Float) ]) pnts1 = self.pnt3D([ numerix.arange(n + 1, typecode=numerix.Float) / n, numerix.ones(n + 1, numerix.Float) ]) pnts2 = self.pnt3D([ numerix.zeros(n + 1, numerix.Float), numerix.arange(n + 1, typecode=numerix.Float) / n ]) pnts3 = self.pnt3D([ numerix.ones(n + 1, numerix.Float), numerix.arange(n + 1, typecode=numerix.Float) / n ]) dislin.curv3d(pnts0[0, :], pnts0[1, :], pnts0[2, :], n + 1) dislin.curv3d(pnts1[0, :], pnts1[1, :], pnts1[2, :], n + 1) dislin.curv3d(pnts2[0, :], pnts2[1, :], pnts2[2, :], n + 1) dislin.curv3d(pnts3[0, :], pnts3[1, :], pnts3[2, :], n + 1) dislin.color('red') step = 1. / iso for uv in numerix.arange(step, 1., step): pnts = self.pnt3D([ numerix.arange(n + 1, typecode=numerix.Float) / n, numerix.zeros(n + 1, numerix.Float) + uv ]) dislin.curv3d(pnts[0, :], pnts[1, :], pnts[2, :], n + 1) pnts = self.pnt3D([ numerix.zeros(n + 1, numerix.Float) + uv, numerix.arange(n + 1, typecode=numerix.Float) / n ]) dislin.curv3d(pnts[0, :], pnts[1, :], pnts[2, :], n + 1) dislin.disfin()