views:

102

answers:

2

Imagine hexagonal space with 3 dimensions.

Each tile has coordinates XYZ. I need to select a given cell neighbors in the same plane. With SQL it's looks like:

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

But, i don't like this way. Perhaps someone know more optimal algorithms? Thank you!

+3  A: 

This looks like you can use a between

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

This might not exactly work for the $tbDir section. I will have a look at this case in more detail.

OK, rather try this

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)

or even

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
astander
I almost didn't notice the $tbDir case before I commented. This looks good to me. It also allows for indexes to be placed on x, y, and z for a further optimization.
cballou
Here is result with 9 tiles, but needed 6 + target. extra 2
Coyod
i think the last example is most optimal. Thank you!
Coyod
Was an interesting problem X-)
astander
This is only the beginning :)
Coyod
+2  A: 

There is an easy mapping if your algorithms can work with a non-orthogonal coordinate system. In your case, the part of the hex tile which is parallel to an axis seems to be vertical:

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

If you can accept a skew Y axis, then you can give a, d, g the X coordinate 0 (i.e. the Y axis goes through the centers of these tiles). (beh would have X == 1, cfi has X == 2 and so on). x has the coordinate (-1,2). Now you can move like this:

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

As you can see, the movements are now completely independent of the y position.

Aaron Digulla
Is the problem that I can't skew the Y axis. Field already formed and cells added to db. Anyway, thanks!
Coyod