Edit: Désolé, comme Jason le souligne dans le commentaire, la réponse suivante ne concerne pas les splines mais l' interpolation linéaire (ou bilinéaire ) bidimensionnelle . Je choisis de ne pas le supprimer au cas où quelqu'un pourrait le trouver informatif.
J'ai créé un terrain 3D simple et j'ai ensuite voulu que mon personnage traverse le terrain. Donc, pour trouver la hauteur du personnage à n'importe quel point du terrain, j'ai utilisé une interpolation bilinéaire .
Voici le code Java que j'utilise pour l'interpolation bilinéaire:
/**
* 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},
};
}
}
Notez que l'interpolation bicubique peut présenter une interpolation plus douce ou plus réaliste sur des points distants; mais je choisis d'aller avec bilinéaire car j'ai une grille dense, dans une tentative d'optimisation (peut-être prématurément).