Bearbeiten: Entschuldigung, wie Jason im Kommentar betont, handelt die folgende Antwort nicht von Splines, sondern von zweidimensionaler linearer (oder bilinearer ) Interpolation. Ich entscheide mich, es nicht zu löschen, falls jemand es informativ findet.
Ich habe ein einfaches 3D-Terrain erstellt und wollte dann, dass mein Charakter über das Terrain läuft. Um die Höhe des Charakters an einem beliebigen Punkt im Gelände zu ermitteln, habe ich die bilineare Interpolation verwendet .
Hier ist der Java-Code, den ich für die bilineare Interpolation verwende:
/**
* 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},
};
}
}
Beachten Sie, dass die bikubische Interpolation eine gleichmäßigere oder realistischere Interpolation über entfernte Punkte hinweg ermöglichen kann. Aber ich entscheide mich für bilinear, weil ich ein dichtes Gitter habe, um zu optimieren (vielleicht vorzeitig).