public class Cubic { public static final double[][] BEZIER = { // Bezier basis matrix {-1 , 3 , -3 , 1 }, { 3 , -6 , 3 , 0 }, {-3 , 3 , 0 , 0 }, { 1 , 0 , 0 , 0 } }; public static final double[][] BSPLINE = { // BSpline basis matrix {-1./6 , 3./6 , -3./6 , 1./6 }, { 3./6 , -6./6 , 3./6 , 0. }, {-3./6 , 0. , 3./6 , 0. }, { 1./6 , 4./6 , 1./6 , 0. } }; public static final double[][] CATMULL_ROM = { // Catmull-Rom basis matrix {-0.5 , 1.5 , -1.5 , 0.5 }, { 1 , -2.5 , 2 , -0.5 }, {-0.5 , 0 , 0.5 , 0 }, { 0 , 1 , 0 , 0 } }; public static final double[][] HERMITE = { // Hermite basis matrix { 2 , -2 , 1 , 1 }, {-3 , 3 , -2 , -1 }, { 0 , 0 , 1 , 0 }, { 1 , 0 , 0 , 0 } }; double a, b, c, d; // cubic coefficients vector Cubic(double[][] M, double[] G) { a = b = c = d; for (int k = 0 ; k < 4 ; k++) { // (a,b,c,d) = M G a += M[0][k] * G[k]; b += M[1][k] * G[k]; c += M[2][k] * G[k]; d += M[3][k] * G[k]; } } public double eval(double t) { return t * (t * (t * a + b) + c) + d; } double[][] C = new double[4][4]; // bicubic coefficients matrix double[][] T = new double[4][4]; // scratch matrix Cubic(double[][] M, double[][] G) { for (int i = 0 ; i < 4 ; i++) // T = G MT for (int j = 0 ; j < 4 ; j++) for (int k = 0 ; k < 4 ; k++) T[i][j] += G[i][k] * M[j][k]; for (int i = 0 ; i < 4 ; i++) // C = M T for (int j = 0 ; j < 4 ; j++) for (int k = 0 ; k < 4 ; k++) C[i][j] += M[i][k] * T[k][j]; } Cubic(double[][] G, double tension) { double S=(1-tension)/2; /* UpdateM( -S, 2-S, S-2, S, 2*S, S-3, 3-2*S, -S, -S, 0, S, 0, 0, 1, 0, 0); */ double[][] CM = { // Catmull-Rom basis matrix { -S, 2-S, S-2, S}, { 2*S, S-3, 3-2*S, -S }, { -S, 0, S, 0 }, {0, 1, 0, 0 } }; for (int i = 0 ; i < 4 ; i++) // T = G MT for (int j = 0 ; j < 4 ; j++) for (int k = 0 ; k < 4 ; k++) T[i][j] += G[i][k] * CM[j][k]; for (int i = 0 ; i < 4 ; i++) // C = M T for (int j = 0 ; j < 4 ; j++) for (int k = 0 ; k < 4 ; k++) C[i][j] += CM[i][k] * T[k][j]; } double[] C3 = C[0], C2 = C[1], C1 = C[2], C0 = C[3]; public double eval(double u, double v) { return u * (u * (u * (v * (v * (v * C3[0] + C3[1]) + C3[2]) + C3[3]) + (v * (v * (v * C2[0] + C2[1]) + C2[2]) + C2[3])) + (v * (v * (v * C1[0] + C1[1]) + C1[2]) + C1[3])) + (v * (v * (v * C0[0] + C0[1]) + C0[2]) + C0[3]); } }