C# 在map/2d数组中查找最近的(几何)非零值

C# 在map/2d数组中查找最近的(几何)非零值,c#,algorithm,graph,multidimensional-array,complexity-theory,C#,Algorithm,Graph,Multidimensional Array,Complexity Theory,我有一个二维数组,表示图片中的选择性数据。所有不感兴趣的数据都设置为0。从两个索引中,我需要找到与索引(表示坐标)最接近的值(几何上),该值不是0 到目前为止,我的方法是在圆中检查以关注点为中心的值,在没有发现非零值的每个圆通过后增加半径 这种方法的复杂度似乎是指数级的,当最近点距离约25像素时,程序需要很长时间 您是否有其他方法/现有算法的建议来实现这一点 编辑:根据请求,我的当前代码如下: int height; int width; usho

我有一个二维数组,表示图片中的选择性数据。所有不感兴趣的数据都设置为0。从两个索引中,我需要找到与索引(表示坐标)最接近的值(几何上),该值不是0

到目前为止,我的方法是在圆中检查以关注点为中心的值,在没有发现非零值的每个圆通过后增加半径

这种方法的复杂度似乎是指数级的,当最近点距离约25像素时,程序需要很长时间

您是否有其他方法/现有算法的建议来实现这一点

编辑:根据请求,我的当前代码如下:

        int height;
        int width;
        ushort[,] _2dfat;

        private ushort getAssociatedFat(int centerX, int centerY) 
        {
            int radiusmax = (int)Math.Ceiling(Math.Sqrt(Math.Pow(height,2) + Math.Pow(width, 2) + 1));
            return getAssociatedFat(1, centerX, centerY,radiusmax); 
        }

        private ushort getAssociatedFat(int radius, int centerX, int centerY,int radiusmax) //RECURSIVE METHOD: requires extensive analysis and testing
        {

            ushort max=circleSym8(centerX, centerY, radius);
            if (max != 0) return max;
            else if (radius <= radiusmax)
                return getAssociatedFat(radius + 1, centerX, centerY, radiusmax);
            else 
            { 
                MessageBox.Show("WARNING: empty fat array/image"); 
                return 0; 
            }
        }

        private ushort getMax(ushort max, int x, int y)
        {
            try
            {
                if (_2dfat[y, x] == 0) return max;
                else if (_2dfat[y, x] > max) return _2dfat[y, x];
                else return max;
            }
            catch (IndexOutOfRangeException) { return max; }


        }

        private ushort circleSym8(int xCenter, int yCenter, int radius)
        {
            int x, y, r2;
            r2 = radius * radius;
            ushort max=0;
            max=getMax(max, xCenter, yCenter + radius);
            max = getMax(max, xCenter, yCenter - radius);
            max = getMax(max, xCenter + radius, yCenter);
            max = getMax(max, xCenter - radius, yCenter);

            y = radius;
            x = 1;
            y = (int)(Math.Sqrt(r2 - 1) + 0.5);
            while (x < y)
            {
                max = getMax(max, xCenter + x, yCenter + y);
                max = getMax(max, xCenter + x, yCenter - y);
                max = getMax(max, xCenter - x, yCenter + y);
                max = getMax(max, xCenter - x, yCenter - y);
                max = getMax(max, xCenter + y, yCenter + x);
                max = getMax(max, xCenter + y, yCenter - x);
                max = getMax(max, xCenter - y, yCenter + x);
                max = getMax(max, xCenter - y, yCenter - x);
                x += 1;
                y = (int)(Math.Sqrt(r2 - x * x) + 0.5);
            }
            if (x == y)
            {
                max = getMax(max, xCenter + x, yCenter + y);
                max = getMax(max, xCenter + x, yCenter - y);
                max = getMax(max, xCenter - x, yCenter + y);
                max = getMax(max, xCenter - x, yCenter - y);
            }
            return max;
        }
int高度;
整数宽度;
ushort[,]2dfat;
专用ushort getAssociatedFat(int centerX、int centerY)
{
intradiusmax=(int)数学天花板(Math.Sqrt(Math.Pow(高度,2)+数学.Pow(宽度,2)+1));
返回getAssociatedFat(1、centerX、centerY、radiusmax);
}
私有ushort getAssociatedFat(int-radius、int-centerX、int-centerY、int-radiusmax)//递归方法:需要大量的分析和测试
{
ushort max=圆形ym8(中心x、中心y、半径);
如果(max!=0)返回max;
如果(最大半径)返回_2dfat[y,x];
否则返回最大值;
}
catch(IndexOutOfRangeException){return max;}
}
专用ushort圆圈SYM8(int xCenter、int Y center、int radius)
{
int x,y,r2;
r2=半径*半径;
ushort max=0;
max=getMax(max,xCenter,yCenter+radius);
max=getMax(max,x中心,y中心-半径);
max=getMax(max,xCenter+radius,yCenter);
max=getMax(max,x中心-半径,y中心);
y=半径;
x=1;
y=(int)(数学Sqrt(r2-1)+0.5);
while(x
您可以将感兴趣的数据存储为或中的点,并以这种方式执行范围搜索。这些数据结构针对您正在执行的查找类型进行了优化,并将降低每次搜索的复杂性

我设想一个足够的四叉树实现,提供以下内容:

// Given some point in the quadtree, walk upwards and outwards
// returning points found ordered by distance
var nearestNeighbor = quadTree.Neighbors(point)
                              .OrderBy(pp => point.Distance(pp))
                              .First();

您可以将感兴趣的数据存储为或中的点,并以这种方式执行范围搜索。这些数据结构针对您正在执行的查找类型进行了优化,并将降低每次搜索的复杂性

我设想一个足够的四叉树实现,提供以下内容:

// Given some point in the quadtree, walk upwards and outwards
// returning points found ordered by distance
var nearestNeighbor = quadTree.Neighbors(point)
                              .OrderBy(pp => point.Distance(pp))
                              .First();

你将要发布一些代码你将要发布一些代码我今天刚刚学习了两个新的数据结构!非常酷,听起来非常适用于上述问题。嗯,有趣的是,我所有的工作都基于两个2d阵列。您知道有任何现有的四叉树实现可以使用2d数组吗?您可以使用2d数组将点插入到四叉树中
Enumerable.Range(0,array.GetLength(0))。SelectMany(x=>Enumerable.Range(0,array.GetLength(1))。其中(y=>array[x,y]>0)。Select(y=>newpoint(x,y))
。更好的是,只需在数组上进行两个for循环,将数据插入四叉树。今天我刚刚学习了两种新的数据结构!非常酷,听起来非常适用于上述问题。嗯,有趣的是,我所有的工作都基于两个2d阵列。您知道有任何现有的四叉树实现可以使用2d数组吗?您可以使用2d数组将点插入到四叉树中
Enumerable.Range(0,array.GetLength(0))。SelectMany(x=>Enumerable.Range(0,array.GetLength(1))。其中(y=>array[x,y]>0)。Select(y=>newpoint(x,y))
。更好的是,只需在数组上进行两个for循环,将数据插入四叉树。