Here the code
/// <summary>
/// Voir https://en.wikipedia.org/wiki/Kernel_(statistics)
/// </summary>
/// <param name="arg_meshECEF"></param>
/// <param name="arg_tab_values">Values to be smoothed at mesh vertex</param>
/// <param name="arg_KernelSize">Size of kernel, same unit as mesh</param>
/// <param name="arg_logInterpolation">if true, arg_tab_values will be smoothed using thes log values</param>
/// <returns>array of smoothed datz</returns>
public static double[] FilterGaussianKDE(Mesh arg_meshECEF, double[] arg_tab_values, double arg_KernelSize, bool arg_logInterpolation)
{
if (arg_meshECEF.Vertices.Count != arg_tab_values.Length)
{
throw new Exception("Filtre KDE : Il n'y a pas le même nombre de points entre le maillage et les données sous forme tabulaire ");
}
double[] filteredData = new double[arg_meshECEF.Vertices.Count];
double n = (double)arg_meshECEF.Vertices.Count;
int i = 0;
foreach (Point3d ptECEF in arg_meshECEF.Vertices)
{
int j = 0;
double sumOfKernel = 0.0;
foreach (Point3d pt2ECEF in arg_meshECEF.Vertices)
{
double distSquared = pt2ECEF.DistanceToSquared(ptECEF);
double kernel = 0;
if (arg_KernelSize > 1e-6)
{
kernel = Math.Exp(-distSquared / (2 * arg_KernelSize * arg_KernelSize));//Kernel de type Gaussien
}
else
{
if (distSquared < 1e-6)
{
kernel = 1;
}
else
{
kernel = 0.0;
}
}
if (arg_logInterpolation)
{
filteredData[i] = filteredData[i] + Math.Log10(arg_tab_values[j]) * kernel;
}
else
{
filteredData[i] = filteredData[i] + arg_tab_values[j] * kernel;
}
sumOfKernel = sumOfKernel + kernel;
j++;
}
if (arg_logInterpolation)
{
filteredData[i] = Math.Pow(10, filteredData[i] / sumOfKernel);
}
else
{
filteredData[i] = filteredData[i] / sumOfKernel;
}
i++;
}
return filteredData;
}