Math::...ryBase(3pm)
β¨ NAME β¨
Math::PlanePath::ImaginaryBase β replications in four directions π«
okay so bestie, this is a Perl module from the Math::PlanePath family, and it draws a plane-filling-ish path that replicates itself in four directions. it's giving chaotic-but-make-it-mathematical, and we're gonna walk through it together π«Ά
πΈ SYNOPSIS πΈ
use Math::PlanePath::ImaginaryBase;
my $path = Math::PlanePath::ImaginaryBase->new (radix => 4);
my ($x, $y) = $path->n_to_xy (123);
literally three lines and you're in. iconic.
π DESCRIPTION π
So this is a simple pattern that comes from expressing complex numbers in a "base" of i*sqrt(2), or honestly any i*sqrt(r) base. Same energy, different radix. Or, if you wanna look at it sideways, it's negabinary-encoded X and Y digits, interleaved. The default radix=2 looks like this:
38 39 34 35 54 55 50 51 5
36 37 32 33 52 53 48 49 4
46 47 42 43 62 63 58 59 3
44 45 40 41 60 61 56 57 2
6 7 2 3 22 23 18 19 1
4 5 0 1 20 21 16 17 <- Y=0
14 15 10 11 30 31 26 27 -1
12 13 8 9 28 29 24 25 -2
^
-2 -1 X=0 1 2 3 4 5
You can see the pattern if you chop it into blocks like this:
+---------------------------------------+
| 38 39 34 35 54 55 50 51 |
| |
| 36 37 32 33 52 53 48 49 |
| |
| 46 47 42 43 62 63 58 59 |
| |
| 44 45 40 41 60 61 56 57 |
+---------+---------+-------------------+
| 6 7 | 2 3 | 22 23 18 19 |
| +----+----+ |
| 4 5 | 0 | 1 | 20 21 16 17 |
+---------+----+----+ |
| 14 15 10 11 | 30 31 26 27 |
| | |
| 12 13 8 9 | 28 29 24 25 |
+-------------------+-------------------+
Here's the tea β β after N=0 sits at the origin, N=1 replicates that single point to the right. Then that pair repeats above as N=2 and N=3. Then that whole 2x2 block repeats to the left as N=4 to N=7, then the 4x2 gets repeated below as N=8 to N=16. Then 4x4 to the right as N=16 to N=31, etc. Every repeat is 90 degrees further around. And here's the key vibe: the relative layout and orientation of any sub-part stays exactly the same when it gets replicated. no cap. π₯
π Complex Base
This pattern comes from writing a complex number in a "base" of i*sqrt(r). For an integer X,Y:
base b = i*sqrt(r)
a[j] = digit 0 to r-1
X + Y*i*sqrt(r) = a[k]*b^k + ... + a[2]*b^2 + a[1]*b + a[0]
and N is the a[j] digits in base r:
N = a[k]*r^k + ... + a[2]*r^2 + a[1]*r + a[0]
The sum's imaginary part has a factor sqrt(r). Divide that out and boom, you get an integer Y. For actual use as a number base, that factor can just be omitted and instead you use fractional digits a[-1]*r^-1 etc to reach smaller Y values β like for example in Knuth's "quater-imaginary" system of base 2*i, which is i*sqrt(4), with digits 0,1,2,3. (That's Knuth Seminumerical Algorithms section 4.1 and CACM 1960 pp245-247, if you wanna go read the source material π.)
The powers of i in the base give you the replication direction, so i^0=1 is right, i^1=i is up, i^2=-1 is right, i^3=-i is down, etc. Then the power of sqrt(r) spreads the replication in that respective direction. Two steps repeat horizontally and sqrt(r)^2=r, hence the doubling: 1x1 to the right, 2x2 to the left, 4x4 to the right, etc β and the same deal vertically. π
π¦ Negabinary
The way blocks repeat horizontally first to the right and then to the left is per the negabinary system, base b=-2.
X = x[k]*(-2)^k + ... + x[2]*(-2)^2 + x[1]*(-2) + x[0]
The effect: any positive or negative X gets represented by a positive integer index NX.
X, negabinary: ... -1 -2 0 1 2 3 4 5 ...
index NX: 2 3 0 1 6 7 4 5
Notice how the 0 point replicates to the right as 1, and then that pair 0,1 replicates to the left as 2,3. Then the block 2,3,0,1 repeats to the right as 6,7,4,5 β same order, just with 4 added to each. Then that resulting block of eight repeats to the left the same way, in the same order with 8 added to each. it's a whole system, bestie πΈ
ImaginaryBase takes the indexes NX and NY of these negabinary forms and makes N by interleaving the digits (bits) of NX and NY. That interleaving is in the style of the ZOrderCurve:
zX,zY = ZOrderCurve n_to_xy(N)
X = to_negabinary(zX)
Y = to_negabinary(zY)
X,Y equals ImaginaryBase n_to_xy(N)
The ZOrderCurve replicates blocks alternately right and up, whereas for ImaginaryBase here it's right, up, left, down, and so on repeating. different rotation schedule, same family vibe π«
π Radix
The radix parameter controls the radix used to break N into X,Y. For example radix 3 replicates to make 3x1, 3x3, 9x3, 9x9, etc blocks. The replications are radix-1=2 copies of the preceding level at each stage:
radix => 3
+------------------------+-----------+
| 24 25 26 15 16 17 | 6 7 8 | 2
| | |
| 21 22 23 12 13 14 | 3 4 5 | 1
| +-----------+
| 18 19 20 9 10 11 | 0 1 2 | <- Y=0
+------------------------+-----------+
| 51 52 53 42 43 44 33 34 35 | -1
| |
| 48 49 50 39 40 41 30 31 32 | -2
| |
| 45 46 47 36 37 38 27 28 29 | -3
| |
| 78 79 80 69 70 71 60 61 62 | -4
| |
| 75 76 77 66 67 68 57 58 59 | -5
| |
| 72 73 74 63 64 65 54 55 56 | -6
+------------------------------------+
^
-6 -5 -4 -3 -2 -1 X=0 1 2
X,Y are "negaternary" in this case, and similar negaradix base=-radix for higher values. π
π FUNCTIONS π
See "FUNCTIONS" in Math::PlanePath for behaviour common to all path classes.
$path = Math::PlanePath::ImaginaryBase->new ()$path = Math::PlanePath::ImaginaryBase->new (radix => $r)β Create and return a new path object. β¨($x,$y) = $path->n_to_xy ($n)β Return the X,Y coordinates of point number$non the path. Points begin at 0 and if"$n < 0"then the return is an empty list. (yes, empty. it just ghosts you π)($n_lo, $n_hi) = $path->rect_to_n_range ($x1,$y1, $x2,$y2)β The returned range is exact, meaning$n_loand$n_hiare the smallest and biggest in the rectangle. no guessing, we're precise here π
β Level Methods
($n_lo, $n_hi) = $path->level_to_n_range($level)β Return(0, $radix**$level - 1).
π« FORMULAS π«
π§ Rectangle to N Range
The X and Y ranges can be treated separately and then interleaved:
NXmin,NXmax = negaradix range to cover x1..x2
NYmin,NYmax = negaradix range to cover y1..y2
Nmin = interleave digits NXmin, NYmin
Nmax = interleave digits NXmax, NYmax
If the NX,NY ranges are exact then the resulting Nmin,Nmax range is exact too. slay β¨
An exact negaradix range can be calculated by digits high to low, by considering the range taken by the negaradix form. For example, two negaternary digits:
N digit 2 1 0
+---------+---------+---------+
N index | 6 7 8 | 3 4 5 | 0 1 2 |
+---------+---------+---------+
X negaternary -6 -5 -4 -3 -2 -1 0 1 2
^
base
Taking the base=-90909...90 which is the lowest taken (where 9 is the radix digit R-1), then the next digit of N is the position from X-base, taken alternately reverse 2,1,0 as shown here or forward 0,1,2. π
π OEIS π
Entries in Sloane's Online Encyclopedia of Integer Sequences related to this path include:
<http://oeis.org/A057300> (etc)
radix=2
A057300 permutation N at transpose Y,X (swap bit pairs)
radix=3
A163327 permutation N at transpose Y,X (swap trit pairs)
radix=4
A126006 permutation N at transpose Y,X (swap digit pairs)
radix=16
A217558 permutation N at transpose Y,X (swap digit pairs)
π«Ά SEE ALSO π«Ά
Math::PlanePath, Math::PlanePath::ImaginaryHalf, Math::PlanePath::CubicBase, Math::PlanePath::ZOrderCurve
π HOME PAGE π
<http://user42.tuxfamily.org/math-planepath/index.html>
π LICENSE π
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Kevin Ryde
Math-PlanePath is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
Math-PlanePath is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Math-PlanePath. If not, see <http://www.gnu.org/licenses/>.
fr fr, that all-caps warranty disclaimer is the loudest part of the whole page and it means it. no promises, bestie π
and that's the whole page, we ate and left no crumbs π this was perl v5.32.0, dated 2021-01-23, from the Math::...ryBase(3pm) corner of the User Contributed Perl Documentation universe. mwah πβ¨π
π¦ where this page comes from
- debian bookworm: libmath-planepath-perl 129-1 Β· GPL-3.0-or-later
- debian trixie: libmath-planepath-perl 129-1 Β· GPL-3.0-or-later
- ubuntu jammy: libmath-planepath-perl 129-1 Β· GPL-3.0-or-later
- ubuntu noble: libmath-planepath-perl 129-1 Β· GPL-3.0-or-later
- ubuntu resolute: libmath-planepath-perl 129-1 Β· GPL-3.0-or-later
- ubuntu stonking: libmath-planepath-perl 129-1 Β· GPL-3.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms