.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Math::PlanePath::GosperReplicate 3pm" .TH Math::PlanePath::GosperReplicate 3pm "2021-01-23" "perl v5.32.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Math::PlanePath::GosperReplicate \-\- self\-similar hexagon replications .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 3 \& use Math::PlanePath::GosperReplicate; \& my $path = Math::PlanePath::GosperReplicate\->new; \& my ($x, $y) = $path\->n_to_xy (123); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This is a self-similar hexagonal tiling of the plane. At each level the shape is the Gosper island. .PP .Vb 10 \& 17\-\-\-\-16 4 \& / \e \& 24\-\-\-\-23 18 14\-\-\-\-15 3 \& / \e \e \& 25 21\-\-\-\-22 19\-\-\-\-20 10\-\-\-\- 9 2 \& \e / \e \& 26\-\-\-\-27 3\-\-\-\- 2 11 7\-\-\-\- 8 1 \& / \e \e \& 31\-\-\-\-30 4 0\-\-\-\- 1 12\-\-\-\-13 <\- Y=0 \& / \e \e \& 32 28\-\-\-\-29 5\-\-\-\- 6 45\-\-\-\-44 \-1 \& \e / \e \& 33\-\-\-\-34 38\-\-\-\-37 46 42\-\-\-\-43 \-2 \& / \e \e \& 39 35\-\-\-\-36 47\-\-\-\-48 \-3 \& \e \& 40\-\-\-\-41 \-4 \& \& ^ \& \-7 \-6 \-5 \-4 \-3 \-2 \-1 X=0 1 2 3 4 5 6 7 .Ve .PP Points are spread out on every second X coordinate to make a triangular lattice in integer coordinates (see \*(L"Triangular Lattice\*(R" in Math::PlanePath). .PP The base pattern is the inner N=0 to N=6, then six copies of that shape are arranged around as the blocks N=7,14,21,28,35,42. Then six copies of the resulting N=0 to N=48 shape are replicated around, etc. .PP Each point can be taken as a little hexagon, so that all points tile the plane with hexagons. The innermost N=0 to N=6 are for instance, .PP .Vb 10 \& * * \& / \e / \e \& / \e / \e \& * * * \& | 3 | 2 | \& * * * \& / \e / \e / \e \& / \e / \e / \e \& * * * * \& | 4 | 0 | 1 | \& * * * * \& \e / \e / \e / \& \e / \e / \e / \& * * * \& | 5 | 6 | \& * * * \& \e / \e / \& \e / \e / \& * * .Ve .PP The further replications are the same arrangement, but the sides become ever wigglier and the centres rotate around. The rotation can be seen N=7 at X=5,Y=1 which is up from the X axis. .PP The \f(CW\*(C`FlowsnakeCentres\*(C'\fR path is this same replicating shape, but starting from a side instead of the middle and traversing in such as way as to make each N adjacent. The \f(CW\*(C`Flowsnake\*(C'\fR curve itself is this replication too, but segments across hexagons. .SS "Complex Base" .IX Subsection "Complex Base" The path corresponds to expressing complex integers X+i*Y in a base .PP .Vb 1 \& b = 5/2 + i*sqrt(3)/2 .Ve .PP with coordinates scaled to put equilateral triangles on a square grid. So for integer X,Y on the triangular grid (X,Y either both odd or both even), .PP .Vb 1 \& X/2 + i*Y*sqrt(3)/2 = a[n]*b^n + ... + a[2]*b^2 + a[1]*b + a[0] .Ve .PP where each digit a[i] is either 0 or a sixth root of unity encoded into base\-7 digits of N, .PP .Vb 2 \& w6 = e^(i*pi/3) sixth root of unity, b = 2 + w6 \& = 1/2 + i*sqrt(3)/2 \& \& N digit a[i] complex number \& \-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& 0 0 \& 1 w6^0 = 1 \& 2 w6^1 = 1/2 + i*sqrt(3)/2 \& 3 w6^2 = \-1/2 + i*sqrt(3)/2 \& 4 w6^3 = \-1 \& 5 w6^4 = \-1/2 \- i*sqrt(3)/2 \& 6 w6^5 = 1/2 \- i*sqrt(3)/2 .Ve .PP 7 digits suffice because .PP .Vb 1 \& norm(b) = (5/2)^2 + (sqrt(3)/2)^2 = 7 .Ve .SS "Rotate Numbering" .IX Subsection "Rotate Numbering" Parameter \f(CW\*(C`numbering_type => \*(Aqrotate\*(Aq\*(C'\fR applies a rotation in each sub-part according to its location around the preceding level. .PP The effect can be illustrated by writing N in base\-7. Part 10\-16 is the same as the middle 0\-6. Part 20\-26 has a rotation by +60 degrees. Part 30\-36 has rotation by +120 degrees, and so on. .PP .Vb 10 \& 22\-\-\-\-21 \& / / numbering_type => \*(Aqrotate\*(Aq \& 31 36 23 20 26 N shown in base\-7 \& / \e \e \e / \& 32 30 35 24\-\-\-\-25 13\-\-\-\-12 \& \e / / \e \& 33\-\-\-\-34 3\-\-\-\- 2 14 10\-\-\-\-11 \& / \e \e \& 46\-\-\-\-45 4 0\-\-\-\- 1 15\-\-\-\-16 \& \e \e \& 41\-\-\-\-40 44 5\-\-\-\- 6 64\-\-\-\-63 \& \e / / \e \& 42\-\-\-\-43 55\-\-\-\-54 65 60 62 \& / \e \e \e / \& 56 50 53 66 61 \& / / \& 51\-\-\-\-52 .Ve .PP Notice this means in each part the 11, 21, 31, etc, points are directed away from the middle in the same way, relative to the sub-part locations. .PP Working through the expansions gives the following rule for when an N is on the boundary of level k, .PP .Vb 5 \& write N in k many base\-7 digits (empty string if k=0) \& if any 0 digit then non\-boundary \& ignore high digit and all 1 digits \& if any 4 or 5 digit then non\-boundary \& if any 32, 33, 66 pair then non\-boundary .Ve .PP A 0 digit is the middle of a block, or 4 or 5 digit the inner side of a block, for k>=1, hence non-boundary. After that the 6,1,2,3 parts variously expand with rotations so that a 66 is enclosed on the clockwise side and 32 and 33 on the anti-clockwise side. .SH "FUNCTIONS" .IX Header "FUNCTIONS" See \*(L"\s-1FUNCTIONS\*(R"\s0 in Math::PlanePath for behaviour common to all path classes. .ie n .IP """$path = Math::PlanePath::GosperReplicate\->new ()""" 4 .el .IP "\f(CW$path = Math::PlanePath::GosperReplicate\->new ()\fR" 4 .IX Item "$path = Math::PlanePath::GosperReplicate->new ()" .PD 0 .ie n .IP """$path = Math::PlanePath::GosperReplicate\->new (numbering_type => $str)""" 4 .el .IP "\f(CW$path = Math::PlanePath::GosperReplicate\->new (numbering_type => $str)\fR" 4 .IX Item "$path = Math::PlanePath::GosperReplicate->new (numbering_type => $str)" .PD Create and return a new path object. The \f(CW\*(C`numbering_type\*(C'\fR parameter can be .Sp .Vb 2 \& "fixed" (default) \& "rotate" .Ve .ie n .IP """($x,$y) = $path\->n_to_xy ($n)""" 4 .el .IP "\f(CW($x,$y) = $path\->n_to_xy ($n)\fR" 4 .IX Item "($x,$y) = $path->n_to_xy ($n)" Return the X,Y coordinates of point number \f(CW$n\fR on the path. Points begin at 0 and if \f(CW\*(C`$n < 0\*(C'\fR then the return is an empty list. .SS "Level Methods" .IX Subsection "Level Methods" .ie n .IP """($n_lo, $n_hi) = $path\->level_to_n_range($level)""" 4 .el .IP "\f(CW($n_lo, $n_hi) = $path\->level_to_n_range($level)\fR" 4 .IX Item "($n_lo, $n_hi) = $path->level_to_n_range($level)" Return \f(CW\*(C`(0, 7**$level \- 1)\*(C'\fR. .SH "FORMULAS" .IX Header "FORMULAS" .SS "Axis Rotations" .IX Subsection "Axis Rotations" In the fixed numbering, digit positions 1,2,3,4,5,6 go around +60deg each, so the N for rotation of X,Y by +60 degrees is each digit +1. .PP .Vb 1 \& N = 0, 1, 2, 3, 4, 5, 6, 10, 11, 12 \& \& rot+60(N) = 0, 2, 3, 4, 5, 6, 1, 14, 16, 17, ... decimal \& = 0, 2, 3, 4, 5, 6, 1, 20, 22, 23, ... base7 \& \& rot+120(N) = 0, 3, 4, 5, 6, 1, 2, 21, 24, 25, ... decimal \& = 0, 3, 4, 5, 6, 1, 2, 30, 33, 34, ... base7 \& \& etc .Ve .PP In the rotate numbering, just adding +1 (etc) at the high digit alone is rotation. .SS "X,Y Extents" .IX Subsection "X,Y Extents" The maximum X in a given level N=0 to 7^k\-1 can be calculated from the replications. A given high digit 1 to 6 has sub-parts located at b^k*w6^(d\-1). Those sub-parts are all the same, so the one with maximum real(b^k*w6^(d\-1)) contains the maximum X. .PP .Vb 2 \& N_xmax_digit(j) = d=1to6 where real(w6^(d\-1) * b^j) is maximum \& = 1,1,6,6,6,5,5,5,4,4,4,3,3,3,3,2,2, ... \& \& k\-1 \& N_xmax(k) = digits N_xmax_digit(j) low digit j=0 \& j=0 \& = 0, 1, 8, 302, 2360, 16766, 100801, ... decimal \& = 0, 1, 11, 611, 6611, 66611, 566611, ... base7 \& \& k\-1 \& z_xmax(k) = sum w6^d[j] * b^j \& j=0 each d[j] with real(w6^d[j] * b^j) maximum \& = 0, 1, 7/2+1/2*sqrt3*i, 10\-sqrt3*i, 57/2\-3/2*sqrt3*i,... \& \& xmax(k) = 2*real(z_xmax(k)) \& = 0, 2, 7, 20, 57, 151, 387, 1070, 2833, 7106, ... .Ve .PP For computer calculation these maximums can be calculated from the powers. The parts resulting can also be written in terms of the angle .PP .Vb 1 \& arg(b) = atan(sqrt(3)/5) = 19.106... degrees .Ve .PP For successive k, if adding this pushes the b^k angle past +30deg then the preceding digit goes past \-30deg and becomes the new maximum X. Write the angle as a fraction of 60deg (pi/3), .PP .Vb 1 \& F = atan(sqrt(3)/5) / (pi/3) = 0.318443 ... .Ve .PP This is irrational since b^k is never on the X or Y axes. That can be seen since 2/sqrt3*imag(b^k) mod 7 goes in a repeating pattern 1,5,4,6,2,3. Similarly 2*real(b^k) mod 7 so not on the Y axis, and also anything on the Y axis would have 3*k fall on the X axis. .PP Digits low to high are successive steps back cyclically 6,5,4,3,2,1 so that (with mod giving 0 to 5), .PP .Vb 1 \& N_xmax_digit(j) = (\-floor(F*j+1/2) mod 6) + 1 .Ve .PP The +1/2 is since initial direction b^0=1 is angle 0 which is half way between \-30 and +30 deg. .PP Similarly for the location, using conj(w6) for rotation back .PP .Vb 3 \& z_xmax_exp(j) = floor(F*j+1/2) \& = 0,0,1,1,1,2,2,2,3,3,3,4,4,4,4,5,5,5, ... \& z_xmax(k) = sum(j=0,k\-1, conj(w6)^z_xmax_exp(j) * b^j) .Ve .PP By symmetry the maximum extent is the same in 60deg, 120deg, etc directions, suitably rotated. The N in those cases has the digits 1,2,3,4,5,6 cycled around for the rotation. In PlanePath triangular X,Y coordinates direction 60deg means when sum X+3*Y is a maximum, etc. .PP If the +1/2 in the floor is omitted then the effect is to find the maximum point in direction +30deg. In the PlanePath coordinates this means maximum sum S = X+Y. .PP .Vb 2 \& N_smax_digit(j) = (\-floor(F*j) mod 6) + 1 \& = 1,1,1,1,6,6,6,5,5,5,4,4,4,3,3, ... \& \& k\-1 \& N_smax(k) = digits N_smax_digit(j) low digit j=0 \& j=0 \& = 0, 1, 8, 57, 400, 14806, 115648, ... decimal \& = 0, 1, 11, 111, 1111, 61111, 661111, ... base7 \& and also N_smax() + 1 \& \& z_smax_exp(j) = floor(F*j) \& = 0,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6, ... \& z_smax(k) = sum(j=0,k\-1, conj(w6)^z_smax_exp(j) * b^j) \& = 0, 1, 7/2+1/2*sqrt3*i, 9+3*sqrt3*i, 19+12*sqrt3*i, ... \& and also z_smax() + w6^2 \& \& smax(k) = 2*real(z_smax(k)) + imag(z_smax(k))*2/sqrt3 \& = 0, 2, 8, 24, 62, 172, 470, 1190, 3202, 8740, ... \& coordinate sum X+Y max .Ve .PP In the base figure, points 1 and 2 have the same X+Y=2 and this remains so in subsequent levels, so that for k>=1 N_smax(k) and N_smax(k)+1 are equal maximums. .SH "SEE ALSO" .IX Header "SEE ALSO" Math::PlanePath, Math::PlanePath::GosperIslands, Math::PlanePath::Flowsnake, Math::PlanePath::FlowsnakeCentres, Math::PlanePath::QuintetReplicate, Math::PlanePath::ComplexPlus .SH "HOME PAGE" .IX Header "HOME PAGE" .SH "LICENSE" .IX Header "LICENSE" Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Kevin Ryde .PP This file is part of Math-PlanePath. .PP Math-PlanePath is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. .PP Math-PlanePath is distributed in the hope that it will be useful, but \&\s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of \s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 See the \s-1GNU\s0 General Public License for more details. .PP You should have received a copy of the \s-1GNU\s0 General Public License along with Math-PlanePath. If not, see .