The math behind Inverse Distance Weighting

There’s nothing to be afraid of with IDW math. Remember that the search distance or the number of closest points determines how many points will be used.

We use the 3 closest points in this example:

Here’s what the table looks like for these 3 distances and values:

| Distance | Value |
| 350m | 12 |
| 750m | 10 |
| 850m | 10 |

For a power of 1, that cell value is equal to:
((12/350) + (10/750) + (10/850)) / ((1/350) + (1/750) + (1/850)) = 11.1

For a power of 2, that cell value is equal to:
= ((12/3502) + (10/7502) + (10/8502)) / ((1/3502) + (1/7502) + (1/8502)) = 11.4

…And here’s the formula:

idw formula

The sigma notation simply means that you are adding whatever number of points that will be interpolated. Here we are simply summing the elevation values at each point for distance.

A smaller number in the denominator (more distance) has less effect on the interpolated (xp) value. You’re also never going to have values above or below your maximum and minimum known values… So you better hope you have your highest or lowest points in your sample points!

Try plugging in different values. The math really isn’t so bad!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    public class PointXYZ
    {
        public double X;
        public double Y;
        public double Z;

        public double d;
    }

    public class Interpolation
    {
        /// <summary>
        /// 插值算法 反距离加权法IDW 
        /// </summary>  
        /// <param name="input">离散点的XYZ</param>
        /// <param name="outpoint">插入点的XY</param> 
        /// <returns></returns>
        public bool InverseDistanceWeighted(List<PointXYZ> input, PointXYZ outpoint)
        {
            try
            {
                double r = 0.0;    //距离的倒数和             
                double ri = 0.0;    //i点的权重
                foreach (PointXYZ inputpoint in input)
                {
                    inputpoint.d = Math.Sqrt(Math.Pow(inputpoint.X - outpoint.X, 2) + Math.Pow(inputpoint.Y - outpoint.Y, 2));

                    inputpoint.d = Math.Pow(inputpoint.d, 2);

                    r += 1.0 / inputpoint.d;
                    //ipqchase  这里可以加条件过滤一部分,0.0001,生成集合下步使用
                }
                //= ((12/3502) + (10/7502) + (10/8502)) / ((1/3502) + (1/7502) + (1/8502)) = 11.4
                outpoint.Z = 0.0;
                foreach (PointXYZ inputpoint in input)
                { 
                    ri = 1.0 / inputpoint.d / r; 
                    outpoint.Z += ri * inputpoint.Z;//所有离散点的权重*高程 和,就是该点的idw插值高程   
                }

                return true;
            }
            catch
            {
                return true;
            }
        }

    }
}



// See https://aka.ms/new-console-template for more information
using ConsoleApp2;

Console.WriteLine("Hello, World!"); 

Interpolation p = new Interpolation();

var pt2 = new PointXYZ() { X = 110.0, Y = 150, Z = 0 };
var pt3 = new PointXYZ() { X = 70, Y = 140, Z = 115.4 };
var pt4 = new PointXYZ() { X = 115, Y = 115, Z = 123.1 };
var pt5 = new PointXYZ() { X = 150, Y = 150, Z = 113.8 };
var pt6 = new PointXYZ() { X = 110, Y = 170, Z = 110.5 };
var pt7 = new PointXYZ() { X = 90, Y = 190, Z = 107.2 };
var pt8 = new PointXYZ() { X = 180, Y = 210, Z = 131.78 };

var lst=new List<PointXYZ>();
lst.Add(pt3);
lst.Add(pt4);
lst.Add(pt5);
lst.Add(pt6);
lst.Add(pt7);
lst.Add(pt8);

p.InverseDistanceWeighted(lst, pt2);

Console.WriteLine(pt2.Z);
Console.ReadKey();
 

x y z
110 150 0
70 140 115.4
115 115 123.1
150 150 113.8
110 170 110.5
90 190 107.2
180 210 131.78

image.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容