content: package edu.stanford.rsl.conrad.geometry.splines;
  
  import java.util.ArrayList;
  
  import edu.stanford.rsl.conrad.geometry.shapes.simple.PointND;
  import edu.stanford.rsl.conrad.numerics.SimpleVector;
  
  /**
   * Implementation after Ruijters, Romeny & Suetens.
   * "Efficient GPU-Based Textutre Interpolation using Uniform B-Splines". 2009
   * 
   * @author akmaier; modifications for closed cubic b-spline curve by jrausch
   *
   */
  public class ClosedCubicBSpline extends BSpline {
  
  	public static double oneOverSix = 1.0 / 6.0;
  	public static double twoOverThree = 2.0 / 3.0;
  
  	/**
  	 * 
  	 * 
  	 */
  	private static final long serialVersionUID = 8467214013384105086L;
  
  	public ClosedCubicBSpline(ArrayList<PointND> controlPoints,
  			double[] uVector) {
  		super(controlPoints, uVector);		
  	}
  
  	public ClosedCubicBSpline(ArrayList<PointND> controlPoints,
  			SimpleVector knotVector) {
  		super(controlPoints, knotVector);
  	}
  
  	public static double [] getWeights(double t){
  		double [] revan = new double [4];
  		double index = Math.floor(t);
  		double alpha = t - index;
  		double oneAlpha = 1.0 - alpha;
  		double oneAlphaSquare = oneAlpha * oneAlpha;
  		double alphaSquare = alpha * alpha;
  		revan[0] = oneOverSix * oneAlphaSquare * oneAlpha;
  		revan[1] = twoOverThree - 0.5 * alphaSquare *(2.0-alpha);
  		revan[2] = twoOverThree - 0.5 * oneAlphaSquare * (2.0-oneAlpha);
  		revan[3] = oneOverSix * alphaSquare * alpha;
  		return revan;
  	}
  
  
  	public double [] evalFast(double t) {
  		if(t == 0.5)
  			System.out.println("   ");
  		double [] p = new double [getControlPoints().get(0).getDimension()];
  		double internal = ((t * getKnots().length));
  		int numPts = getControlPoints().size();
  		double step = internal- Math.floor(internal);
  
  		//System.out.println(t + " " + internal);
  		double [] weights = getWeights(step);
  		for (int i=0;i<4;i++){
  			double [] loc; 
  				loc = getControlPoint((int) (internal+i)).getCoordinates();
  			for (int j = 0; j < loc.length; j++) {
  				p[j] += (loc[j] * weights[i]);
  				//p[j] = loc[j];
  			}
  		}
  		return p;
  	}
  	
  
  
  }
  