双线性插值 - c#实现

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;
    }

猜你喜欢

转载自blog.csdn.net/xdedzl/article/details/85414427