3

I can't figure out the math. I have a staggered 2d isometric grid, got no problem into converting the grid cells into world coordinates, but now I can't figure out how to reverse the process.

Here is the CellToCoord method:

public static Vector2 CellToCoord(int x, int y) {
    return new Vector2() {
        x = x + ((y % 2) * 0.5f),
        y = y * -0.25f
    };
}

Pretty simple and display the grid exactly like i wanted it to be, I would like to get the tile from world coordinates now.

Edit:
Image, the world coordinates i get from the CellToCoord() method give me a world position which represent the center of the cell.

reonZ
  • 135
  • 2
  • 10

1 Answers1

0
public static Point CoordToCell(Vector2 coord) {
    // Divide the cell coordinate the value again (or multiply by -4)
    // Then Math.Round() to eliminate any floating point inaccuracies
    var cellY = (int)Math.Round(coord.y / -0.25f);

    // Armed with the original Integer Y, we can undo the mutation of X (again, accounting for floating point inaccuracies)
    var cellX = (int)Math.Round(coord.x - ((cellY % 2) * 0.5f));

    return new Point() {
        x = cellX,
        y = cellY
    };
}

This should reverse the process. I've used Point as a generic container for an integer X and Y coordinate, you can replace this as appropriate.

The biggest issue in my opinion is that the X mutation was originally based on the integer value of Y, from which you then stored a floating point value. I couldn't find a way to reverse this without the Math.Round()s to coerce the floating point results back into integer values reliably.

Update Calculating the cell coordinates containing a given world coordinate:

Looking at how your world coordinates are arranged, we can see that the centres of each cell are on the diagonal lines given by:

  • y = ( x - i ) / 2 ... or ... x - 2y = i
  • y = ( j - x ) / 2 ... or ... x + 2y = j

where i and j are integers. This diagram shows this for the x - 2y = i diagonals.

Diagram showing diagonal coordinates

Using these, we can take the world coordinates of a given point, work out i and j, then round them to the nearest integer to get the centre of the cell as i and j.

We can then use i and j to work out the x and y of the cell centre, and use the function I posted before to convert these back into cell coordinates.

public static Point CoordToCell(Vector2 coord)
{
    // Work out the diagonal i and j coordinates of the point.
    // i and j are in a diagonal coordinate system that allows us
    // to round them to get the centre of the cell.
    var i = Math.Round( coord.x - coord.y * 2 );
    var j = Math.Round( coord.x + coord.y * 2 );

    // With the i and j coordinates of the centre of the cell,
    // convert these back into the world coordinates of the centre
    var centreX = ( i + j ) / 2;
    var centreY = ( j - i ) / 4;

    // Now convert these centre world coordinates back into the
    // cell coordinates
    int cellY = (int)Math.Round(centreY * -4f);
    int cellX = (int)Math.Round(centreX - ((cellY % 2) * 0.5f));

    return new Point() {
        x = cellX,
        y = cellY
    };
}

I used the following coordinate points as test cases

{ x = 1.5f, y = -0.25f } => ( 1, 1 )        // Centre of 1, 1
{ x = 1.9f, y = -0.25f } => ( 1, 1 )        // Near the right of 1, 1
{ x = 1.5f, y = -0.374f } => ( 1, 1 )       // Near the bottom of 1, 1
{ x = 1.1f, y = -0.25f } => ( 1, 1 )        // Near the left of 1, 1
{ x = 1.5f, y = -0.126f } => ( 1, 1 )       // Near the top of 1, 1
{ x = 2.5f, y = -0.25f } => ( 2, 1 )        // Centre of 2, 1
{ x = 2f, y = -0.5f } => ( 2, 2 )           // Centre of 2, 2

Hope this helps

Trevor
  • 1,251
  • 1
  • 9
  • 11
  • That is what i ended up having (with the help of friends) but when i navigate the mouse (from which i use the world coordinates), it is not working properly, especially on the Y part – reonZ Jan 29 '18 at 19:04
  • Are you trying to just convert the coordinates back, or are you trying to work out which cell a given world coordinate is in? If you're trying to identify which cell the point is in, which of the four points do you want the coordinates for as the "representative" point of the cell? – Trevor Jan 29 '18 at 19:07
  • I want to find a cell from world coordinates, so i have a vector or point comprised of 2 floats x & y, and from that i want to end up with 2 integers representing the cell. – reonZ Jan 29 '18 at 19:36
  • I'm still not quite following. Your X and Y integers don't represent a call, they represent a point, so which point of the four that make up a cell are you trying to get? The bottom one, for example? Do you have some test cases of inputs and expected outputs? – Trevor Jan 29 '18 at 19:39
  • https://i.imgur.com/kRd0KAE.png, the world coordinates i get from the CellToCoord() method give me a world position which represent the center of the cell. – reonZ Jan 29 '18 at 19:47
  • Ok, I see, I'll see if I can come up with something succinct. You might want to update the question to include those details. – Trevor Jan 29 '18 at 19:54
  • That is impressive and i thank you really, i worked on the issue with a friend for the past 4 hours and we could not figure out how to get it. Thanks a lot once again. – reonZ Jan 29 '18 at 21:56