Search code examples
algorithm2dmultidimensional-arraycoordinate-systems

Algorithm for finding nearest object on 2D grid


Say you have a 2D grid with each spot on the grid having x number of objects (with x >=0). I am having trouble thinking of a clean algorithm so that when a user specifies a coordinate, the algorithm finds the closest coordinate (including the one specified) with an object on it.

For simplicity's sake, we'll assume that if 2 coordinates are the same distance away the first one will be returned (or if your algorithm doesn't work this way then the last one, doesn't matter).

Edit: A coordinate that is 1 away must be either 1 up, down, left or right. Coordinates that are away diagonally are 2.

As a side note, what is a great, free, online reference for algorithms?


Solution

  • Update

    With new information:

    Assuming that a coordinate diagonally is 2 away

    This algorithm would work. The algorithm searches outwards in a spiral kinda way testing each point in each 'ring' started from the inside.

    Note that it does not handle out of bounds situations. So you should change this to fit your needs.

    int xs, ys; // Start coordinates
    
    // Check point (xs, ys)
    
    for (int d = 1; d<maxDistance; d++)
    {
        for (int i = 0; i < d + 1; i++)
        {
            int x1 = xs - d + i;
            int y1 = ys - i;
    
            // Check point (x1, y1)
    
            int x2 = xs + d - i;
            int y2 = ys + i;
    
            // Check point (x2, y2)
        }
    
    
        for (int i = 1; i < d; i++)
        {
            int x1 = xs - i;
            int y1 = ys + d - i;
    
            // Check point (x1, y1)
    
            int x2 = xs + i;
            int y2 = ys - d + i;
    
            // Check point (x2, y2)
        }
    }
    

    Old version

    Assuming that in your 2D grid the distance between (0, 0) and (1, 0) is the same as (0, 0) and (1, 1). This algorithm would work. The algorithm searches outwards in a spiral kinda way testing each point in each 'ring' started from the inside.

    Note that it does not handle out of bounds situations. So you should change this to fit your needs.

    int xs, ys; // Start coordinates
    
    if (CheckPoint(xs, ys) == true)
    {
        return (xs, ys);
    }
    
    for (int d = 0; d<maxDistance; d++)
    {
        for (int x = xs-d; x < xs+d+1; x++)
        {
            // Point to check: (x, ys - d) and (x, ys + d) 
            if (CheckPoint(x, ys - d) == true)
            {
                return (x, ys - d);
            }
    
            if (CheckPoint(x, ys + d) == true)
            {
                return (x, ys - d);
            }
        }
    
        for (int y = ys-d+1; y < ys+d; y++)
        {
            // Point to check = (xs - d, y) and (xs + d, y) 
            if (CheckPoint(x, ys - d) == true)
            {
                return (xs - d, y);
            }
    
            if (CheckPoint(x, ys + d) == true)
            {
                return (xs - d, y);
            }
        }
    }