initial commit
This commit is contained in:
156
lib/math/interpolants/CubicInterpolant.js
Normal file
156
lib/math/interpolants/CubicInterpolant.js
Normal file
@ -0,0 +1,156 @@
|
||||
import { ZeroCurvatureEnding } from '../../constants.js';
|
||||
import { Interpolant } from '../Interpolant.js';
|
||||
import { WrapAroundEnding, ZeroSlopeEnding } from '../../constants.js';
|
||||
|
||||
/**
|
||||
* Fast and simple cubic spline interpolant.
|
||||
*
|
||||
* It was derived from a Hermitian construction setting the first derivative
|
||||
* at each sample position to the linear slope between neighboring positions
|
||||
* over their parameter interval.
|
||||
*
|
||||
* @author tschw
|
||||
*/
|
||||
|
||||
function CubicInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
|
||||
|
||||
Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
|
||||
|
||||
this._weightPrev = - 0;
|
||||
this._offsetPrev = - 0;
|
||||
this._weightNext = - 0;
|
||||
this._offsetNext = - 0;
|
||||
|
||||
}
|
||||
|
||||
CubicInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
|
||||
|
||||
constructor: CubicInterpolant,
|
||||
|
||||
DefaultSettings_: {
|
||||
|
||||
endingStart: ZeroCurvatureEnding,
|
||||
endingEnd: ZeroCurvatureEnding
|
||||
|
||||
},
|
||||
|
||||
intervalChanged_: function ( i1, t0, t1 ) {
|
||||
|
||||
var pp = this.parameterPositions,
|
||||
iPrev = i1 - 2,
|
||||
iNext = i1 + 1,
|
||||
|
||||
tPrev = pp[ iPrev ],
|
||||
tNext = pp[ iNext ];
|
||||
|
||||
if ( tPrev === undefined ) {
|
||||
|
||||
switch ( this.getSettings_().endingStart ) {
|
||||
|
||||
case ZeroSlopeEnding:
|
||||
|
||||
// f'(t0) = 0
|
||||
iPrev = i1;
|
||||
tPrev = 2 * t0 - t1;
|
||||
|
||||
break;
|
||||
|
||||
case WrapAroundEnding:
|
||||
|
||||
// use the other end of the curve
|
||||
iPrev = pp.length - 2;
|
||||
tPrev = t0 + pp[ iPrev ] - pp[ iPrev + 1 ];
|
||||
|
||||
break;
|
||||
|
||||
default: // ZeroCurvatureEnding
|
||||
|
||||
// f''(t0) = 0 a.k.a. Natural Spline
|
||||
iPrev = i1;
|
||||
tPrev = t1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( tNext === undefined ) {
|
||||
|
||||
switch ( this.getSettings_().endingEnd ) {
|
||||
|
||||
case ZeroSlopeEnding:
|
||||
|
||||
// f'(tN) = 0
|
||||
iNext = i1;
|
||||
tNext = 2 * t1 - t0;
|
||||
|
||||
break;
|
||||
|
||||
case WrapAroundEnding:
|
||||
|
||||
// use the other end of the curve
|
||||
iNext = 1;
|
||||
tNext = t1 + pp[ 1 ] - pp[ 0 ];
|
||||
|
||||
break;
|
||||
|
||||
default: // ZeroCurvatureEnding
|
||||
|
||||
// f''(tN) = 0, a.k.a. Natural Spline
|
||||
iNext = i1 - 1;
|
||||
tNext = t0;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var halfDt = ( t1 - t0 ) * 0.5,
|
||||
stride = this.valueSize;
|
||||
|
||||
this._weightPrev = halfDt / ( t0 - tPrev );
|
||||
this._weightNext = halfDt / ( tNext - t1 );
|
||||
this._offsetPrev = iPrev * stride;
|
||||
this._offsetNext = iNext * stride;
|
||||
|
||||
},
|
||||
|
||||
interpolate_: function ( i1, t0, t, t1 ) {
|
||||
|
||||
var result = this.resultBuffer,
|
||||
values = this.sampleValues,
|
||||
stride = this.valueSize,
|
||||
|
||||
o1 = i1 * stride, o0 = o1 - stride,
|
||||
oP = this._offsetPrev, oN = this._offsetNext,
|
||||
wP = this._weightPrev, wN = this._weightNext,
|
||||
|
||||
p = ( t - t0 ) / ( t1 - t0 ),
|
||||
pp = p * p,
|
||||
ppp = pp * p;
|
||||
|
||||
// evaluate polynomials
|
||||
|
||||
var sP = - wP * ppp + 2 * wP * pp - wP * p;
|
||||
var s0 = ( 1 + wP ) * ppp + ( - 1.5 - 2 * wP ) * pp + ( - 0.5 + wP ) * p + 1;
|
||||
var s1 = ( - 1 - wN ) * ppp + ( 1.5 + wN ) * pp + 0.5 * p;
|
||||
var sN = wN * ppp - wN * pp;
|
||||
|
||||
// combine data linearly
|
||||
|
||||
for ( var i = 0; i !== stride; ++ i ) {
|
||||
|
||||
result[ i ] =
|
||||
sP * values[ oP + i ] +
|
||||
s0 * values[ o0 + i ] +
|
||||
s1 * values[ o1 + i ] +
|
||||
sN * values[ oN + i ];
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { CubicInterpolant };
|
30
lib/math/interpolants/DiscreteInterpolant.js
Normal file
30
lib/math/interpolants/DiscreteInterpolant.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { Interpolant } from '../Interpolant.js';
|
||||
|
||||
/**
|
||||
*
|
||||
* Interpolant that evaluates to the sample value at the position preceeding
|
||||
* the parameter.
|
||||
*
|
||||
* @author tschw
|
||||
*/
|
||||
|
||||
function DiscreteInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
|
||||
|
||||
Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
|
||||
|
||||
}
|
||||
|
||||
DiscreteInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
|
||||
|
||||
constructor: DiscreteInterpolant,
|
||||
|
||||
interpolate_: function ( i1 /*, t0, t, t1 */ ) {
|
||||
|
||||
return this.copySampleValue_( i1 - 1 );
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { DiscreteInterpolant };
|
44
lib/math/interpolants/LinearInterpolant.js
Normal file
44
lib/math/interpolants/LinearInterpolant.js
Normal file
@ -0,0 +1,44 @@
|
||||
import { Interpolant } from '../Interpolant.js';
|
||||
|
||||
/**
|
||||
* @author tschw
|
||||
*/
|
||||
|
||||
function LinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
|
||||
|
||||
Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
|
||||
|
||||
}
|
||||
|
||||
LinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
|
||||
|
||||
constructor: LinearInterpolant,
|
||||
|
||||
interpolate_: function ( i1, t0, t, t1 ) {
|
||||
|
||||
var result = this.resultBuffer,
|
||||
values = this.sampleValues,
|
||||
stride = this.valueSize,
|
||||
|
||||
offset1 = i1 * stride,
|
||||
offset0 = offset1 - stride,
|
||||
|
||||
weight1 = ( t - t0 ) / ( t1 - t0 ),
|
||||
weight0 = 1 - weight1;
|
||||
|
||||
for ( var i = 0; i !== stride; ++ i ) {
|
||||
|
||||
result[ i ] =
|
||||
values[ offset0 + i ] * weight0 +
|
||||
values[ offset1 + i ] * weight1;
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { LinearInterpolant };
|
43
lib/math/interpolants/QuaternionLinearInterpolant.js
Normal file
43
lib/math/interpolants/QuaternionLinearInterpolant.js
Normal file
@ -0,0 +1,43 @@
|
||||
import { Interpolant } from '../Interpolant.js';
|
||||
import { Quaternion } from '../Quaternion.js';
|
||||
|
||||
/**
|
||||
* Spherical linear unit quaternion interpolant.
|
||||
*
|
||||
* @author tschw
|
||||
*/
|
||||
|
||||
function QuaternionLinearInterpolant( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
|
||||
|
||||
Interpolant.call( this, parameterPositions, sampleValues, sampleSize, resultBuffer );
|
||||
|
||||
}
|
||||
|
||||
QuaternionLinearInterpolant.prototype = Object.assign( Object.create( Interpolant.prototype ), {
|
||||
|
||||
constructor: QuaternionLinearInterpolant,
|
||||
|
||||
interpolate_: function ( i1, t0, t, t1 ) {
|
||||
|
||||
var result = this.resultBuffer,
|
||||
values = this.sampleValues,
|
||||
stride = this.valueSize,
|
||||
|
||||
offset = i1 * stride,
|
||||
|
||||
alpha = ( t - t0 ) / ( t1 - t0 );
|
||||
|
||||
for ( var end = offset + stride; offset !== end; offset += 4 ) {
|
||||
|
||||
Quaternion.slerpFlat( result, 0, values, offset - stride, values, offset, alpha );
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
} );
|
||||
|
||||
|
||||
export { QuaternionLinearInterpolant };
|
Reference in New Issue
Block a user