Elgoog
Elgoog

Reputation: 2275

Working out positions with array indexes

I have an array that represents a grid grid

For the sake of this example we will start the array at 1 rather that 0 because I realized after doing the picture, and can't be bothered to edit it

In this example blue would have an index of 5, green an index of 23 and red 38

Each color represents an object and the array index represents where the object is. I have implemented very simple gravity, whereby if the grid underneath is empty x + (WIDTH * (y + 1)) then the grid below is occupied by this object, and the grid that the object was in becomes empty.

This all works well in its current form, but what I want to do is make it so that red is the gravity point, so that in this example, blue will move to array index 16 and then 27.

This is not too bad, but how would the object be able to work out dynamically where to move, as in the example of the green grid? How can I get it to move to the correct index?

Also, what would be the best way to iterate through the array to 'find' the location of red? I should also note that red won't always be at 38

Any questions please ask, also thank you for your help.

Upvotes: 3

Views: 2826

Answers (3)

William the Coderer
William the Coderer

Reputation: 708

x = x position
y = y position
cols = number of columns across in your grid

(y * cols) + x = index in array absolute value for any x, y

you could generalize this in a function:

int get_index(int x, int y, int gridcols)
{
    return (gridcols * y) + x;
}

It should be noted that this works for ZERO BASED INDICES. This is assuming I am understanding what you're talking about at all...

As for the second question, for any colored element you have, you should keep a value in memory (possibly stored in a structure) that keeps track of its position so you don't have to search for it at all.

struct _THING {
   int xpos;
   int ypos;
};

Using the get_index() function, you could find the index of the grid cell below it by calling like this:

index_below = get_index(thing.x, thing.y + 1, gridcols);
thing.y++; // increment the thing's y now since it has moved down

simple...

IF YOU WANT TO DO IT IN REVERSE, as in finding the x,y position by the array index, you can use the modulus operator and division.

ypos = array_index / total_cols; // division without remainder
xpos = array_index % total_cols; // gives the remainder

You could generalize this in a function like this:

// x and y parameters are references, and return values using these references

void get_positions_from_index(int array_index, int total_columns, int& x, int& y)
{
    y = array_index / total_columns;
    x = array_index % total_columns;
}

Whenever you're referring to an array index, it must be zero-based. However, when you are referring to the number of columns, that value will be 1-based for the calculations. x and y positions will also be zero based.

Upvotes: 3

sarnold
sarnold

Reputation: 104080

Probably easiest would be to work entirely in a system of (x,y) coordinates to calculate gravity and switch to the array coordinates when you finally need to lookup and store objects.

In your example, consider (2, 4) (red) to be the center of gravity; (5, 1) (blue) needs to move in the direction (2-5, 4-1) == (-3, 3) by the distance _n_. You get decide how simple you want n to be -- it could be that you move your objects to an adjoining element, including diagonals, so move (blue) to (5-1, 1+1) == (4, 2). Or perhaps you could move objects by some scalar multiple of the unit vector that describes the direction you need to move. (Say, heavier objects move further because the attraction of gravity is stronger. Or, lighter objects move further because they have less inertia to overcome. Or objects move further the closer they are to the gravity well, because gravity is an inverse square law).

Once you've sorted out the virtual coordinates of your universe, then convert your numbers (4, 2) via some simple linear formulas: 4*columns + 2 -- or just use multidimensional arrays and truncate your floating-point results to get your array indexes.

Upvotes: 1

Christian Rau
Christian Rau

Reputation: 45948

This sounds very similar to line rasterization. Just imagine the grid to be a grid of pixels. Now when you draw a line from the green point to the red point, the pixels/cells that the line will pass are the cells that the green point should travel along, which should indeed be the shortest path from the green point to the red point along the discrete grid cells. You then just stop once you encounter a non-empty grid cell.

Look for Bresenham's algorithm as THE school book algorithm for line rasterization.

And for searching the red point, just iterate over the array linearly until you have it and then keep track of its grid position, like William already suggested in his answer.

Upvotes: 4

Related Questions