📄 tobezier.cc
字号:
}}/*----------------------------------------------------------------------------- * Knotspec::showpts - print out points before transformation * * Client: Knotspec::select *----------------------------------------------------------------------------- */voidKnotspec::showpts( REAL *outpt ){ if( next ) { for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) next->showpts( outpt ); } else { for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) _glu_dprintf( "show %g %g %g\n", outpt[0], outpt[1], outpt[2] ); }}/*----------------------------------------------------------------------------- * Knotspec::factors - precompute scale factors * - overwrites knot vector, actual new knot vector is NOT produced * * Client: Knotspec::select *----------------------------------------------------------------------------- */voidKnotspec::factors( void ){ Knot *mid = (outkend - 1) - order + bend->multi; Knot_ptr fptr = sbegin; for( Breakpt *bpt = bend; bpt >= bbegin; bpt-- ) { mid -= bpt->multi; // last knot less than knot to insert int def = bpt->def - 1; // number of knots to insert if( def <= 0 ) continue; Knot kv = bpt->value; // knot to insert Knot *kf = (mid-def) + (order-1); for( Knot *kl = kf + def; kl != kf; kl-- ) { Knot *kh, *kt; for( kt=kl, kh=mid; kt != kf; kh--, kt-- ) *(fptr++) = (kv - *kh) / (*kt - *kh); *kl = kv; } }}/*----------------------------------------------------------------------------- * Knotspec::insert - convert subobject in direction of kspec into Bezier * * Client: Knotspec::transform *----------------------------------------------------------------------------- */voidKnotspec::insert( REAL *p ){ Knot_ptr fptr = sbegin; REAL *srcpt = p + prewidth - poststride; REAL *dstpt = p + postwidth + postoffset - poststride; Breakpt *bpt = bend; for( REAL *pend = srcpt - poststride*bpt->def; srcpt != pend; pend +=poststride ) { REAL *p1 = srcpt; for( REAL *p2 = srcpt-poststride; p2 != pend; p1 = p2, p2 -= poststride ) { pt_oo_sum( p1, p1, p2, *fptr, 1.0-*fptr ); fptr++; } } for( --bpt; bpt >= bbegin; bpt-- ) { for( int multi = bpt->multi; multi > 0; multi-- ) { pt_oo_copy( dstpt, srcpt ); dstpt -= poststride; srcpt -= poststride; } for( REAL *pend = srcpt - poststride*bpt->def; srcpt != pend; pend +=poststride, dstpt-=poststride ) { pt_oo_copy( dstpt, srcpt ); REAL *p1 = srcpt; for( REAL *p2 = srcpt-poststride; p2 != pend; p1=p2, p2 -= poststride ) { pt_oo_sum( p1, p1, p2, *fptr, 1.0-*fptr ); fptr++; } } }}/*----------------------------------------------------------------------------- * Knotspec::preselect - initialize kspec for processing * * Client: Splinespec::select *----------------------------------------------------------------------------- */voidKnotspec::preselect( void ){ Knot kval; /* position klast after last knot of "last" breakpoint */ for( klast = inkend - order, kval = *klast; klast != inkend; klast++ ) if( ! identical( *klast, kval ) ) break; /* position kfirst after last knot of "first" breakpoint */ for( kfirst = inkbegin+order-1, kval= *kfirst; kfirst != inkend; kfirst++ ) if( ! identical( *kfirst, kval ) ) break; /* compute multiplicity of first breakpoint */ Knot_ptr k; for( k = kfirst - 1; k >= inkbegin; k-- ) if( ! identical( kval, *k ) ) break; k++; /* allocate space for breakpoints - use worst case estimate on number of breakpoints */ bbegin = new Breakpt[(klast - kfirst)+1]; /* record multiplicity and value of first breakpoint */ bbegin->multi = kfirst - k; bbegin->value = kval; bend = bbegin; kleft = kright = kfirst;}/*----------------------------------------------------------------------------- * Knotspec::select - Knotspec::select segments and precompute scale factors * * Client: Splinespec::select *----------------------------------------------------------------------------- */voidKnotspec::select( void ){ breakpoints(); knots(); factors(); preoffset = kleft - (inkbegin + order); postwidth = (int)((bend - bbegin) * order); prewidth = (int)((outkend - outkbegin) - order); postoffset = (bbegin->def > 1) ? (bbegin->def-1) : 0;} /*----------------------------------------------------------------------------- * Knotspec::breakpoints - compute breakpoints for knotspec * * Client: Knotspec::select *----------------------------------------------------------------------------- */voidKnotspec::breakpoints( void ){ Breakpt *ubpt = bbegin; Breakpt *ubend = bend; long nfactors = 0; ubpt->value = ubend->value; ubpt->multi = ubend->multi; kleft = kright; for( ; kright != klast; kright++ ) { if ( identical(*kright,ubpt->value) ) { (ubpt->multi)++; } else { ubpt->def = (int) (order - ubpt->multi); nfactors += (ubpt->def * (ubpt->def - 1)) / 2; (++ubpt)->value = *kright; ubpt->multi = 1; } } ubpt->def = (int) (order - ubpt->multi); nfactors += (ubpt->def * (ubpt->def - 1)) / 2; bend = ubpt; if( nfactors ) { sbegin = new Knot[nfactors]; } else { sbegin = NULL; }}/*----------------------------------------------------------------------------- * Knotspec::knots - copy relevant subsequence of knots into temporary area * * Client: Knotspec::select *----------------------------------------------------------------------------- */voidKnotspec::knots( void ){ Knot_ptr inkpt = kleft - order; Knot_ptr inkend = kright + bend->def; /* allocate space for knots and factors */ outkbegin = new Knot[inkend-inkpt]; Knot_ptr outkpt; for( outkpt = outkbegin; inkpt != inkend; inkpt++, outkpt++ ) *outkpt = *inkpt; outkend = outkpt;}/*----------------------------------------------------------------------------- * Knotspec::transform - convert a spline along a given direction * * Client: Splienspec::transform *----------------------------------------------------------------------------- */voidKnotspec::transform( REAL *p ){ if( next ) { if( this == kspectotrans ) { next->transform( p ); } else { if( istransformed ) { p += postoffset; for( REAL *pend = p + postwidth; p != pend; p += poststride ) next->transform( p ); } else { REAL *pend = p + prewidth; for( ; p != pend; p += poststride ) next->transform( p ); } } } else { if( this == kspectotrans ) { insert( p ); } else { if( istransformed ) { p += postoffset; for( REAL *pend = p + postwidth; p != pend; p += poststride ) kspectotrans->insert( p ); } else { REAL *pend = p + prewidth; for( ; p != pend; p += poststride ) kspectotrans->insert( p ); } } }}/*----------------------------------------------------------------------------- * Knotspec::~Knotspec - free space alocated for knotspec *----------------------------------------------------------------------------- */Knotspec::~Knotspec( void ){ if( bbegin ) delete[] bbegin; if( sbegin ) delete[] sbegin; if( outkbegin ) delete[] outkbegin;}/*----------------------------------------------------------------------------- * pt_io_copy - make internal copy of input cntrl pt. of x coords *----------------------------------------------------------------------------- */voidKnotspec::pt_io_copy( REAL *topt, INREAL *frompt ){ switch( ncoords ) { case 4: topt[3] = (REAL) frompt[3]; case 3: topt[2] = (REAL) frompt[2]; case 2: topt[1] = (REAL) frompt[1]; case 1: topt[0] = (REAL) frompt[0]; break; default: { for( int i = 0; i < ncoords; i++ ) *topt++ = (REAL) *frompt++; } }}/*----------------------------------------------------------------------------- * pt_oo_copy - make internal copy of internal cntrl pt. of x coords *----------------------------------------------------------------------------- */voidKnotspec::pt_oo_copy( REAL *topt, REAL *frompt ){ switch( ncoords ) { case 4: topt[3] = frompt[3]; case 3: topt[2] = frompt[2]; case 2: topt[1] = frompt[1]; case 1: topt[0] = frompt[0]; break; default: memcpy( topt, frompt, ncoords * sizeof( REAL ) ); }}/*----------------------------------------------------------------------------- * pt_oo_sum - compute affine combination of internal cntrl pts *----------------------------------------------------------------------------- */voidKnotspec::pt_oo_sum( REAL *x, REAL *y, REAL *z, Knot a, Knot b ){ switch( ncoords ) { case 4: x[3] = a * y[3] + b * z[3]; case 3: x[2] = a * y[2] + b * z[2]; case 2: x[1] = a * y[1] + b * z[1]; case 1: x[0] = a * y[0] + b * z[0]; break; default: { for( int i = 0; i < ncoords; i++ ) *x++ = a * *y++ + b * *z++; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -