There’s a beautiful article by Herman Tulleken on Gamasutra, 20 Fun Grid Facts (Hex Grids), from 2014.

The part about the coordinates reminds me of some of the code I have written...

## One Step To

# Brute forcing the "next" step by trying all the neighbors. The
# connection data to connect to neighbouring hexes.
#
# Example Map Index for the array
#
# 0201 2
# 0102 0302 1 3
# 0202 0402
# 0103 0303 6 4
# 0203 0403 5
# 0104 0304
#
# Note that the arithmetic changes when x is odd.
sub one_step_to {
my ($self, $other) = @_;
my $delta = [[[-1, 0], [ 0, -1], [+1, 0], [+1, +1], [ 0, +1], [-1, +1]], # even
[[-1, -1], [ 0, -1], [+1, -1], [+1, 0], [ 0, +1], [-1, 0]]]; # odd
my ($min, $best);
for my $i (0 .. 5) {
# make a new guess
my ($x, $y) = ($self->x + $delta->[$self->x % 2]->[$i]->[0],
$self->y + $delta->[$self->x % 2]->[$i]->[1]);
my $d = ($other->x - $x) * ($other->x - $x)
+ ($other->y - $y) * ($other->y - $y);
if (!defined($min) || $d < $min) {
$min = $d;
$best = Point->new(x => $x, y => $y);
}
}
return $best;
}

## Distance

sub distance {
my ($x1, $y1, $x2, $y2) = @_;
if (@_ == 2) {
($x1, $y1, $x2, $y2) = map { xy($_) } @_;
}
# transform the coordinate system into a decent system with one axis tilted by
# 60°
$y1 = $y1 - POSIX::ceil($x1/2);
$y2 = $y2 - POSIX::ceil($x2/2);
if ($x1 > $x2) {
# only consider moves from left to right and transpose start and
# end point to make it so
my ($t1, $t2) = ($x1, $y1);
($x1, $y1) = ($x2, $y2);
($x2, $y2) = ($t1, $t2);
}
if ($y2>=$y1) {
# if it the move has a downwards component add Δx and Δy
return $x2-$x1 + $y2-$y1;
} else {
# else just take the larger of Δx and Δy
return $x2-$x1 > $y1-$y2 ? $x2-$x1 : $y1-$y2;
}
}

Tags: Hex Maps Programming Perl

## Comments