# Converting a 2D table index into a 1D table index?

Table. Array. Same difference. :P

I'm having a total brain fart on the math for converting an (x,y) index into a single (x) index.

The units of measure are arbitrary. They can be as small as a pixel to as big as a house...

Given:

• A source grid of 20x10 tiles labeled 0 through 199 starting at the upper left at size 32x32 for each tile.
• A destination grid of 20x1500 tiles starting at zero with the same size tiles and orientation.
• A series of numbers indicating an index from the source grid; i.e 3, 3, 3, 48, 47, 158; where each index's location (zero-based) in the list is the destination tile placement.

Problem:

Using the series of numbers from first to last, place each source tile in its proper location on the destination grid.

For those of you that know C++ here's my attempt:

A representative sample of the MAP definition to follow because it's massive.

//blit Signature
void blit(BITMAP* source, BITMAP* destination, int source_x, int source_y, int dest_x, int dest_y, int width, int height);

for(int map_pos = 0; (map_pos < L1TW * L1TH); ++map_pos) {
blit(tiles->GetImage(), background->GetImage(), ((MAP[map_pos] % 20) - 1) * L1FW, ((MAP[map_pos] / 10) - 1) * L1FH, (map_pos % L1TH) * L1FH, (map_pos / L1TW) * L1FW, L1FW, L1FH);
}

 

#define L1TW 20
#define L1TH 1500
#define L1FW 32
#define L1FH 32
#define L1PW (L1TW * L1FW)
#define L1PH (L1TH * L1FH)
#define L1A (L1TW * L1TH)
const int MAP[] = {
3, 3, 3, 3, 3, 3, 3, 3, 48, 1, 57, 1, 47, 3, 3, 3,
3, 3, 3, 3,
23, 23, 23, 23, 23, 23, 23, 23, 10, 1, 57, 1, 49, 23, 23, 23,
23, 23, 23, 23,
158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
158, 158, 158, 158,
166, 158, 158, 166, 158, 166, 166, 158, 158, 158, 158, 158, 158, 158, 158, 158,
158, 158, 166, 158,
158, 158, 158, 158,
158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
158, 158, 158, 158,
158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
158, 158, 158, 158,
158, 158, 158, 158, 158, 166, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
166, 158, 158, 158,
158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
158, 158, 158, 158,
158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
158, 158, 158, 158,
22, 22, 22, 22, 22, 22, 22, 50, 1, 57, 1, 30, 22, 22, 22, 22,
22, 22, 22, 22,
3, 3, 3, 3, 3, 3, 3, 48, 1, 57, 1, 47, 3, 3, 3, 3,
3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 48, 1, 57, 1, 47, 3, 3, 3, 3,
3, 3, 3, 3,
3, 99, 99, 99, 99, 99, 3, 48, 1, 57, 1, 47, 3, 3, 3, 3,
3, 94, 94, 94,
3, 99, 127, 99, 127, 99, 3, 48, 1, 57, 1, 47, 3, 3, 3, 3,
3, 94, 95, 94,
3, 99, 127, 127, 127, 99, 3, 48, 1, 57, 1, 47, 3, 3, 3, 3,
3, 94, 94, 94,
3, 99, 127, 99, 127, 99, 3, 48, 1, 57, 1, 47, 3, 3, 3, 3,
3, 3, 3, 3,
3, 99, 99, 99, 99, 99, 3, 48, 1, 57, 1, 47, 3, 3, 3, 3,
3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 48, 1, 57, 1, 47, 3, 3, 3, 3,
3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 48, 1, 57, 1, 47, 3, 3, 3, 3,
3, 3, 3, 3
};

 

EDIT

Here's the corrected math:

for(int map_pos = 0; (map_pos < L1TW * L1TH); ++map_pos) {
blit(tiles->GetImage(), background->GetImage(), (MAP[map_pos] % L1TW) * L1FW, (MAP[map_pos] / L1TW) * L1FH, (map_pos % L1TW) * L1FW, (map_pos / L1TW) * L1FH, L1FW, L1FH);
}

-

I don't quite understand your source and target grids and so forth, but I can answer your previous question about

the math for converting an (x,y) index into a single (x) index.

Let's say you have a $M\times N = 5\times4$ array. That is, you have $5$ rows of $4$ elements each. You would address them as $(x,y)$, where $1 \le x \le 5$ and $1 \le y \le 4$.

The first element in the first row is offset from the beginning of the array by $0$. That is, start counting at $0$, and you'll find that the first element in the first row is element number $0$, the second element in the first row is $1$, ... the last element in the first row is $3$, and the first element in the second row is $4$.

In other words, the first element in the second row is $4$ elements more than the first element in the first row.

To convert that to math, you have that:

row $1$'s elements are numbered $0\ldots3$

row $2$'s elements are numbered $4\ldots7$

$\vdots$

row $m$'s elements are numbered $(m-1)N, (m-1)N+1, \ldots, (m-1)N+(N-1)$.

Put another way, the element in position $(x,y)$ is element numbered $$(x-1)N+(y-1),$$ where $N$ is the number of columns. And that is the answer I think you are looking for.

-
Thanks for the second pair of eyes. See edit for corrected math. – Casey Jan 8 '12 at 4:48