基于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

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

*菜鸟工程师*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值