NAME
Math::PlanePath::SierpinskiCurveStair  Sierpinski curve with stairstep diagonals
SYNOPSIS
use Math::PlanePath::SierpinskiCurveStair;
my $path = Math::PlanePath::SierpinskiCurveStair>new (arms => 2);
my ($x, $y) = $path>n_to_xy (123);
DESCRIPTION
This is a variation on the SierpinskiCurve
with stairstep diagonal parts.
10  5253
  
9  5051 5455
  
8  4948 5756
  
7  4243 4647 5859 6263
      
6  4041 4445 6061 6465
  
5  3938 3534 7170 6766
      
4  1213 3736 3332 7372 6968 9293
      
3  1011 1415 3031 7475 9091 9495
      
2  98 1716 2928 7776 8988 9796
      
1  23 67 1819 2223 2627 7879 8283 8687 9899
            
Y=0  01 45 2021 2425 8081 8485 ...

+
^
X=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
The tiling is the same as the SierpinskiCurve
, but each diagonal is a stair step horizontal and vertical. The correspondence is
SierpinskiCurve SierpinskiCurveStair
7 12
/ 
6 1011
 
5 98
\ 
12 4 23 67
/ \ /   
0 3 01 45
The SierpinskiCurve
N=0 to N=3 corresponds to N=0 to N=5 here. N=7 to N=12 which is a copy of the N=0 to N=5 base. Point N=6 is an extra in between the parts. The next such extra is N=19.
Diagonal Length
The diagonal_length
option can make longer diagonals, still in stairstep style. For example
diagonal_length => 4
10  3637
  
9  3435 3839
  
8  3233 4041
  
7  3031 4243
  
6  2829 4445
  
5  2726 4746
  
4  89 2524 4948 ...
     
3  67 1011 2322 5150 6263
     
2  45 1213 2120 5352 6061
     
1  23 1415 1819 5455 5859
     
Y=0  01 1617 5657

+
^
X=0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
The length is reckoned from N=0 to the end of the first side N=8, which is X=1 to X=5 for length 4 units.
Arms
The optional arms
parameter can give up to eight copies of the curve, each advancing successively. For example
arms => 8
9890 6658 5765 8997 5
     
99 8274 5042 4149 7381 96 4
   
9183 2634 3325 8088 3
   
6775 1810 917 7264 2
   
5951 2719 2 1 1624 4856 1
     
4335 113 . 08 3240 < Y=0
4436 124 715 3947 1
     
6052 2820 5 6 2331 5563 2
   
6876 2113 1422 7971 3
   
9284 2937 3830 8795 4
 
8577 5345 4654 7886 5
     
93 6961 6270 94 6
^
6 5 4 3 2 1 X=0 1 2 3 4 5 6
The multiples of 8 (or however many arms) N=0,8,16,etc is the original curve, and the further mod 8 parts are the copies.
The middle "." shown is the origin X=0,Y=0. It would be more symmetrical to have the origin the middle of the eight arms, which would be X=0.5,Y=0.5 in the above, but that would give fractional X,Y values. Apply an offset X+0.5,Y+0.5 to centre if desired.
Level Ranges
The N=0 point is reckoned as level=0, then N=0 to N=5 inclusive is level=1, etc. Each level is 4 copies of the previous and an extra 2 points between.
LevelPoints[k] = 4*LevelPoints[k1] + 2 starting LevelPoints[0]=1
= 2 + 2*4 + 2*4^2 + ... + 2*4^(k1) + 1*4^k
= (5*4^k  2)/3
Nlevel[k] = LevelPoints[k]  1 since starting at N=0
= 5*(4^k  1)/3
= 0, 5, 25, 105, 425, 1705, 6825, 27305, ... (A146882)
The width along the X axis of a level doubles each time, plus an extra distance 3 between.
LevelWidth[k] = 2*LevelWidth[k1] + 3 starting LevelWidth[0]=0
= 3 + 3*2 + 3*2^2 + ... + 3*2^(k1) + 0*2^k
= 3*(2^k  1)
Xlevel[k] = 1 + LevelWidth[k]
= 3*2^k  2
= 1, 4, 10, 22, 46, 94, 190, 382, ... (A033484)
Level Ranges with Diagonal Length
With diagonal_length
= L, level=0 is reckoned as having L many points instead of just 1.
LevelPoints[k] = 2 + 2*4 + 2*4^2 + ... + 2*4^(k1) + L*4^k
= ( (3L+2)*4^k  2 )/3
Nlevel[k] = LevelPoints[k]  1
= ( (3L+2)*4^k  5 )/3
The width of level=0 becomes L1 instead of 0.
LevelWidth[k] = 2*LevelWidth[k1] + 3 starting LevelWidth[0]=L1
= 3 + 3*2 + 3*2^2 + ... + 3*2^(k1) + (L1)*2^k
= (L+2)*2^k  3
Xlevel[k] = 1 + LevelWidth[k]
= (L+2)*2^k  2
Level=0 as L many points can be thought of as a little block which is replicated in mirror image to make level=1. For example the diagonal 4 example above becomes
8 9 diagonal_length => 4
 
67 1011
 
. 5 12 .
23 1415
 
01 1617
The spacing between the parts is had in the tiling by taking a margin of 1/2 at the base and 1 horizontally left and right.
Level Fill
The curve doesn't visit all the points in the eighth of the plane below the X=Y diagonal. In general Nlevel+1 many points of the triangular area Xlevel^2/4 are visited, for a filled fraction which approaches a constant
Nlevel 4*(3L+2)
FillFrac =  > 
Xlevel^2 / 4 3*(L+2)^2
For example the default L=1 has FillFrac=20/27=0.74. Or L=2 FillFrac=2/3=0.66. As the diagonal length increases the fraction decreases due to the growing holes in the pattern.
FUNCTIONS
See "FUNCTIONS" in Math::PlanePath for the behaviour common to all path classes.
$path = Math::PlanePath::SierpinskiCurveStair>new ()
$path = Math::PlanePath::SierpinskiCurveStair>new (diagonal_length => $L, arms => $A)

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 0 and if$n < 0
then the return is an empty list.Fractional positions give an X,Y position along a straight line between the integer positions.
$n = $path>n_start()

Return 0, the first N in the path.
Level Methods
($n_lo, $n_hi) = $path>level_to_n_range($level)

Return
(0, ((3*$diagonal_length +2) * 4**$level  5)/3
as per "Level Ranges with Diagonal Length" above.
OEIS
Entries in Sloane's Online Encyclopedia of Integer Sequences related to this path include
http://oeis.org/A146882 (etc)
A146882 Nlevel, for level=1 up
A033484 Xmax and Ymax in level, being 3*2^n  2
SEE ALSO
Math::PlanePath, Math::PlanePath::SierpinskiCurve
HOME PAGE
http://user42.tuxfamily.org/mathplanepath/index.html
LICENSE
Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Kevin Ryde
MathPlanePath 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.
MathPlanePath 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 MathPlanePath. If not, see <http://www.gnu.org/licenses/>.