基於Excel的查表插值計算工具及算法詳解

一、基於Excel的查表插值計算工具

二維查表算法是控制器軟件開發中最爲基礎的算法之一,同時進行二維查表計算也是標定開發過程中常見操作。
模型代碼中的查表函數
通常一維線性插值算法可以採用手工計算的方式;二維查表插值算法則多采用Matlab、Origin等軟件實現,但上述軟件體積較大,操作複雜,並不適合日常辦公使用。

爲此製作了基於Excel的查表插值計算工具,其操作界面如下:
在這裏插入圖片描述

其使用方法如下:
1、將INCA中的二維MAP表格的X軸座標值、Y座標值、MAP值分別填入Excel中對應的位置。
在這裏插入圖片描述
注意

  • 本工具X軸最大長度爲25,Y軸最大長度20
  • X軸與Y軸座標值務必是單調遞增趨勢
    在這裏插入圖片描述
    2、填寫Y軸取值點以及X軸取值點(X軸可選取多個點),按下計算按鍵後,藍色框區會自動顯示查表插值算法的結果。

在這裏插入圖片描述

二、查表插值算法詳解

1、舉例計算X=18,Y=850時,Z點的取值 ?
在這裏插入圖片描述
二維查表函數如下:

        // 查表函數  x = 橫座標取點值     y = 縱座標取點值    z =返回查表結果
        public float GetElementAt(float x, float y)         
        {
            uint x_index, y_index;
            float x_offset, y_offset;
            float x_distance, y_distance, result;

            // 計算X軸 起始座標索引、偏移量、起始座標索引至下一個座標索引點的距離
            SearchDistrX(x, out x_index, out x_offset, out x_distance);

            // 計算Y軸 起始座標索引、偏移量、起始座標索引至下一個座標索引點的距離
            SearchDistrY(y, out y_index, out y_offset, out y_distance);

            // 根據X,Y軸座標信息計算MAP插值
             return result = GetDeltaAt(x_index, x_offset, x_distance, y_index, y_offset, y_distance);
        }

獲取 X=18,Y=850時,Z點的取值?

float Z = GetElementAt(18.00 , 850)  

2、首先計算X在起始座標索引、偏移量、起始座標索引至下一個座標索引點的距離,out關鍵字類似指針的效果,表示此處輸出參數值

SearchDistrX(x, out x_index, out x_offset, out x_distance);
運算結果 SearchDistrX(18, 3, 3, 5);

如圖所示,將x=18帶入函數可得( x 值在[15,20]的座標區間中)
x_index = 3; 區間起始座標點對應的下標值(X3)
x_offset = 3; x值(18) - 區間起始座標點(15)
x_distance = 5;區間結束座標點(20) - 區間起始座標點(15)
在這裏插入圖片描述

3、同理計算Y在起始座標索引、偏移量、起始座標索引至下一個座標索引點的距離

SearchDistrY(y, out y_index, out y_offset, out y_distance);
運算結果 SearchDistrY(850, 1, 422.5, 427.25);

4、將上述計算結果帶入MAP插值計算函數中

// 根據X,Y軸座標信息計算MAP插值
result = GetDeltaAt(3, 3, 5, 1, 422.5, 427.25);
        public float GetDeltaAt(uint x_index, float x_offset, float x_distance, uint y_index, float y_offset, float y_distance)
        {
            float v00, v01, v10, v11, v0, v1, result;

            // 獲取需查詢的MAP值所在的左上角單元格數值
            v00 = this.zMapValue[y_index, x_index];  /* base value at vMat[x1,y1]*/

            // 需查詢的MAP值在二維數組範圍內
            if ((x_index < (this.xAxisLen - 1)) && (y_index < (this.yAxisLen - 1)))
            {
                // 獲取需查詢的MAP值所在的右上角單元格數值
                v01 = this.zMapValue[y_index, x_index + 1];
                // 獲取需查詢的MAP值所在的左下角單元格數值
                v10 = this.zMapValue[y_index + 1, x_index];
                // 獲取需查詢的MAP值所在的右下角單元格數值
                v11 = this.zMapValue[y_index + 1, x_index + 1];      
            }
            // 如果需查詢的MAP值Y座標超過最大邊界
            else if ((x_index < (this.xAxisLen - 1)) && (y_index == (this.yAxisLen - 1)))
            {
                // // 獲取需查詢的MAP值所在的右上角單元格數值
                v01 = this.zMapValue[y_index, x_index + 1];
                // 因爲Y軸超邊界, 左下角單元格數值  == 左上角單元格數值
                v10 = v00;
                // 因爲Y軸超邊界, 右下角單元格數值  == 右上角單元格數值
                v11 = v01;
            }
            // 如果需查詢的MAP值X座標超過最大邊界
            else if ((x_index == (this.xAxisLen - 1)) && (y_index < (this.yAxisLen - 1)))
            {
                // 獲取需查詢的MAP值所在的左下角單元格數值
                v10 = this.zMapValue[y_index + 1, x_index];
                // 因爲X軸超邊界, 右上角單元格數值  == 左上角單元格數值
                v01 = v00;
                // 因爲X軸超邊界, 右下角單元格數值  == 左下角單元格數值
                v11 = v10;
            }
            // 如果需查詢的MAP值X座標和Y座標超過最小邊界
            else
            {
                // 四個單元格的值都等於左上角單元格數值
                v01 = v00;
                v10 = v00;
                v11 = v00;
            }

            // 獲取需查詢的Y點座標值在左上角與右上角單元格之間的差值
            v0 = Interpolate(v00, v01, x_offset, x_distance);
            // 獲取需查詢的Y點座標值在左下角與右下角單元格之間的差值
            v1 = Interpolate(v10, v11, x_offset, x_distance);
            //  獲取需查詢的X點座標值在 差值點v0,v1的之間的差值
            return result = Interpolate(v0, v1, y_offset, y_distance);
        }

5、上述函數的第一步是根據計算出的X,Y值座標索引值(x_index,y_index),可知當X=18,Y=850時,Z值務必在四個黃色單元格內:
分別對應函數的v00(左上1150),v01(左下1275),v10(右上1175),v11(右下1300)
在這裏插入圖片描述
6、選取四個單元格完成後,根據x_offset和x_distance之間的比值,計算出左上角與右上角之間的v0值,計算出左下角與右下角之間的v1值
插值公式:
在這裏插入圖片描述 在這裏插入圖片描述
配圖說明:
在這裏插入圖片描述

            // 獲取需查詢的Y點座標值在左上角與右上角單元格之間的差值
            v0 = Interpolate(1150, 1175, 3, 5)
            v0 =1165
            // 獲取需查詢的Y點座標值在左下角與右下角單元格之間的差值
            v1 = Interpolate(1275, 1300, 422.5, 427.25);
            v1 = 1290

7、使用y_offset,y_distance值在計算出來的v0,v1值之間在進行最後一次插值計算
在這裏插入圖片描述

//  獲取需查詢的X點座標值在 差值點v0,v1的之間的差值
result = Interpolate(v0, v1, y_offset, y_distance);
result = 1288.61

最終二維查表插值結果:

1288.61 = GetElementAt(18.00 , 850) 

工具下載地址(含插值算法源代碼):

百度網盤:提取碼:y3i1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章