雙線性插值 - c#實現
阿新 • • 發佈:2019-01-01
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; }