float Noise::interpolateNoise(float x, float y) { int wholePartX = (int) x; // Same as flooring. float fractionPartX = x - wholePartX; int wholePartY = (int) y; float fractionPartY = y - wholePartY; float v1 = nextFloat(wholePartX, wholePartY); float v2 = nextFloat(wholePartX + 1, wholePartY); float v3 = nextFloat(wholePartX, wholePartY + 1); float v4 = nextFloat(wholePartX + 1, wholePartY + 1); float i1 = InterpolateCubic(v1, v2, fractionPartX); float i2 = InterpolateCubic(v3, v4, fractionPartX); return InterpolateCubic(i1, i2, fractionPartY); }
__kernel void SliceTimingCorrection(__global float* Corrected_Volumes, __global const float* Volumes, __private float delta, __private int DATA_W, __private int DATA_H, __private int DATA_D, __private int DATA_T) { int x = get_global_id(0); int y = get_global_id(1); int3 tIdx = {get_local_id(0), get_local_id(1), get_local_id(2)}; if (x >= DATA_W || y >= DATA_H) return; float t0, t1, t2, t3; // Forward interpolation if (delta > 0.0f) { t0 = Volumes[Calculate3DIndex(x,y,0,DATA_W,DATA_H)]; t1 = t0; t2 = Volumes[Calculate3DIndex(x,y,1,DATA_W,DATA_H)]; t3 = Volumes[Calculate3DIndex(x,y,2,DATA_W,DATA_H)]; // Loop over timepoints for (int t = 0; t < DATA_T - 3; t++) { // Cubic interpolation in time Corrected_Volumes[Calculate3DIndex(x,y,t,DATA_W,DATA_H)] = InterpolateCubic(t0,t1,t2,t3,delta); // Shift old values backwards t0 = t1; t1 = t2; t2 = t3; // Read one new value t3 = Volumes[Calculate3DIndex(x,y,t+3,DATA_W,DATA_H)]; } int t = DATA_T - 3; Corrected_Volumes[Calculate3DIndex(x,y,t,DATA_W,DATA_H)] = InterpolateCubic(t0,t1,t2,t3,delta); t = DATA_T - 2; t0 = t1; t1 = t2; t2 = t3; Corrected_Volumes[Calculate3DIndex(x,y,t,DATA_W,DATA_H)] = InterpolateCubic(t0,t1,t2,t3,delta); t = DATA_T - 1; t0 = t1; t1 = t2; Corrected_Volumes[Calculate3DIndex(x,y,t,DATA_W,DATA_H)] = InterpolateCubic(t0,t1,t2,t3,delta); } // Backward interpolation else { delta = 1.0f - (-delta); t0 = Volumes[Calculate3DIndex(x,y,0,DATA_W,DATA_H)]; t1 = t0; t2 = t0; t3 = Volumes[Calculate3DIndex(x,y,1,DATA_W,DATA_H)]; // Loop over timepoints for (int t = 0; t < DATA_T - 2; t++) { // Cubic interpolation in time Corrected_Volumes[Calculate3DIndex(x,y,t,DATA_W,DATA_H)] = InterpolateCubic(t0,t1,t2,t3,delta); // Shift old values backwards t0 = t1; t1 = t2; t2 = t3; // Read one new value t3 = Volumes[Calculate3DIndex(x,y,t+2,DATA_W,DATA_H)]; } int t = DATA_T - 2; Corrected_Volumes[Calculate3DIndex(x,y,t,DATA_W,DATA_H)] = InterpolateCubic(t0,t1,t2,t3,delta); t = DATA_T - 1; t0 = t1; t1 = t2; t2 = t3; Corrected_Volumes[Calculate3DIndex(x,y,t,DATA_W,DATA_H)] = InterpolateCubic(t0,t1,t2,t3,delta); }
T InterpolateCubic (T prev, T start, T end, T after, float startT, float endT, float time) { return InterpolateCubic(prev, start, end, after, (time-startT)/(endT-startT)); };