1.要求
在8*8網格下求某點的全區間內插要求X方向和Y方向前後各取4個點求X值和Y值。主要考慮0個點/1個點/2個點/3個點的情況。
2.算法實現
從8*8的格網中考慮前後4個點的插值是不可能的,只可能一邊到4個點,一邊未到4個點,如果靠單邊的4個點進行插值,顯然不合理。算法設計時考慮了對稱插值,即x,y假如一邊有3個點,則另一邊也取3個點,一邊2個點,另一邊也取2個點。實現算法如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SpaceInterpolation
{
class InterpolationClass
{
///<summary>
///點集數據
///</summary>
privatedouble[,] _data;
public double[,] Data
{
get{ return _data; }
set{ _data = value; }
}
///<summary>
///插值單邊點數
///</summary>
privateint _num;
public int Num
{
get{ return _num; }
set{ _num = value; }
}
publicInterpolationClass(double[,] data)
{
_data = data;
_num = 4;
}
///<summary>
///獲取插值結果
///</summary>
///<paramname="x">插值結果X</param>
///<paramname="y">插值結果Y</param>
///<returns>插值結果</returns>
public double getValue(doublex, double y)
{
//保持對稱性
doubletmpxNum = _num;
doubletmpyNum = _num;
if(x <= _num)
{
tmpxNum = Math.Floor(x);
}
elseif (x >= _data.GetLength(0) - _num - 1)
{
tmpxNum = Math.Floor(_data.GetLength(0) - x);
}
if(y <= _num)
{
tmpyNum = Math.Floor(x);
}
elseif (y >= _data.GetLength(0) - _num - 1)
{
tmpyNum = Math.Floor(_data.GetLength(1) - y);
}
intstartX = Math.Max((int)(Math.Floor(x - tmpxNum)),0);
intstartY = Math.Max((int)(Math.Floor(y - tmpyNum)),0);
intendX = Math.Min((int)(Math.Floor(x + tmpxNum)),7);
intendY = Math.Min((int)(Math.Floor(y + tmpyNum)),7);
double[]tmp = new double[endX-startX+1];
//先計算臨時向量
for(int i = startX; i <= endX; i++)
{
for(int j = startY; j <= endY; j++)
{
doublelag = 1.0;
for(int k = startY; k <= endY; k++)
{
if(j != k)
lag *= (y - k) / (j- k);
}
tmp[i - startX] += lag *_data[i, j];
}
}
doubleres = 0;
//再計算完整的值
for(int i = startX; i <= endX; i++)
{
doublelag = 1.0;
for(int j = startX; j <= endX; j++)
{
if(i!=j)
lag *= (x - j) / (i -j);
}
res += lag * tmp[i - startX];
}
returnres;
}
}
}
3.分析
座標系統爲(0-7,0-7),格網的數據取隨機數0~100,取點(3.5,2.7)得出的結果爲56.3397912,綜合附近的像素值,發現其插值結果是合理的。
然後我們取邊外界值(7.2,7.2),此時退化爲最鄰近插值
然後我們取邊界值(0.5,0.5),此時退化爲雙線性插值