如何获取从固定点到特定距离的坐标邻居

Posted

技术标签:

【中文标题】如何获取从固定点到特定距离的坐标邻居【英文标题】:How to get coordinate neighbors from a fixed point to a specific distance 【发布时间】:2021-11-10 19:52:43 【问题描述】:

我的任务是实现 GetNeighbors 方法,该方法从一组点返回仅与具有整数坐标 x 和 y 的点的 h 邻居的点。 (阅读代码中的摘要以获得更多理解)

其实我和Find k nearest neighbor in C#这个人有同样的任务,但是那里的答案似乎不起作用。而且我想只用我猜应该期望的循环来做这件事:)>。

到目前为止我的代码:

        /// <summary>
        /// Gets from a set of points only points that are h-neighbors for a point with integer coordinates x and y.
        /// </summary>
        /// <param name="point">Given point with integer coordinates x and y.</param>
        /// <param name="h">Distance around a given point.</param>
        /// <param name="points">A given set of points.</param>
        /// <returns>Only points that are h-neighbors for a point with integer coordinates x and y.</returns>
        /// <exception cref="ArgumentNullException">Throw when array points is null.</exception>
        /// <exception cref="ArgumentException">Throw when h-distance is less or equals zero.</exception>
        public static Point[] GetNeighbors(Point point, int h, params Point[] points)
        
            if (points is null)
            
                throw new ArgumentNullException(nameof(points));
            

            if (h <= 0)
            
                throw new ArgumentException(null);
            

            List<Point> neighbors = new List<Point>();

            int left = point.X - h;
            int right = point.X + h;
            int bottom = point.Y - h;
            int top = point.Y + h;


            for (int y = top; y <= bottom; y++)
            
                for (int x = left; x <= right; x++)
                
                    // Yeah...
                
            

            return neighbors.ToArray();
        

所以到目前为止我所做的是在附近找到顶部、底部、左侧和右侧边界。我认为我只需要做一个 if 语句,它可以比较我拥有的点和来自点数组的点。嗯,怎么做,我对使用structs不是很熟悉,每次都是失败的。

这就是 struct Point 的构建方式:

/// <summary>
    /// Represents a point on the coordinate plane.
    /// </summary>
    public readonly struct Point : System.IEquatable<Point>
    
        public Point(int x, int y)
        
            this.X = x;
            this.Y = y;
        

        public int X  get; 

        public int Y  get; 
        
        public static bool operator ==(Point left, Point right)
        
            return left.Equals(right);
        
        
        public static bool operator !=(Point left, Point right)
        
            return !(left == right);
        
        
        public override int GetHashCode()
        
            return this.X.GetHashCode() ^ this.Y.GetHashCode();
        
        
        public override bool Equals(object obj)
        
            if (obj is null)
            
                return false;
            

            if (!(obj is Point))
            
                return false;
            

            if (obj.GetType() != this.GetType())
            
                return false;
            

            Point point = (Point)obj;
            
            return this.Equals(point);
        

        public bool Equals(Point other)
        
            return this.X == other.X && this.Y == other.Y;
        
    

【问题讨论】:

什么是 h 邻居?您是否需要 h 最近的邻居(按欧几里得距离)或边长为 2h 的正方形内的邻居或最大欧几里得距离为 h 的点或其他点? 它是h距离内的邻居,它是方形的(图片发布)他们是紫色标记的。 【参考方案1】:

您不能在坐标上循环,而是在点上循环。这是使用 LINQ 的解决方案:

public static Point[] GetNeighbors(Point point, int h, params Point[] points)

    int minX = point.X - h;
    int maxX = point.X + h;
    int minY = point.Y - h;
    int maxY = point.Y + h;
    return points
        .Where(p => p.X >= minX && p.X <= maxX && p.Y >= minY && p.Y <= maxY)
        .ToArray();

使用 C# 9.0,您可以简化与模式匹配的比较

        .Where(p => p.X is >=minX and <=maxX && p.Y is >=minY and <=maxY)

这是一个使用显式循环的解决方案。由于我们不知道结果数组的大小,我将结果存储在一个列表中:

    ...
    var list = new List<Point>();
    foreach (Point p in points) 
        if (p.X is >=minX and <=maxX && p.Y is >=minY and <=maxY) 
            list.Add(p);
        
    
    return list.ToArray();

或者您可以返回一个列表。


另一种解决方案是使用iterator method:

public static IEnumerable<Point> GetNeighbors(Point point, int h, params Point[] points)

    int minX = point.X - h;
    int maxX = point.X + h;
    int minY = point.Y - h;
    int maxY = point.Y + h;
    foreach (Point p in points) 
        if (p.X is >=minX and <=maxX && p.Y is >=minY and <=maxY) 
            yield return p;
        
    

请注意,这种方法不会将点存储在集合中,而是在循环结果时执行方法内部的循环(显式在 foreach 循环中或通过应用 .ToArray().Count() 等隐式执行.).

Point[] result = GetNeighbors(center, 2, p1, p2, p3, p4).ToArray();

【讨论】:

它确实测试了绿色,哇。现在我认为您需要遍历这些点并比较循环内的点坐标。让我对这个解决方案感到惊讶,谢谢:)

以上是关于如何获取从固定点到特定距离的坐标邻居的主要内容,如果未能解决你的问题,请参考以下文章

如何从距离、方位角和仰角获取 3D 坐标

获取二维数组中邻居的坐标

如何从地理坐标向任何方向移动 x 距离?

如何从python中的图像中获取特定像素(蓝色)的x,y坐标?

如何应用地理位置坐标从 googlemaps 获取到特定地点的路线?

CoreLocation 从坐标获取一定距离和方向的经纬度