package edu.stanford.rsl.conrad.geometry.splines;
import java.util.ArrayList;
import edu.stanford.rsl.conrad.geometry.AbstractShape;
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
*
*/
public class UniformCubicBSpline 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 UniformCubicBSpline(ArrayList<PointND> controlPoints,
double[] uVector) {
super(controlPoints, uVector);
}
public UniformCubicBSpline(ArrayList<PointND> controlPoints,
SimpleVector knotVector) {
super(controlPoints, knotVector);
}
public UniformCubicBSpline(UniformCubicBSpline ucs){
super(ucs);
}
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) {
double [] p = new double [getControlPoints().get(0).getDimension()];
double internal = ((t * getKnots().length) -3.0);
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;
if (internal+i < 0) {
loc = getControlPoint(0).getCoordinates();
} else {
if (internal+i>=numPts)
loc = getControlPoint(numPts-1).getCoordinates();
else
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;
}
@Override
public AbstractShape clone() {
return new UniformCubicBSpline(this);
}
}
/*
* Copyright (C) 2010-2014 Andreas Maier
* CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
*/