1Math::PlanePath::HilberUtsCeurrvCeo(n3t)ributed Perl DocMuamtehn:t:aPtliaonnePath::HilbertCurve(3)
2
3
4

NAME

6       Math::PlanePath::HilbertCurve -- 2x2 self-similar quadrant traversal
7

SYNOPSIS

9        use Math::PlanePath::HilbertCurve;
10        my $path = Math::PlanePath::HilbertCurve->new;
11        my ($x, $y) = $path->n_to_xy (123);
12

DESCRIPTION

14       This path is an integer version of the curve described by David Hilbert
15       in 1891 for filling a unit square.  It traverses a quadrant of the
16       plane one step at a time in a self-similar 2x2 pattern,
17
18                  ...
19               |   |
20             7 |  63--62  49--48--47  44--43--42
21               |       |   |       |   |       |
22             6 |  60--61  50--51  46--45  40--41
23               |   |           |           |
24             5 |  59  56--55  52  33--34  39--38
25               |   |   |   |   |   |   |       |
26             4 |  58--57  54--53  32  35--36--37
27               |                   |
28             3 |   5---6   9--10  31  28--27--26
29               |   |   |   |   |   |   |       |
30             2 |   4   7---8  11  30--29  24--25
31               |   |           |           |
32             1 |   3---2  13--12  17--18  23--22
33               |       |   |       |   |       |
34           Y=0 |   0---1  14--15--16  19--20--21
35               +----------------------------------
36                 X=0   1   2   3   4   5   6   7
37
38       The start is a sideways U shape N=0 to N=3, then four of those are put
39       together in an upside-down U as
40
41           5,6    9,10
42           4,7--- 8,11
43             |      |
44           3,2   13,12
45           0,1   14,15--
46
47       The orientation of the sub parts ensure the starts and ends are
48       adjacent, so 3 next to 4, 7 next to 8, and 11 next to 12.
49
50       The process repeats, doubling in size each time and alternately
51       sideways or upside-down U with invert and/or transpose as necessary in
52       the sub-parts.
53
54       The pattern is sometimes drawn with the first step 0->1 upwards instead
55       of to the right.  Right is used here since that's what most of the
56       other PlanePaths do.  Swap X and Y for upwards first instead.
57
58       See examples/hilbert-path.pl for a sample program printing the path
59       pattern in ascii.
60
61   Level Ranges
62       Within a power-of-2 square 2x2, 4x4, 8x8, 16x16 etc (2^k)x(2^k) at the
63       origin, all the N values 0 to 2^(2*k)-1 are within the square.  The
64       maximum 3, 15, 63, 255 etc 2^(2*k)-1 is alternately at the top left or
65       bottom right corner.
66
67       Because each step is by 1, the distance along the curve between two X,Y
68       points is the difference in their N values (as from "xy_to_n()").
69
70       On the X=Y diagonal N=0,2,8,10,32,etc is the integers using only digits
71       0 and 2 in base 4, or equivalently have even-numbered bits 0, like
72       x0y0...z0.
73
74   Locality
75       The Hilbert curve is fairly well localized in the sense that a small
76       rectangle (or other shape) is usually a small range of N.  This
77       property is used in some database systems to store X,Y coordinates with
78       the Hilbert curve N as an index.  A search through an 2-D region is
79       then usually a fairly modest linear search through N values.
80       "rect_to_n_range()" gives exact N range for a rectangle, or see
81       "Rectangle to N Range" below for calculating on any shape.
82
83       The N range can be large when crossing sub-parts.  In the sample above
84       it can be seen for instance adjacent points X=0,Y=3 and X=0,Y=4 have
85       rather widely spaced N values 5 and 58.
86
87       Fractional X,Y values can be indexed by extending the N calculation
88       down into X,Y binary fractions.  The code here doesn't do that, but
89       could be pressed into service by moving the binary point in X and Y an
90       even number of places, the same in each.  (An odd number of bits would
91       require swapping X,Y to compensate for the alternating transpose in
92       part 0.)  The resulting integer N is then divided down by a
93       corresponding multiple-of-4 binary places.
94

FUNCTIONS

