NAME
Path::Hilbert  A nofrills converter between 1D and 2D spaces using the Hilbert curve
VERSION
Version 2.000
SYNOPSIS
use Path::Hilbert;
my ($x, $y) = d2xy(16, 127);
my $d = xy2d(16, $x, $y);
die unless $d == 127;
my $space = Path::Hilbert>new(16);
my ($u, $v) = $space>d2xy(127);
my $t = $space>xy2d($u, $v);
die unless $t == 127;
DESCRIPTION
See Wikipedia for a description of the Hilbert curve, and why it's a good idea.
Most (all?) of the existing CPAN modules for dealing with Hilbert curves state "only works for $foo data", "optimized for $foo situations", or "designed to work as part of the $foo framework".
This module is based directly on the example algorithm given on Wikipedia, except it is not subject to the strict limitation of "proper" Hilbert curves, which is that the sidelength $n MUST be a nonnegative integer power of 2.
If you supply an "invalid but sane" side length (i.e. any positive number), be forewarned that you'll get a noninteger answer. Unfortunately, I haven't yet worked out how to make this particular algorithm work with noninteger inputs for $d, or ($x, $y), so if you supply such, they'll be rounded to the nearest integer before being fed into the algorithm. So far, I have not found a practical realworld usecase where the roundingerror is significant  except perhaps in the case of very small (single digit or less) side lengths, but I hereby advise you to pre and postscale the arguments and return values by some sane amount as the best workaround.
FunctionOriented Interface
 ($X, $Y) = d2xy($SIDE, $INDEX)

Returns the X and Y coordinates (each in the range 0 .. n  1) of the supplied INDEX (in the range 0 .. SIDE ** 2  1), where SIDE itself is an integer power of 2.
 $INDEX = xy2d($SIDE, $X, $Y)

Returns the INDEX (in the range 0 .. SIDE ** 2  1) of the point corresponding to the supplied X and Y coordinates (each in the range 0 .. n  1), where SIDE itself is an integer power of 2.
ObjectOriented Interface
 $object = Path::Hilbert>new(SIDE)

Create a new Path::Hilbert object with the specified SIDE (which must be an integer power of 2).
 ($X, $Y) = $object>d2xy($INDEX)

Returns the X and Y coordinates (each in the range 0 .. n  1) of the supplied INDEX (in the range 0 .. SIDE ** 2  1), where SIDE was provided via new().
 $INDEX = $object>xy2d($X, $Y)

Returns the INDEX (in the range 0 .. SIDE ** 2  1) of the point corresponding to the supplied X and Y coordinates (each in the range 0 .. n  1), where SIDE was provided via new().
AUTOMATIC USE OF XS
As of v2.000, this module automatically loads and uses Path::Hilbert::XS if possible (i.e. when that module is installed), except when Path::Hilbert::BigInt is requested (which still tries GMP, Pari, and FastCalc in that order, all of which are slower than even the nonXS module).
CAVEATS
If your platform has $n bit integers, things will go badly if you try a side length longer than 2 ** ($n / 2). If you need enormous Hilbert spaces, you should try Path::Hilbert::BigInt, which uses Math::BigInt instead of the native integer
support for your platform.
BUGS
Please let me know via the CPAN RT if you find any algorithmic defects.
AUTHOR
PWBENNETT <paul.w.bennett@gmail.com>
LICENSE
GNU LGPL 3.0 or newer.