def test_dB(self): bs = BSpline() x = np.linspace(bs.xmin, bs.xmax, 1000) N = len(x) M = bs.deg + bs.nknots + 1 for nu in xrange(1, 4): B = np.zeros((N,M)) for i in xrange(-bs.deg, bs.nknots + 1): for n in xrange(N): B[n,ix(i)] = bs.dB(nu, i, bs.deg + 1, x[n]) pass
def test_partition_of_unity(self): bs = BSpline() B = bs.spline_matrix(self.z) unity_vector = np.sum(B, axis=1) print "Matrix B" print B print "Partition of unity check" print unity_vector N, M = np.shape(B) print "checking unity_vector ..." self.assertEqual(N, sum(unity_vector)) pass
def test_dBdB(self): bs = BSpline(nknots=5) M = bs.deg + bs.nknots + 1 BB = np.zeros((M,M)) for i in xrange(-bs.deg, bs.nknots + 1): for j in xrange(i, bs.nknots + 1): BB[ix(i),ix(j)] = bs.dBdB(i, j) BB[ix(j),ix(i)] = BB[ix(i),ix(j)] print "matrix dBdB" print BB aI = 10e-6*np.eye(np.shape(BB)[0]) L = np.linalg.cholesky(BB + aI) print "Cholesky factor of matrix dBdB" print L print "sucess, matrix is 'almost' semidefinite" pass
def create_spb(spl_bnd, coors, rho=10): """ Initialize SplineBox knots, control points, base functions, ... """ dim = 2 if coors.shape[1] != dim: print 'Only 2D SplineBoxSBnd is supported!' raise (ValueError) bnd_poly = [] bnd_cp = [] for s in spl_bnd: s.set_param_n(rho) bnd_poly.append(s.eval()[:-1]) bnd_cp.append(s.get_control_points()[:-1, :]) bnd_poly.append(bnd_poly[0][0, :]) ncpoints = 1 base, bspl, uidx, ncp = [], [], [], [] for idim, si in enumerate([0, 1]): s = spl_bnd[si] bspl0 = BSpline(s.degree, ncp=s.ncp) bspl0.set_knot_vector(s.knots) bspl.append(bspl0) base.append(None) uidx.append(None) ncp.append(s.ncp) ncpoints *= s.ncp cp_idx, mul_cp_idx = SplineBox.gen_cp_idxs(ncp) cpoints = SplineRegion2D.define_control_points(nm.vstack(bnd_cp), ncp) idxs_inside = SplineRegion2D.points_in_poly(coors, nm.vstack(bnd_poly)) return { 'base': base, 'bspl': bspl, 'uidx': uidx, 'ncp': ncp, 'cp_idx': cp_idx, 'mul_cp_idx': mul_cp_idx, 'control_points': cpoints, 'idxs_inside': idxs_inside }
def create_spb(spl_bnd, coors, rho=10): """ Initialize SplineBox knots, control points, base functions, ... """ dim = 2 if coors.shape[1] != dim: print 'Only 2D SplineBoxSBnd is supported!' raise(ValueError) bnd_poly = [] bnd_cp = [] for s in spl_bnd: s.set_param_n(rho) bnd_poly.append(s.eval()[:-1]) bnd_cp.append(s.get_control_points()[:-1,:]) bnd_poly.append(bnd_poly[0][0,:]) ncpoints = 1 base, bspl, uidx, ncp = [], [], [], [] for idim, si in enumerate([0, 1]): s = spl_bnd[si] bspl0 = BSpline(s.degree, ncp=s.ncp) bspl0.set_knot_vector(s.knots) bspl.append(bspl0) base.append(None) uidx.append(None) ncp.append(s.ncp) ncpoints *= s.ncp cp_idx, mul_cp_idx = SplineBox.gen_cp_idxs(ncp) cpoints = SplineRegion2D.define_control_points(nm.vstack(bnd_cp), ncp) idxs_inside = SplineRegion2D.points_in_poly(coors, nm.vstack(bnd_poly)) return {'base': base, 'bspl': bspl, 'uidx': uidx, 'ncp': ncp, 'cp_idx': cp_idx, 'mul_cp_idx': mul_cp_idx, 'control_points': cpoints, 'idxs_inside': idxs_inside}
def create_spb(bbox, coors, degree=3, nsg=None): nc, dim = coors.shape inside = nm.ones((nc,), dtype=nm.bool) nsg = nm.ones((dim,), dtype=nm.int) if nsg is None else nm.array(nsg) for idim in range(dim): inrange = nm.logical_and(coors[:,idim] >= bbox[idim][0], coors[:,idim] <= bbox[idim][1]) inside = nm.logical_and(inside, inrange) ncpoints = 1 base, uidx, ncp, cp = [], [], [], [] for idim in range(dim): ucoors, ucoors_idx = nm.unique(coors[inside,idim], return_inverse=True) ncp0 = degree + nsg[idim] bspl = BSpline(degree, ncp=ncp0) bspl.make_knot_vector(knot_range=(bbox[idim][0], bbox[idim][1])) knots = bspl.get_knot_vector() cp0 = nm.zeros((ncp0,), dtype=nm.double) for j in range(cp0.shape[0]): cp0[j] = nm.sum(knots[(j + 1):(j + degree + 1)]) / degree base.append(bspl.eval_basis(t=ucoors, return_val=True)) uidx.append(ucoors_idx) ncp.append(ncp0) cp.append(cp0) ncpoints *= ncp0 cpoints = nm.zeros((ncpoints, dim), dtype=nm.double) cp_idx, mul_cp_idx = SplineBox.gen_cp_idxs(ncp) for ii in range(dim): cpoints[:,ii] = cp[ii][cp_idx[ii]] return {'base': base, 'uidx': uidx, 'ncp': ncp, 'cp_idx': cp_idx, 'mul_cp_idx': mul_cp_idx, 'control_points': cpoints, 'idxs_inside' : inside}
def __init__( self , fov , ratio , near , far , skybox_img , duck_img ) : self.fov = fov self.far = far self.near = near self.ratio = ratio self.last_time = timer() self.water = Water( 128 ) self.box = Skybox( skybox_img ) self.duck = Mesh( 'data/duck.gpt' , duck_img , 'shad/anisotropic' ) self.path = BSpline( (-1,1) , (-1,1) ) self.light = np.array( (0,2,0) ) self.water.drop_rnd()
def create_spb(bbox, coors, degree=3, nsg=None): bbox = nm.array(bbox) coors = nm.array(coors) dim = coors.shape[1] spbox = [] if nsg is None: nsg = nm.ones((dim,), dtype=nm.int) else: nsg = nm.array(nsg) ncpoints = 1 spbox = {'base': [None] * dim, 'uidx': [None] * dim, 'cp': [None] * dim, 'ncp': [None] * dim, 'cp_idx': [None] * dim} for idim in range(dim): ucoors, ucoors_idx = nm.unique(coors[:,idim], return_inverse=True) ncp = degree + nsg[idim] bspl = BSpline(degree, ncp=ncp) bspl.make_knot_vector(knot_range=(bbox[idim,0], bbox[idim,1])) knots = bspl.get_knot_vector() cp = nm.zeros((ncp,), dtype=nm.double) for j in range(cp.shape[0]): cp[j] = nm.sum(knots[(j + 1):(j + degree + 1)]) / degree spbox['base'][idim] = bspl.eval_basis(t=ucoors, return_val=True).copy() spbox['uidx'][idim] = ucoors_idx[:] spbox['cp'][idim] = cp[:] spbox['ncp'][idim] = ncp ncpoints *= ncp cpoints = nm.zeros((ncpoints, dim), dtype=nm.double) ncp = spbox['ncp'] cp = spbox['cp'] if dim == 2: idxs = nm.mgrid[0:ncp[0],0:ncp[1]] elif dim == 3: idxs = nm.mgrid[0:ncp[0],0:ncp[1],0:ncp[2]] aux = [1] for ii in range(dim - 1): aux.append(aux[ii] * ncp[ii]) spbox['mul_cp_idx'] = nm.array(aux) for ii in range(dim): spbox['cp_idx'][ii] = idxs[ii].reshape(ncpoints, order='F') cpoints[:,ii] = cp[ii][spbox['cp_idx'][ii]] return spbox, cpoints
def create_spb(bbox, coors, degree=3, nsg=None): nc, dim = coors.shape inside = nm.ones((nc, ), dtype=nm.bool) nsg = nm.ones((dim, ), dtype=nm.int) if nsg is None else nm.array(nsg) for idim in range(dim): inrange = nm.logical_and(coors[:, idim] >= bbox[idim][0], coors[:, idim] <= bbox[idim][1]) inside = nm.logical_and(inside, inrange) ncpoints = 1 base, uidx, ncp, cp = [], [], [], [] for idim in range(dim): ucoors, ucoors_idx = nm.unique(coors[inside, idim], return_inverse=True) ncp0 = degree + nsg[idim] bspl = BSpline(degree, ncp=ncp0) bspl.make_knot_vector(knot_range=(bbox[idim][0], bbox[idim][1])) knots = bspl.get_knot_vector() cp0 = nm.zeros((ncp0, ), dtype=nm.double) for j in range(cp0.shape[0]): cp0[j] = nm.sum(knots[(j + 1):(j + degree + 1)]) / degree base.append(bspl.eval_basis(t=ucoors, return_val=True)) uidx.append(ucoors_idx) ncp.append(ncp0) cp.append(cp0) ncpoints *= ncp0 cpoints = nm.zeros((ncpoints, dim), dtype=nm.double) cp_idx, mul_cp_idx = SplineBox.gen_cp_idxs(ncp) for ii in range(dim): cpoints[:, ii] = cp[ii][cp_idx[ii]] return { 'base': base, 'uidx': uidx, 'ncp': ncp, 'cp_idx': cp_idx, 'mul_cp_idx': mul_cp_idx, 'control_points': cpoints, 'idxs_inside': inside }
class Scene : def __init__( self , fov , ratio , near , far , skybox_img , duck_img ) : self.fov = fov self.far = far self.near = near self.ratio = ratio self.last_time = timer() self.water = Water( 128 ) self.box = Skybox( skybox_img ) self.duck = Mesh( 'data/duck.gpt' , duck_img , 'shad/anisotropic' ) self.path = BSpline( (-1,1) , (-1,1) ) self.light = np.array( (0,2,0) ) self.water.drop_rnd() def gfx_init( self ) : self.camera = Camera( ( 0 , 5 , 0 ) , ( 1 , 1 , 0 ) , ( 1 , 0 , 0 ) ) self._update_proj() self.water.gfx_init() self.box .gfx_init() self.duck .gfx_init() def draw( self ) : self.time = timer() dt = self.time - self.last_time glMatrixMode(GL_MODELVIEW) glLoadIdentity() self.camera.look() self.box.draw() self.path.next( dt ) self.water.drop( *((self.path.value+1.0)*self.water.n/2.0) , force = np.linalg.norm(self.path.tangent)*25 ) self.water.step( dt * .5 ) self.water.draw( self.box.texture , self.camera.matrix ) self.duck.draw( self.path.value , self.path.tangent , self.light ) self.last_time = self.time def set_fov( self , fov ) : self.fov = fov self._update_proj() def set_near( self , near ) : self.near = near self._update_proj() def set_ratio( self , ratio ) : self.ratio = ratio self._update_proj() def set_screen_size( self , w , h ) : self.width = w self.height = h self.set_ratio( float(w)/float(h) ) def set_fov( self , fov ) : self.fov = fov self._update_proj() def set_near( self , near ) : self.near = near self._update_proj() def set_ratio( self , ratio ) : self.ratio = ratio self._update_proj() def set_screen_size( self , w , h ) : self.width = w self.height = h self.set_ratio( float(w)/float(h) ) def mouse_move( self , df ) : self.camera.rot( *map( lambda x : -x*.2 , df ) ) def key_pressed( self , mv ) : self.camera.move( *map( lambda x : x*.05 , mv ) ) def _update_proj( self ) : glMatrixMode(GL_PROJECTION) glLoadIdentity() gluPerspective( self.fov , self.ratio , self.near , self.far ) glMatrixMode(GL_MODELVIEW)
from bspline import BSpline from display import display if __name__ == "__main__": # 2d b = BSpline([[2, 5], [3, 4], [5, 7], [1, 2], [1, 8], [7, 5]]) display(b) # 3d b = BSpline([[2, 5, 5], [3, 4, 3], [5, 7, 4], [1, 2, 2], [1, 8, 3], [7, 5, 2]]) display(b) # Surface splines = [BSpline([[2, i, 5], [5, i, 4], [1, i, 2], [7, i, 2]]) for i in range(-5, 5)] display(splines)
def test_fit(self): print "Fitting spline to data ..." bs = BSpline() bs.fit(self.z, self.y_noizy, alpha=0.01) pass
def test_print(self): bs = BSpline() bs._print() pass