C#,码海拾贝(12)——拉格朗日(Lagrange)曲面插值算法,《C#数值计算算法编程》源代码升级改进版

曲面插值

在空间数据中, 具有不均匀位置分布的数据被称为离散数据, 在平面二维地理空间的定位中, 离散数据的坐标由不规则分布的离散样本的平面坐标实现。高程和属性值通常用作第三维数据。曲面插值则是一种通过这些离散的空间数据计算未知空间数据的方法. 它是基于“地理学第一定律”的基本假设: 空间位置上越靠近的点, 具有相似特征值的可能性越大, 而距离远的点, 其具有相似特征值的可能性越小。它通常用于将离散点的测量数据转换为连续数据表面, 以便于比较其他空间现象的分布情况.

In spatial data, data with uneven position distribution is referred to as discrete data. In the positioning of planar two-dimensional geographic space, the coordinates of discrete data are achieved by the plane coordinates of irregularly distributed discrete samples. Elevations and attribute values are typically used as three-dimensional data. Surface interpolation is a method of calculating unknown spatial data through these discrete spatial data It is based on the basic assumption of the "First Law of Geography": the closer a point is in spatial position, the greater the likelihood of having similar eigenvalues, while the farther away a point is, the less likely it is to have similar eigenvalues. It is usually used to convert measurement data from discrete points into continuous data surfaces for comparing the distribution of other spatial phenomena

曲面插值分析算法的分类方式有多种: 按插值的区域范围分类, 可以分为整体插值、局部插值、边界内插法等; 整体插值是用研究区的所有采样点进行全区特征拟合, 在整体插值方法中, 整个区域的数值会影响单个插值点的数值, 同样单个采样点的数值的增加、减少或删除对整个区域的特征拟合都有影响, 代表性插值方法具有趋势面分析插值方法等。

There are various classification methods for surface interpolation analysis algorithms: based on the range of interpolation regions, they can be divided into global interpolation, local interpolation, boundary interpolation, etc; Global interpolation is the process of fitting the entire region's features using all sampling points in the research area. In the global interpolation method, the values of the entire region will affect the values of a single interpolation point. Similarly, the increase, decrease, or deletion of the values of a single sampling point will have an impact on the feature fitting of the entire region. Representative interpolation methods include trend surface analysis interpolation methods.

using System;
using System.Drawing;
using System.Collections;
using System.Collections.Generic;

namespace Zhou.CSharp.Algorithm
{
    /// 
    /// 插值计算类Interpolation.cs
    /// 作者:周长发
    /// 改编:深度混淆
    /// https://blog.csdn.net/beijinghorn
    /// 
    public static partial class Interpolation
    {
        /// 
        /// 二维全区间插值
        /// 
        /// 一维数组,长度为n,存放给定n x m 个结点x方向上的n个值x(i)
        /// 一维数组,长度为m,存放给定n x m 个结点y方向上的m个值y(i)
        /// 一维数组,长度为n x m,存放给定的n x m个结点的函数值z(i,j),z(i,j) = f(x(i), y(j)), i=0,1,...,n-1, j=0,1,...,m-1
        /// 存放插值点x坐标
        /// 存放插值点y坐标
        /// 指定函数值f(u, v)
        public static double Lagrange_2D(double[] x, double[] y, double[] z, double u, double v)
        {
            // x方向上给定结点的点数
            int n = x.Length;
            // y方向上给定结点的点数
            int m = y.Length;

            // 特例
            int ip, ipp;
            if (u <= x[0])
            {
                ip = 1;
                ipp = 4;
            }
            else if (u >= x[n - 1])
            {
                ip = n - 3;
                ipp = n;
            }
            else
            {
                int i = 1;
                int j = n;
                while (((i - j) != 1) && ((i - j) != -1))
                {
                    int w = (i + j) / 2;
                    if (u < x[w - 1])
                    {
                        j = w;
                    }
                    else
                    {
                        i = w;
                    }
                }
                ip = i - 3;
                ipp = i + 4;
            }

            if (ip < 1)
            {
                ip = 1;
            }
            if (ipp > n)
            {
                ipp = n;
            }

            int iq, iqq;
            if (v <= y[0])
            {
                iq = 1;
                iqq = 4;
            }
            else if (v >= y[m - 1])
            {
                iq = m - 3;
                iqq = m;
            }
            else
            {
                int i = 1;
                int j = m;
                while (((i - j) != 1) && ((i - j) != -1))
                {
                    int l = (i + j) / 2;
                    if (v < y[l - 1])
                    {
                        j = l;
                    }
                    else
                    {
                        i = l;
                    }
                }
                iq = i - 3;
                iqq = i + 4;
            }

            if (iq < 1)
            {
                iq = 1;
            }
            if (iqq > m)
            {
                iqq = m;
            }

            double[] b = new double[10];
            for (int i = ip - 1; i <= ipp - 1; i++)
            {
                b[i - ip + 1] = 0.0;
                for (int j = iq - 1; j <= iqq - 1; j++)
                {
                    double h = z[m * i + j];
                    for (int k = iq - 1; k <= iqq - 1; k++)
                    {
                        if (k != j)
                        {
                            h = h * (v - y[k]) / (y[j] - y[k]);
                        }
                    }
                    b[i - ip + 1] = b[i - ip + 1] + h;
                }
            }

            double zv = 0.0;
            for (int i = ip - 1; i <= ipp - 1; i++)
            {
                double h = b[i - ip + 1];
                for (int j = ip - 1; j <= ipp - 1; j++)
                {
                    if (j != i)
                    {
                        h = h * (u - x[j]) / (x[i] - x[j]);
                    }
                }
                zv = zv + h;
            }

            return (zv);
        }
    }
}

POWER BY 315SOFT.COM

基于坐标点的计算,从点集计算插值曲线等拓展方法请参阅《拉格朗日插值算法及其拓展》

参考:

拉格朗日曲线插值

任何类型的曲线都可以通过其控制点的线性组合来表示。

例如,当k=2,m0=m1=m2=1时,已知函数f(t)在三个点t0、t1和t2的函数值f(t0)、f(t1)和f(t2),则二次多项式P(t)为

P(t)=f(t0)g0(t) + f(t1)g1(t) + f(t2)g2(t)

式中,混合函数如下:

g0(t)=[(t-t1)(t-t2)] / [(t0-t1)(t0-t2)]

g1(t)=[(t-t0)(t-t2)] / [(t1-t0)(t1-t2)]

g2(t)=[(t-t0)(t-t1)] / [(t2-t0)(t2-t1)]

 

你可能感兴趣的:(C#数值计算,Numerical,Recipes,C#入门教程,Beginner‘s,Recipes,算法,数据结构,C#,曲面插值)