96       See "FUNCTIONS" in Math::PlanePath for behaviour common to all path
97       classes.
98
99       "$path = Math::PlanePath::HilbertCurve->new ()"
100           Create and return a new path object.
101
102       "($x,$y) = $path->n_to_xy ($n)"
103           Return the X,Y coordinates of point number $n on the path.  Points
104           begin at 0 and if "$n < 0" then the return is an empty list.
105
106           Fractional positions give an X,Y position along a straight line
107           between the integer positions.  Integer positions are always just 1
108           apart either horizontally or vertically, so the effect is that the
109           fraction part is an offset along either $x or $y.
110
111       "$n = $path->xy_to_n ($x,$y)"
112           Return an integer point number for coordinates "$x,$y".  Each
113           integer N is considered the centre of a unit square and an "$x,$y"
114           within that square returns N.
115
116       "($n_lo, $n_hi) = $path->rect_to_n_range ($x1,$y1, $x2,$y2)"
117           The returned range is exact, meaning $n_lo and $n_hi are the
118           smallest and biggest in the rectangle.
119
120   Level Methods
121       "($n_lo, $n_hi) = $path->level_to_n_range($level)"
122           Return "(0, 4**$level - 1)".
123

FORMULAS

125   N to X,Y
126       Converting N to X,Y coordinates is reasonably straightforward.  The top
127       two bits of N is a configuration
128
129           3--2                    1--2
130              |    or transpose    |  |
131           0--1                    0  3
132
133       according to whether it's an odd or even bit-pair position.  Then
134       within each of the "3" sub-parts there's also inverted forms
135
136           1--0        3  0
137           |           |  |
138           2--3        2--1
139
140       Working N from high to low with a state variable can record whether
141       there's a transpose, an invert, or both, being four states altogether.
142       A bit pair 0,1,2,3 from N then gives a bit each of X,Y according to the
143       configuration and a new state which is the orientation of that sub-
144       part.  William Gosper's HAKMEM item 115 has this with tables for the
145       state and X,Y bits,
146
147           <http://www.inwap.com/pdp10/hbaker/hakmem/topology.html#item115>
148
149       And C++ code based on that in Jorg Arndt's book,
150
151           <http://www.jjj.de/fxt/#fxtbook> (section 1.31.1)
152
153       It also works to process N from low to high, at each stage applying any
154       transpose (swap X,Y) and/or invert (bitwise NOT) to the low X,Y bits
155       generated so far.  This works because there's no "reverse" sections, or
156       since the curve is the same forward and reverse.  Low to high saves
157       locating the top bits of N, but if using bignums then the bitwise
158       inverts of the full X,Y values will be much more work.
159
160   X,Y to N
161       X,Y to N can follow the table approach from high to low taking one bit
162       from X and Y each time.  The state table of N-pair -> X-bit,Y-bit is
163       reversible, and a new state is based on the N-pair thus obtained (or
164       could be based on the X,Y bits if that mapping is combined into the
165       state transition table).
166
167   Rectangle to N Range
168       An easy over-estimate of the maximum N in a region can be had by
169       finding the next bigger (2^k)x(2^k) square enclosing the region.  This
170       means the biggest X or Y rounded up to the next power of 2, so
171
172           find lowest k with 2^k > max(X,Y)
173           N_max = 2^(2k) - 1
174
175       Or equivalently rounding down to the next lower power of 2,
176
177           find highest k with 2^k <= max(X,Y)
178           N_max = 2^(2*(k+1)) - 1
179
180       An exact N range can be found by following the high to low N to X,Y
181       procedure above.  Start at the 2^(2k) bit pair position in an N bigger
182       than the desired region and choose 2 bits for N to give a bit each of X
183       and Y.  The X,Y bits are based on the state table as above and the bits
184       chosen for N are those for which the resulting X,Y sub-square overlaps
185       some of the target region.  The smallest N similarly, choosing the
186       smallest bit pair for N which overlaps.
187
188       The biggest and smallest N digit for a sub-part can be found with a
189       lookup table.  The X range might cover one or both sub-parts, and the Y
190       range similarly, for a total 9 possible configurations.  Then a table
191       of state+coverage -> digit gives the minimum and maximum N bit-pair,
192       and state+digit gives a new state the same as X,Y to N.
193
194       Biggest and smallest N must be calculated with separate state and X,Y
195       values since they track down different N bits and thus different
196       states.  But they take the same number of steps from an enclosing level
197       down to level 0 and can thus be done in a single loop.
198
199       The N range for any shape can be found this way, not just a rectangle
200       like "rect_to_n_range()".  At each level the procedure only depends on
201       asking which combination of the four sub-parts overlaps some of the
202       target area.
203
204   Direction
205       Each step between successive N values is always 1 up, down, left or
206       right.  The next direction can be calculated from N in the high-to-low
207       procedure above by watching for the lowest non-3 digit and noting the
208       direction from that digit towards digit+1.  That can be had from the
209       state+digit -> X,Y table looking up digit and digit+1, or alternatively
210       a further table encoding state+digit -> direction.
211
212       The reason for taking only the lowest non-3 digit is that in a 3 sub-
213       part the direction it goes is determined by the next higher level.  For
214       example at N=11 the direction is down for the inverted-U of the next
215       higher level N=0,4,8,12.
216
217       This non-3 (or non whatever highest digit) is a general procedure and
218       can be used on any state-based high-to-low procedure of self-similar
219       curves.  In the current code it's used to apply a fractional part of N
220       in the correct direction but is not otherwise made directly available.
221
222       Because the Hilbert curve has no "reversal" sections it also works to
223       build a direction from low to high N digits.  1 and 2 digits make no
224       change to the orientation, 0 digit is a transpose, and a 3 digit is a
225       rotate and transpose, except that low 3s are transpose-only (no rotate)
226       for the same reason as taking the lowest non-3 above.
227
228       Jorg Arndt in the fxtbook above notes the direction can be obtained
229       just by counting 3s in n and -n (the twos-complement).  This numbers
230       segments starting n=1, unlike PlanePath here starting N=0, so it
231       becomes
232
233           N+1 count 3s  / 0 mod 2   S or E
234                         \ 1 mod 2   N or W
235
236           -(N+1) count 3s  / 0 mod 2   N or E
237                            \ 1 mod 2   S or W
238
239       For the twos-complement negation an even number of base-4 digits of N
240       must be taken.  Because -(N+1) = ~N, ie. a ones-complement, the second
241       part is also
242
243           N count 0s          / 0 mod 2   N or E
244           in even num digits  \ 1 mod 2   S or W
245
246       Putting the two together then
247
248           N count 0s   N+1 count 3s    direction (0=E,1=N,etc)
249           in base 4    in base 4
250
251             0 mod 2      0 mod 2          0
252             1 mod 2      0 mod 2          3
253             0 mod 2      1 mod 2          1
254             1 mod 2      1 mod 2          2
255
256   Segments in Direction
257       The number of segments in each direction is calculated in
258
259           Sergey Kitaev, Toufik Mansour and Patrice Séébold, "Generating the
260           Peano Curve and Counting Occurrences of Some Patterns", Journal of
261           Automata, Languages and Combinatorics, volume 9, number 4, 2004,
262           pages 439-455.
263           <https://personal.cis.strath.ac.uk/sergey.kitaev/publications.html>
264           <https://personal.cis.strath.ac.uk/sergey.kitaev/index_files/Papers/peano.ps>
265
266           (Preprint as Sergey Kitaev and Toufik Mansour, "The Peano Curve and
267           Counting Occurrences of Some Patterns", October 2002.
268           <http://arxiv.org/abs/math/0210268/>, version 1.)
269
270       Their form is based on keeping the top-most U shape fixed and expanding
271       sub-parts.  This means the end segments alternate vertical and
272       horizontal in successive expansion levels.
273
274           direction            k=1              2       2
275             1 to 4                            *---*   *---*
276                                  2           1|  3|   |1  |3
277               1                *---*          *   *---*   *
278               |               1|   |3        1| 4   2   4 |3
279           4--- ---2            *   *          *---*   *---*
280               |                                  1|   |3       k=2
281               3                               *---*   *---*
282                                                 2       2
283
284           count segments in direction, for k >= 1
285           d(1,k) = 4^(k-1)                = 1,4,16,64,256,1024,4096,...
286           d(2,k) = 4^(k-1) + 2^(k-1) - 1  = 1,5,19,71,271,1055,4159,...
287           d(3,k) = 4^(k-1)                = 1,4,16,64,256,1024,4096,...
288           d(4,k) = 4^(k-1) - 2^(k-1)      = 0,2,12,56,240, 992,4032,...
289                                    (A000302, A099393, A000302, A020522)
290
291           total segments d(1,k)+d(2,k)+d(3,k)+d(4,k) = 4^k - 1
292
293       The form in the path here keeps the first segment direction fixed.
294       This means a transpose 1<->2 and 3<->4 in odd levels.  The result is to
295       take the alternate d values as follows.  For k=0 there is a single
296       point N=0 so no line segments at all and so c(dir,0)=0.
297
298           first 4^k-1 segments
299
300           c(1,k) = / 0                        if k=0
301            North   | 4^(k-1) + 2^(k-1) - 1    if k odd >= 1
302                    \ 4^(k-1)                  if k even >= 2
303             = 0, 1, 4, 19, 64, 271, 1024, 4159, 16384, ...
304
305
306           c(2,k) = / 0                        if k=0
307            East    | 4^(k-1)                  if k odd >= 1
308                    \ 4^(k-1) + 2^(k-1) - 1    if k even >= 2
309             = 0, 1, 5, 16, 71, 256, 1055, 4096, 16511, ...
310
311           c(3,k) = / 0                        if k=0
312            South   | 4^(k-1) - 2^(k-1)        if k odd >= 1
313                    \ 4^(k-1)                  if k even >= 2
314             = 0, 0, 4, 12, 64, 240, 1024, 4032, 16384, ...
315
316           c(4,k) = / 0                        if k=0
317            West    | 4^(k-1)                  if k odd >= 1
318                    \ 4^(k-1) - 2^(k-1)        if k even >= 2
319             = 0, 1, 2, 16, 56, 256, 992, 4096, 16256, ...
320
321       The segment N=4^k-1 to N=4^k is North (direction 1) when k odd, or East
322       (direction 2) when k even.  That could be added to the respective cases
323       in c(1,k) and c(2,k) if desired.
324
325   Hamming Distance
326       The Hamming distance between integers X and Y is the number of bit
327       positions where the two values differ when written in binary.  On the
328       Hilbert curve each bit-pair of N becomes a bit of X and a bit of Y,
329
330              N      X   Y
331           ------   --- ---
332           0 = 00    0   0
333           1 = 01    1   0     <- difference 1 bit
334           2 = 10    1   1
335           3 = 11    0   1     <- difference 1 bit
336
337       So the Hamming distance for N=0to3 is 1 at N=1 and N=3.  As higher
338       levels these the X,Y bits may be transposed (swapped) or rotated by 180
339       or both.  A transpose swapping X<->Y doesn't change the bit difference.
340       A rotate by 180 is a flip 0<->1 of the bit in each X and Y, so that
341       doesn't change the bit difference either.
342
343       On that basis the Hamming distance X,Y is the number of base4 digits of
344       N which are 01 or 11.  If bit positions are counted from 0 for the
345       least significant bit then
346
347           X,Y coordinates of N
348           HammingDist(X,Y) = count 1-bits at even bit positions in N
349                            = 0,1,0,1, 1,2,1,2, 0,1,0,1, 1,2,1,2, ... (A139351)
350
351       See also "Hamming Distance" in Math::PlanePath::CornerReplicate which
352       is the same formula, but arising directly from 01 or 11, no transpose
353       or rotate.
354

OEIS

356       This path is in Sloane's OEIS in several forms,
357
358           <http://oeis.org/A059252> (etc)
359
360           A059253    X coord
361           A059252    Y coord
362           A059261    X+Y
363           A059285    X-Y
364           A163547    X^2+Y^2 = radius squared
365           A139351    HammingDist(X,Y)
366           A059905    X xor Y, being ZOrderCurve X
367
368           A163365    sum N on diagonal
369           A163477    sum N on diagonal, divided by 4
370           A163482    N values on X axis
371           A163483    N values on Y axis
372           A062880    N values on diagonal X=Y (digits 0,2 in base 4)
373
374           A163538    dX -1,0,1 change in X
375           A163539    dY -1,0,1 change in Y
376           A163540    absolute direction of each step (0=E,1=S,2=W,3=N)
377           A163541    absolute direction, swapped X,Y
378           A163542    relative direction (ahead=0,right=1,left=2)
379           A163543    relative direction, swapped X,Y
380
381           A083885    count East segments N=0 to N=4^k (first 4^k segs)
382
383           A163900    distance dX^2+dY^2 between Hilbert and ZOrder
384           A165464    distance dX^2+dY^2 between Hilbert and Peano
385           A165466    distance dX^2+dY^2 between Hilbert and transposed Peano
386           A165465    N where Hilbert and Peano have same X,Y
387           A165467    N where Hilbert and Peano have transposed same X,Y
388
389       The following take points of the plane in various orders, each value in
390       the sequence being the N of the Hilbert curve at those positions.
391
392           A163355    N by the ZOrderCurve points sequence
393           A163356      inverse, ZOrderCurve by Hilbert points order
394           A166041    N by the PeanoCurve points sequence
395           A166042      inverse, PeanoCurve N by Hilbert points order
396           A163357    N by diagonals like Math::PlanePath::Diagonals with
397                      first Hilbert step along same axis the diagonals start
398           A163358      inverse
399           A163359    N by diagonals, transposed start along the opposite axis
400           A163360      inverse
401           A163361    A163357 + 1, numbering the Hilbert N's from N=1
402           A163362      inverse
403           A163363    A163355 + 1, numbering the Hilbert N's from N=1
404           A163364     inverse
405
406       These sequences are permutations of the integers since all X,Y
407       positions of the first quadrant are covered by each path (Hilbert,
408       ZOrder, Peano).  The inverse permutations can be thought of taking X,Y
409       positions in the Hilbert order and asking what N the ZOrder, Peano or
410       Diagonals path would put there.
411
412       The A163355 permutation by ZOrderCurve can be considered for repeats or
413       cycles,
414
415           A163905    ZOrderCurve permutation A163355 applied twice
416           A163915    ZOrderCurve permutation A163355 applied three times
417           A163901    fixed points (N where X,Y same in both curves)
418           A163902    2-cycle points
419           A163903    3-cycle points
420           A163890    cycle lengths, points by N
421           A163904    cycle lengths, points by diagonals
422           A163910    count of cycles in 4^k blocks
423           A163911    max cycle length in 4^k blocks
424           A163912    LCM of cycle lengths in 4^k blocks
425           A163914    count of 3-cycles in 4^k blocks
426           A163909      those counts for even k only
427           A163891    N of previously unseen cycle length
428           A163893      first differences of those A163891
429           A163894    smallest value not an n-cycle
430           A163895      position of new high in A163894
431           A163896      value of new high in A163894
432
433           A163907    ZOrderCurve permutation twice, on points by diagonals
434           A163908      inverse of this
435
436       See examples/hilbert-oeis.pl for a sample program printing the A163359
437       permutation values.
438

SEE ALSO

440       Math::PlanePath, Math::PlanePath::HilbertSides,
441       Math::PlanePath::HilbertSpiral
442
443       Math::PlanePath::PeanoCurve, Math::PlanePath::ZOrderCurve,
444       Math::PlanePath::BetaOmega, Math::PlanePath::KochCurve
445
446       Math::Curve::Hilbert, Algorithm::SpatialIndex::Strategy::QuadTree
447
448       David Hilbert, "Ueber die stetige Abbildung einer Line auf ein
449       Flächenstück", Mathematische Annalen, volume 38, number 3, p459-460,
450       DOI 10.1007/BF01199431.
451       <http://www.springerlink.com/content/v1u6427kk33k8j56/>
452       <http://notendur.hi.is/oddur/hilbert/gcs-wrapper-1.pdf>
453

HOME PAGE

455       <http://user42.tuxfamily.org/math-planepath/index.html>
456

LICENSE

458       Copyright 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 Kevin
459       Ryde
460
461       This file is part of Math-PlanePath.
462
463       Math-PlanePath is free software; you can redistribute it and/or modify
464       it under the terms of the GNU General Public License as published by
465       the Free Software Foundation; either version 3, or (at your option) any
466       later version.
467
468       Math-PlanePath is distributed in the hope that it will be useful, but
469       WITHOUT ANY WARRANTY; without even the implied warranty of
470       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
471       General Public License for more details.
472
473       You should have received a copy of the GNU General Public License along
474       with Math-PlanePath.  If not, see <http://www.gnu.org/licenses/>.
475
476
477
478perl v5.32.0                      2020-07-28  Math::PlanePath::HilbertCurve(3)
Impressum