SYNOPSIS
use Math::PlanePath::GosperIslands;
my $path = Math::PlanePath::GosperIslands->new;
my ($x, $y) = $path->n_to_xy (123);
DESCRIPTION
This path is integer versions of the Gosper island at successive levels, arranged as concentric rings on a triangular lattice (see ``Triangular Lattice'' in Math::PlanePath). Each island is the outline of a self-similar tiling of the plane by hexagons, and the sides are self-similar expansions of line segments
35----34 8 / \ ..-36 33----32 29----28 7 \ / \ 31----30 27----26 6 \ 25 5 78 4 \ 11-----10 77 3 / \ / 13----12 9---- 8 76 2 / \ \ 14 3---- 2 7 ... 1 \ / \ 15 4 1 24 <- Y=0 / \ \ 16 5----- 6 23 -1 \ / 17----18 21----22 -2 \ / 19----20 -3 -5 -4 -3 -2 -1 X=0 1 2 3 4 5 6 7 8 9 10 11
Hexagon Replications
The islands can be thought of as a self-similar tiling of the plane by hexagonal shapes. The innermost hexagon N=1 to N=6 is replicated six times to make the next outline N=7 to N=24.
*---* / \ *---* *---* / \ / \ * *---* * \ / \ / *---* *---* / \ / \ * *---* * \ / \ / *---* *---* \ / *---*
Then that shape is in turn replicated six times around itself to make the next level.
*---E / \ *---* *---* *---* / \ / \ * *---* *---* \ / \ * * D / \ / *---* * * / \ / \ *---* *---* *---* * / \ / \ / * *---* *---* *---* \ / \ / \ * * C---* *---* / \ / \ * * O * * \ / \ / *---* *---* * * \ / \ / \ *---* *---* *---* * / \ / \ / * *---* *---* *---* \ / \ / * * *---* / \ / * * * \ / \ *---* *---* * \ / \ / *---* *---* *---* \ / *---*
The shapes here and at higher level are like hexagons with wiggly sides. The sides are symmetric, so they mate on opposite sides but the join ``corner'' is not on the X axis (after the first level). For example the point marked ``C'' (N=7) is above the axis at X=5,Y=1. The next replication joins at point ``D'' (N=25) at X=11,Y=5.
Side and Radial Lines
The sides at each level is a self-similar line segment expansion,
*---* *---* becomes / *---*
This expanding side shape is also the radial line or spoke from the origin out to ``corner'' join points. At level 0 they're straight lines,
...----* / \ / \ side / \ / \ O---------* / /
Then at higher levels they're wiggly, such as level 1,
...--* / \ * *---* \ \ * *---C / / / O---* ...
Or level 2,
*---E ... / \ * *---* *---* \ \ / \ * *---* *---* / \ * *---D \ / / *---* *---* ... \ / * * / \ * * \ / * *---C / / O---*
The lines become ever wigglier at higher levels, and in fact become ``S'' shapes with the ends spiralling around and in (and in fact middle sections likewise S and spiralling, to a lesser extent).
The spiralling means that the X axis is crossed multiple times at higher levels. For example in level 11 X>0,Y=0 occurs 22 times between N=965221 and N=982146. Likewise on diagonal lines X=Y and X=-Y which are ``sixths'' of the initial hexagon.
The self-similar spiralling means the Y axis too is crossed multiple times at higher levels. In level 11 again X=0,Y>0 is crossed 7 times between N=1233212 and N=1236579. (Those N's are bigger than the X axis crossing, because the Nstart position at level 11 has rotated around some 210 degrees to just under the negative X axis.)
In general any radial straight line is crossed many times way eventually.
Level Ranges
Counting the inner hexagon as level=0, the side length and whole ring is
sidelen = 3^level ringlen = 6 * 3^level
The starting N for each level is the total points preceding it, so
Nstart = 1 + ringlen(0) + ... + ringlen(level-1) = 3^(level+1) - 2
For example level=2 starts at Nstart=3^3-2=25.
The way the side/radial lines expand as described above makes the Nstart position rotate around at each level. N=7 is at X=5,Y=1 which is angle
angle = arctan(1*sqrt(3) / 5) = 19.106.. degrees
The sqrt(3) factor as usual turns the flattened integer X,Y coordinates into proper equilateral triangles. The further levels are then multiples of that angle. For example N=25 at X=11,Y=5 is 2*angle, or N=79 at X=20,Y=18 at 3*angle.
The N=7 which is the first radial replication at X=5,Y=1, scaled to unit sided equilateral triangles, has distance from the origin
d1 = hypot(5, 1*sqrt(3)) / 2 = sqrt(7)
The subsequent levels are powers of that sqrt(7),
Xstart,Ystart of the Nstart(level) position d = hypot(Xstart,Ystart*sqrt(3))/2 = sqrt(7) ^ level
This multiple of the angle and powering of the radius means the Nstart points are on a logarithmic spiral.
Fractal Island
The Gosper island is usually conceived as a fractal, with the initial hexagon in a fixed position and the sides having the line segment substitution described above, for ever finer levels of ``S'' spiralling wiggliness. The code here can be used for that by rotating the Nstart position back to the X axis and scaling down to a desired unit radius.
Xstart,Ystart of the Nstart(level) position scale factor = 0.5 / hypot(Ystart*sqrt(3), Xstart) rotate angle = - atan2 (Ystart*sqrt(3), Xstart)
This scale and rotate puts the Nstart point at X=1,Y=0 and further points of the ring around from that. Remember the sqrt(3) factor on Y for all points to turn the integer coordinates into proper equilateral triangles.
Notice the line segment substitution doesn't change the area of the initial hexagon. Effectively (and not to scale),
* / \ *-------* becomes * / * \ / *
So the area lost below is gained above (or vice versa). The result is a line of ever greater length enclosing an unchanging area.
FUNCTIONS
See ``FUNCTIONS'' in Math::PlanePath for behaviour common to all path classes.- "$path = Math::PlanePath::GosperIslands->new ()"
- Create and return a new path object.
- "($x,$y) = $path->n_to_xy ($n)"
- Return the X,Y coordinates of point number $n on the path. Points begin at 1 and if "$n < 0" then the return is an empty list.
LICENSE
Copyright 2011, 2012, 2013, 2014, 2015, 2016 Kevin RydeMath-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/>.