⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tobezier.cc

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 CC
📖 第 1 页 / 共 2 页
字号:
     }
}

/*-----------------------------------------------------------------------------
 * Knotspec::showpts - print out points before transformation
 *
 * Client: Knotspec::select
 *-----------------------------------------------------------------------------
 */
void
Knotspec::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 )
	    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
 *-----------------------------------------------------------------------------
 */

void
Knotspec::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
 *-----------------------------------------------------------------------------
 */

void
Knotspec::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
 *-----------------------------------------------------------------------------
 */

void
Knotspec::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
 *-----------------------------------------------------------------------------
 */

void
Knotspec::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
 *-----------------------------------------------------------------------------
 */

void
Knotspec::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
 *-----------------------------------------------------------------------------
 */

void
Knotspec::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
 *-----------------------------------------------------------------------------
 */

void
Knotspec::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
 *-----------------------------------------------------------------------------
 */

void
Knotspec::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
 *-----------------------------------------------------------------------------
 */

void
Knotspec::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
 *-----------------------------------------------------------------------------
 */

void
Knotspec::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 + -