matlab克里格插值(基於扇區鄰域點選取)

前言

此次博客是前面mink函數的博客的進階版本,往往我們在進行克里格插值時需要計算目標點周圍鄰域內多個點來進行插值操作,一般情況下鄰域內的點數並不是越多越好,有時要根據鄰域內點的分佈分佈狀況以及點的分佈個數來評估克里格插值的結果,但是有時鄰域的點對數量選取是基於距離最短的原則來選取,這樣就有時會造成鄰域點選取的結果分佈不均勻,爲了使插值更加精確,arcgis中已經封裝了設置領域點選擇的一些條件,如下圖所示,arcgis中還考慮了扇區的數目,每個扇區內點的數量限制,潘老師的理解是把扇區的數目就是把整個區域搜索的圓分成nn等份,如下圖會有更直觀的理解:

從上圖中定義的扇區大小爲4,則將其分爲4等分,每個扇區至少要有4個相鄰要素,最多8個,因此權重那裏最少是16個,那麼問題來了,怎樣在Matlab中編程將每個扇區內這樣的點對提取出來呢。

1方法原理

1.1座標系平移

對於座標點集(xi,yi)(x_i,y_i),取出要搜索的目標點(x0,y0)(x_0,y_0),剩餘點集爲(x0i,y0i)(x_{0i},y_{0i}),進行座標平移,如下,新座標系以(x0,y0)(x_0,y_0)爲原點,因此剩餘點集座標有:
x0i=x0ix0y0i=y0iy0 x_{0i}=x_{0i}-x_0\\ y_{0i}=y_{0i}-y_0
如下圖所示:
在這裏插入圖片描述

1.2方位角確定

方位角原本是在測繪中的一個定義,這裏我們求解的平移座標系之後的剩餘點集與原點連線與正北方向即(y)(y軸)的夾角α[0,2π]\alpha \in[0,2\pi],在直角座標系下有四個象限,具體如下圖所示

