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;    //距離的倒數(shù)和             
                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
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容