package org.andork.bspline; public class FloatBSplineEvaluator { protected int degree = 0; protected int dimension = 0; protected float[ ] deboorPoints; public FloatBSplineEvaluator degree( int degree ) { this.degree = degree; updateDeBoorPoints( ); return this; } private void updateDeBoorPoints( ) { if( deboorPoints == null || deboorPoints.length < ( degree + 1 ) * dimension ) { deboorPoints = new float[ ( degree + 1 ) * dimension ]; } } public FloatBSplineEvaluator dimension( int dimension ) { this.dimension = dimension; updateDeBoorPoints( ); return this; } /** * Evaluates a b-spline curve with the given qualities. DOES NOT DO ANY ERROR CHECKING. It's up to you to ensure you pass correct values. * * @param degree * the degree of the curve * @param dimension * the number of coordinates per point * @param knots * the knots, sorted in ascending order * @param knotIndex * the index of the knot in {@code knots} such that {@code knots[index] <= param} and {@code param < knots[index + 1} * @param multiplicity * the multiplicity of {@code knots[index]} (number of adjacent equal knots) * @param points * the control points * @param pointsStride * the offset between control points. Can be different from {@code degree}. * @param param * the spline function parameter. * @param out * the array to store the evaluated point in. * @param outIndex * the index in {@code out} to store the first coordinate of the evaluated point at. */ public void eval( int degree , int dimension , float[ ] knots , int knotIndex , int multiplicity , float[ ] points , int pointsStride , float param , float[ ] out , int outIndex ) { if( param == knots[ 0 ] ) { System.arraycopy( points , 0 , out , outIndex , dimension ); return; } else if( param == knots[ knots.length - 1 ] ) { System.arraycopy( points , points.length - pointsStride , out , outIndex , dimension ); return; } int r = degree - multiplicity; for( int i = 0 ; i <= r ; i++ ) { System.arraycopy( points , ( knotIndex - degree + i ) * pointsStride , deboorPoints , i * dimension , dimension ); } for( int j = 1 ; j <= r ; j++ ) { for( int i = 0 ; i <= r - j ; i++ ) { float a = ( param - knots[ knotIndex - degree + j + i ] ) / ( knots[ i + knotIndex + 1 ] - knots[ knotIndex - degree + j + i ] ); int k0 = i * dimension; int k1 = k0 + dimension; for( int k = k0 ; k < k1 ; k++ ) { deboorPoints[ k ] = a * deboorPoints[ k + dimension ] + ( 1f - a ) * deboorPoints[ k ]; } } } System.arraycopy( deboorPoints , 0 , out , outIndex , dimension ); } }