因此有計算方位角公式如下:
αI=π2arctan(yx),αIV=π2arctan(yx)\alpha_{I}=\frac{\pi}{2}-arctan(\frac{y}{x}) ,\alpha_{IV}=\frac{\pi}{2}-arctan(\frac{y}{x})
αIII=3π2arctan(yx),αII=3π2arctan(yx)\alpha_{III}=\frac{3\pi}{2}-arctan(\frac{y}{x}),\alpha_{II}=\frac{3\pi}{2}-arctan(\frac{y}{x})
因此有如下通項公式:
α=ππ2sign(x)arctan(yx)\alpha=\pi-\frac{\pi}{2}sign(x)-arctan(\frac{y}{x})
其中sign(x)sign(x)爲符號函數,表達式如下:
f(x)=sgn(x)={ ⁣ ⁣1,x>00,x=01,x<0 f(x)= sgn (x)=\left\{ \!\! \begin{array}{cl} 1, & x>0 \\ 0, & x=0 \\ -1, & x<0 \end{array} \right.

1.3鄰域點扇區確定

αi\alpha_{i}爲第ii個點的方位角,areaiarea_{i}爲其所屬扇區,nn爲扇區數目,因此第ii個扇區的角度範圍是[(i1)2πn,i2πn][(i-1)*\frac{2\pi}{n},i*\frac{2\pi}{n}]
因此有如下計算公式:
areai=ceil(α/(2π/n)) area_{i}=ceil({\alpha}/({2\pi/n}))

2案例實踐

2.1數據集

隨機產生100個[0,1]直接的隨機座標點,存儲與txt文檔中,

設置扇區數目nn
每個扇區對應最少要素數目numneighborminnum_{neighbormin}
每個扇區對應最多要素數目numneighbormaxnum_{neighbormax}

2.2座標系平移

xy=textread('C:\Users\asus\Desktop\3.txt');
xy0=xy(1,:);%這裏默認將第一個點選定目標點
xy1=xy(2:end,:);%目標點周圍的所有點
xy1=[xy1(:,1)-xy0(1),xy1(:,2)-xy0(2)];%平移座標系,使目標點爲原點
plot(xy1(:,1),xy1(:,2),'r.');%繪圖
xlabel('x');ylabel('y');
ax = gca;
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';%設置座標系爲原點處

最終效果如下圖:

2.3方位角計算與扇區確定

n=6;%扇區數目
num_neighbormin=4;%設置每個扇區內要搜索到的點的數量限制
num_neighbormax=8;%
%最少搜索4個,最多8個
%計算目標點周圍的點方位角
angle=pi-(pi/2).*sign(xy1(:,1))-atan(xy1(:,2)./xy1(:,1));%這裏返回的弧度值
xy_area=[xy1,ceil(angle./(2*pi/n))];%第1,2列爲對於的xy座標數據,
%第三列爲對應座標點對在哪個扇區

2.4針對每個扇區開始搜索

%開始逐個扇區搜索
I=cell(n,1);%定義一個扇區大小的元胞,存儲對應扇區的結果
for i=1:n
    logi=xy_area(:,3)==i;%第i個扇區內所有點
    xy_area_i=xy_area(logi,:);
    D2=(xy_area_i(:,1)).^2+(xy_area_i(:,2)).^2;
    num=size(xy_area_i,1);
    if num>num_neighbormax
        num_neighbor=num_neighbormax;
    elseif num>num_neighbormin
        num_neighbor=num;
    else
        I{i,1}=[];
        continue;
    end
    [D,tag]=mink(D2,num_neighbor);%tag表示最近的4個點D表示對應的距離平方
    Dc_neighbor=sqrt(D);%最近的num_neighbormax個點距離
    tag_neighbor=tag;%最近的num_neighbormax個點的索引
    I{i,1}=xy_area_i(tag_neighbor,:);
end

首先定義一個大小與扇區數目的元胞存儲每個扇區的結果點的座標,其次在各個扇區上搜索的鄰域點數目判斷,再基於前面博客所寫的mink函數的基礎知識上進行結果存儲
條件判斷如下:
1.如果搜索到的點數大於最大數的限制,那麼取前numneighborminnum_{neighbormin}個點作爲鄰域點
2.如果在其範圍之間,那麼就用搜索到的點數
3.如果搜索到的點數小於最小數的限制,那麼之間返回空值,進行下一個扇區的搜索

2.5結果展示

figure;%畫六個扇區的散點,不同顏色表示
for i=1:n
    plot(I{i,1}(:,1),I{i,1}(:,2),'*');
    hold on;
end
ax = gca;
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';
ux=-0.5:0.001:0.5;
uy1=ux./(tan(2*pi/n));
uy2=ux./(tan(2*2*pi/n));
hold on;
plot(ux,uy1);
hold on;
plot(ux,uy2);

效果如下:
在這裏插入圖片描述

3總結

本次matlab克里格插值(基於扇區鄰域點選取)的方法是基於Arcgis中的功能模塊來設置,最終將目標的點對篩選出來再次進行下一步操作才能進行克里格插值的計算,因此在考慮鄰域點的空間分佈的情況下來對其進行克里格插值是提高精度的一種方法,希望同學們能夠將簡單的算法原理進一步轉化成代碼能夠實現功能,走進算法世界,展現代碼力量!!

4參考文獻

[1]王紅芳,張保亮.座標方位角通用計算公式[J].山西建築,2008(06):361-362.

5附錄

xy=textread('C:\Users\asus\Desktop\3.txt');
xy0=xy(1,:);%這裏默認將第一個點選定目標點
xy1=xy(2:end,:);%目標點周圍的所有點
xy1=[xy1(:,1)-xy0(1),xy1(:,2)-xy0(2)];%平移座標系,使目標點爲原點
plot(xy1(:,1),xy1(:,2),'r.');%繪圖
xlabel('x');ylabel('y');
ax = gca;
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';
n=6;%扇區數目
num_neighbormin=4;%設置每個扇區內要搜索到的點的數量限制
num_neighbormax=8;%
%最少搜索兩個,最多4個
%計算目標點周圍的點方位角
angle=pi-(pi/2).*sign(xy1(:,1))-atan(xy1(:,2)./xy1(:,1));%這裏返回的使弧度值
xy_area=[xy1,ceil(angle./(2*pi/n))];%第1,2列爲對於的xy座標數據,
%第三列爲對應座標點對在哪個扇區
%開始逐個扇區搜索
I=cell(n,1);%定義一個扇區大小的元胞,存儲對應扇區的結果
for i=1:n
    logi=xy_area(:,3)==i;%第i個扇區內所有點
    xy_area_i=xy_area(logi,:);
    D2=(xy_area_i(:,1)-xy0(1)).^2+(xy_area_i(:,2)-xy0(2)).^2;
    num=size(xy_area_i,1);
    if num>num_neighbormax
        num_neighbor=num_neighbormax;
    elseif num>num_neighbormin
        num_neighbor=num;
    else
        I{i,1}=[];
        continue;
    end
    [D,tag]=mink(D2,num_neighbor);%tag表示最近的4個點D表示對應的距離平方
    Dc_neighbor=sqrt(D);%最近的num_neighbormax個點距離
    tag_neighbor=tag;%最近的num_neighbormax個點的索引
    I{i,1}=xy_area_i(tag_neighbor,:);
end
figure;
for i=1:n
    plot(I{i,1}(:,1),I{i,1}(:,2),'*');
    hold on;
end
ax = gca;
ax.XAxisLocation = 'origin';
ax.YAxisLocation = 'origin';
ux=-0.5:0.001:0.5;
uy1=ux./(tan(2*pi/n));
uy2=ux./(tan(2*2*pi/n));
hold on;
plot(ux,uy1);
hold on;
plot(ux,uy2);

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