Получение плитки из координат на шахматной изометрической сетке

Я не могу понять математику. У меня есть ступенчатая 2D-изометрическая сетка, у меня нет проблем с преобразованием ячеек сетки в мировые координаты, но теперь я не могу понять, как обратить процесс вспять.

Вот метод CellToCoord:

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

Довольно просто и отображать сетку точно так, как я хотел, чтобы это было, я хотел бы получить плитка из мировых координат сейчас.

Изменить:
Изображение, мировые координаты, которые я получаю из метода CellToCoord(), дают мне мировая позиция, которая представляет собой центр ячейки.


person reonZ    schedule 29.01.2018    source источник


Ответы (1)


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
    };
}

Это должно обратить процесс вспять. Я использовал Point в качестве универсального контейнера для целочисленных координат X и Y, вы можете заменить его по мере необходимости.

Самая большая проблема, на мой взгляд, заключается в том, что мутация X изначально была основана на целочисленном значении Y, из которого вы затем сохранили значение с плавающей запятой. Я не мог найти способ изменить это без Math.Round(), чтобы надежно преобразовать результаты с плавающей запятой в целые значения.

Обновить Расчет координат ячейки, содержащей заданную мировую координату:

Глядя на то, как расположены ваши мировые координаты, мы видим, что центры каждой ячейки находятся на диагональных линиях, заданных следующим образом:

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

где i и j — целые числа. Эта диаграмма показывает это для x - 2y = i диагоналей.

Диаграмма с диагональными координатами

Используя их, мы можем взять мировые координаты данной точки, вычислить i и j, а затем округлить их до ближайшего целого числа, чтобы получить центр ячейки как i и j.

Затем мы можем использовать i и j для определения x и y центра ячейки и использовать функцию, которую я опубликовал ранее, чтобы преобразовать их обратно в координаты ячейки.

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
    };
}

Я использовал следующие координатные точки в качестве тестовых случаев

{ 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

Надеюсь это поможет

person Trevor    schedule 29.01.2018
comment
Это то, что у меня получилось (с помощью друзей), но когда я перемещаюсь мышью (из которой я использую мировые координаты), она не работает должным образом, особенно в части Y. - person reonZ; 29.01.2018
comment
Вы пытаетесь просто преобразовать координаты обратно или пытаетесь выяснить, в какой ячейке находится данная мировая координата? Если вы пытаетесь определить, в какой ячейке находится точка, координаты какой из четырех точек вам нужны в качестве репрезентативной точки ячейки? - person Trevor; 29.01.2018
comment
Я хочу найти ячейку по мировым координатам, поэтому у меня есть вектор или точка, состоящая из 2 поплавков x и y, и из этого я хочу получить 2 целых числа, представляющих ячейку. - person reonZ; 29.01.2018
comment
Я все еще не совсем понимаю. Ваши целые числа X и Y не представляют вызов, они представляют собой точку, так какую точку из четырех, составляющих ячейку, вы пытаетесь получить? Нижний, например? У вас есть тестовые примеры входных данных и ожидаемых результатов? - person Trevor; 29.01.2018
comment
i.imgur.com/kRd0KAE.png, мировые координаты, которые я получаю из CellToCoord() Метод дает мне мировую позицию, которая представляет собой центр ячейки. - person reonZ; 29.01.2018
comment
Хорошо, я вижу, я посмотрю, смогу ли я придумать что-нибудь лаконичное. Возможно, вы захотите обновить вопрос, чтобы включить эти детали. - person Trevor; 29.01.2018
comment
Это впечатляет, и я действительно благодарю вас, я работал над проблемой с другом в течение последних 4 часов, и мы не могли понять, как ее получить. Большое спасибо еще раз. - person reonZ; 30.01.2018