1.双线性插值
线性插值是游戏Unity开发过程中非常常用的算法,在Unity中直接使用 lerp函数就可以实现。但对于双线性插值,Unity并没有给出可以直接使用了API,下面会给出一个利用C#对二维数组进行双线性插值的算法。
下图是双线性插值的示意图(图片取自维基百科英文页),对于一个正方形的区域,已知四个顶点的值,我们希望通过这四个值获取正方形区域某一位置的值,就要用到双线性插值。我们对四个点取权值,我们假设整个正方形区域的面积为1,求点(x,y)的值就可以把这一个块面积分成四个,每块区域的面积占总面的比例就是其对应顶点的权值,比如右上角的顶点所占的权值就是黄色区域面积占总面积的比例。
2.c#实现
这里传入一个原始数组以及目标数组的第一维和第二维的长度,返回目标数组。
public static float[,] BilinearInterp(float[,] array, int length_0, int length_1)
{
float[,] _out = new float[length_0, length_1];
int original_0 = array.GetLength(0);
int original_1 = array.GetLength(1);
float ReScale_0 = original_0 / ((float)length_0); // 倍数的倒数
float ReScale_1 = original_1 / ((float)length_1);
float index_0;
float index_1;
int inde_0;
int inde_1;
float s_leftUp;
float s_rightUp;
float s_rightDown;
float s_leftDown;
for (int i = 0; i < length_0; i++)
{
for (int j = 0; j < length_1; j++)
{
index_0 = i * ReScale_0;
index_1 = j * ReScale_1;
inde_0 = Mathf.FloorToInt(index_0);
inde_1 = Mathf.FloorToInt(index_1);
s_leftUp = (index_0 - inde_0) * (index_1 - inde_1);
s_rightUp = (inde_0 + 1 - index_0) * (index_1 - inde_1);
s_rightDown = (inde_0 + 1 - index_0) * (inde_1 + 1 - index_1);
s_leftDown = (index_0 - inde_0) * (inde_1 + 1 - index_1);
_out[i, j] = array[inde_0, inde_1] * s_rightDown + array[inde_0 + 1, inde_1] * s_leftDown + array[inde_0 + 1, inde_1 + 1] * s_leftUp + array[inde_0, inde_1 + 1] * s_rightUp;
}
}
return _out;
}