Выбор соседних клеток в гексагональном поле - PullRequest
2 голосов
/ 07 декабря 2009

Представьте себе шестиугольное пространство с 3 измерениями.

Каждая плитка имеет координаты XYZ. Мне нужно выбрать соседей по данной ячейке в одной плоскости. С SQL это выглядит так:

$tbDir = $y % 2 == 0 ? -1 : 1;

$result =  db_query('SELECT x,y,z FROM {cells} WHERE
                    x = %d AND y = %d AND z = %d OR
                    x = %d AND y = %d AND z = %d OR
                    x = %d AND y = %d AND z = %d OR
                    x = %d AND y = %d AND z = %d OR
                    x = %d AND y = %d AND z = %d OR
                    x = %d AND y = %d AND z = %d OR
                    x = %d AND y = %d AND z = %d ',
                    $x, $y, $z,
                    $x-1, $y, $z,
                    $x+1, $y, $z,
                    $x, $y-1, $z,
                    $x, $y+1, $z,
                    $x+$tbDir, $y-1, $z,
                    $x+$tbDir, $y+1, $z);

Но мне не нравится этот способ. Возможно, кто-то знает более оптимальные алгоритмы? Спасибо!

Ответы [ 2 ]

4 голосов
/ 07 декабря 2009

Похоже, вы можете использовать между

x BETWEEN $x-1 AND $x+1 AND y BETWEEN $y-1 AND $y+1 AND z = $z

Это может не совсем работать для секции $ tbDir. Я рассмотрю этот случай более подробно.

ОК, попробуйте это

WHERE   x BETWEEN ($x-1 AND $x+1 AND y = $y AND z = $z)
OR      (y BETWEEN $y-1 AND $y+1 AND x = $x AND z = $z)
OR      (y BETWEEN $y-1 AND $y+1 AND x = $x + $tbDir AND z = $z)

или даже

WHERE   (   (x BETWEEN $x-1 AND $x+1 AND y = $y )
            OR      (y BETWEEN $y-1 AND $y+1 AND x = $x)
            OR      (y BETWEEN $y-1 AND $y+1 AND x = $x + $tbDir)
        )
AND     z = $z
3 голосов
/ 07 декабря 2009

Существует простое отображение, если ваши алгоритмы могут работать с неортогональной системой координат. В вашем случае часть шестигранной плитки, параллельная оси, кажется вертикальной:

 / \ / \ / \
| a | b | c |
 \ / \ / \ / \
  | d | e | f |
 / \ / \ / \ /
| x | g | h | i

Если вы можете принять наклонную ось Y, то вы можете дать a, d, g координату X 0 (т.е. ось Y проходит через центры этих плиток). (beh будет иметь X == 1, cfi будет иметь X == 2 и т. Д.). x имеет координату (-1,2). Теперь вы можете двигаться так:

e -> f: x+1,y
e -> d: x-1,y
e -> b: x,  y-1
e -> c: x+1,y-1
e -> g: x-1,y+1
e -> h: x,  y+1

Как вы можете видеть, движения теперь полностью независимы от позиции y.

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