Modifica: scusate, come sottolinea Jason nel commento, la seguente risposta non riguarda le spline ma l' interpolazione lineare bidimensionale (o bilineare ). Sto scegliendo di non eliminarlo nel caso qualcuno lo trovasse informativo.
Ho creato un semplice terreno 3D e poi volevo che il mio personaggio attraversasse il terreno. Quindi, per trovare l'altezza del personaggio in qualsiasi punto del terreno, ho usato l' interpolazione bilineare .
Ecco il codice Java che utilizzo per l'interpolazione bilineare:
/**
* Interpolates the value of a point in a two dimensional surface using bilinear spline interpolation.
* The value is calculated using the position of the point and the values of the 4 surrounding points.
* Note that the returned value can be more or less than any of the values of the surrounding points.
*
* @param p A 2x2 array containing the heights of the 4 surrounding points
* @param x The horizontal position, between 0 and 1
* @param y The vertical position, between 0 and 1
* @return the interpolated height
*/
private static float bilinearInterpolate (float[][] p, float x, float y) {
return p[0][0]*(1.0f-x)*(1.0f-y) + p[1][0]*x*(1.0f-y) + p[0][1]*(1.0f-x)*y + p[1][1]*x*y;
}
/**
* Finds a 2-dimensional array of the heights of the four points that
* surround (x,y).
*
* Uses the member variable "verts", an 2D array of Vertex objects which have
* a member "height" that is the specific vertex's height.
*/
private float[][] nearestFour(float x, float y) {
int xf = (int) Math.floor(x);
int yf = (int) Math.floor(y);
if(xf < 0 || yf < 0 || xf > verts[0].length-2 || yf > verts.length-2) {
// TODO do something better than just return 0s
return new float[][]{
{0.0f, 0.0f},
{0.0f, 0.0f}
};
} else {
return new float[][]{
{verts[yf][xf].height, verts[yf][xf+1].height},
{verts[yf+1][xf].height, verts[yf+1][xf+1].height},
};
}
}
Si noti che l'interpolazione bicubica potrebbe presentare interpolazioni più fluide o più realistiche attraverso punti distanti; ma scelgo di andare con bilineare perché ho una griglia densa, nel tentativo di ottimizzare (forse prematuramente).