3
\$\begingroup\$

I have an isometric map broken up into terrain tiles. the area of the map on-screen is given by a rectangle rotated 45 degrees (in red below).

Given the position of the corners of the visible rectangle, how would I go about iterating over all visible tiles (shaded), such that no tile down or to the right of tile A is iterated upon before tile A

Iso map

\$\endgroup\$
  • \$\begingroup\$ What is tile A? It is not indicated in your text or image. Also, why is your area rotated, but your tiles aren't? Then all you need to do is figure out the particular indexing used... which is pretty easy. \$\endgroup\$ – Engineer Sep 25 '17 at 8:02
  • \$\begingroup\$ Tile A is any arbitrary tile. no tile is iterated upon before the tile down or to the right of that tile. \$\endgroup\$ – BostonBrooks Sep 25 '17 at 8:15
  • \$\begingroup\$ I had a solution years ago but I've lost that code. \$\endgroup\$ – BostonBrooks Sep 25 '17 at 8:46
  • \$\begingroup\$ Look up "isometric". You would usually see the map tiles rotated and the visible area a usual up/down, left/right rectangle, but this is the same down to a change of basis. \$\endgroup\$ – BostonBrooks Sep 25 '17 at 9:03
  • \$\begingroup\$ Look up "isometric". You would usually see the map tiles rotated and the visible area a usual up/down, left/right rectangle, but this is the same down to a change of basis. \$\endgroup\$ – BostonBrooks Sep 25 '17 at 9:03
0
\$\begingroup\$

Assuming the top right side of that diamond is the top (row 0) of your array...

You're still walking top to bottom (+y) as in the unrotated array, but you are also stepping -1 in Y each time you step +1 in X. Where N is the width (and height) of your square grid:

for (int y = 0; y < N; y++)  //row in untransformed space
{
    for (int x = 0; x < N; x++) //col in untransformed space
    {
        yt = y - x;
        if (yt >= 0) //we haven't hit the right/top edge of the rotated map
        {
            ProcessTile(x, y);
        }
        else break; //exit the x loop and return to the y loop
    }
}

Next, we limit to the red rectangle. I do this by isometric row and column, min and max. You already have the row yt above, the column xt would be x + (N - y). Thus, those 3 darkened squares on the left of your diagram being [0,4], [1,5], [2,6] would be 0 + (8-4) - 1 = 3, 1 + (8-5) - 1 = 3, 2 + (8-6) - 1 = 3. So this is column 3 i.e. the 4th column as you count from the leftmost edge (first column is 0).

Then you just need to check whether you're within the min and max transformed row and column, and it will process only those cells outlined by the rect.

for (int y = 0; y < N; y++)  //row in untransformed space
{
    for (int x = 0; x < N; x++) //col in untransformed space
    {
        yt = y - x;
        xt = x + (N - y);
        if (yt >= 0) //we haven't hit the right/top edge of the rotated map
        {
            if (yt >= minRow && yt <= maxRow) //inclusive
            if (xt >= minCol && xt <= maxCol) //inclusive
                ProcessTile(x, y);
        }
        else break; //exit the x loop and return to the y loop
    }
}

P.S. It's left to you to get the minRow / maxRow / minCol / maxCol from screen corners.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Much appreciated, I feel a bit dumb for not working it out myself, \$\endgroup\$ – BostonBrooks Sep 26 '17 at 7:05
  • \$\begingroup\$ @BostonBrooks Glad it helped and that it was readable enough. \$\endgroup\$ – Engineer Sep 26 '17 at 7:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.