2009-12-07 5 views
2

Imaginez un espace hexagonal avec 3 dimensions.Sélection de cellules voisines dans un champ hexagonal

Chaque carreau a les coordonnées XYZ. Je dois sélectionner un voisin de cellule donné dans le même plan. Avec SQL il est ressemble à:

$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); 

Mais, je ne l'aime pas de cette façon. Peut-être que quelqu'un connaît des algorithmes plus optimaux? Merci!

Répondre

4

Cela ressemble, vous pouvez utiliser un entre

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

Cela ne fonctionne pas exactement pour la section tbDir $. Je vais regarder cette affaire plus en détail.

OK, plutôt essayer

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) 

ou même

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 
+0

Je n'ai presque pas remarqué l'affaire $ tbDir avant de commenter. Cela me semble bon. Il permet également de placer des index sur x, y et z pour une optimisation supplémentaire. –

+0

Voici le résultat avec 9 tuiles, mais besoin de 6 + cible. extra 2 – Coyod

+0

Je pense que le dernier exemple est le plus optimal. Je vous remercie! – Coyod

3

Il est une application facile si vos algorithmes peuvent fonctionner avec un système de coordonnées non orthogonal. Dans votre cas, la partie de la tuile hexagonale qui est parallèle à un axe semble être vertical:

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

Si vous pouvez accepter un axe d'inclinaison Y, vous pouvez donner a, d, g la coordonnée X 0 (c'est-à-dire que l'axe Y passe par les centres de ces tuiles). (beh aurait X == 1, cfi a X == 2 et ainsi de suite). x a la coordonnée (-1,2). Vous pouvez maintenant déplacer comme ceci:

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 

Comme vous pouvez le voir, les mouvements sont maintenant complètement indépendants de la position y.

+0

Est le problème que je ne peux pas biaiser l'axe Y. Champ déjà formé et cellules ajoutées à db. Quoi qu'il en soit, merci! – Coyod

Questions connexes