Provided by: libmath-planepath-perl_125-1_all bug

NAME

       Math::PlanePath::KochSnowflakes -- Koch snowflakes as concentric rings

SYNOPSIS

        use Math::PlanePath::KochSnowflakes;
        my $path = Math::PlanePath::KochSnowflakes->new;
        my ($x, $y) = $path->n_to_xy (123);

DESCRIPTION

       This path traces out concentric integer versions of the Koch snowflake at successively greater iteration
       levels.

                                      48                                6
                                     /  \
                             50----49    47----46                       5
                               \              /
                    54          51          45          42              4
                   /  \        /              \        /  \
           56----55    53----52                44----43    41----40     3
             \                                                  /
              57                      12                      39        2
             /                       /  \                       \
           58----59          14----13    11----10          37----38     1
                   \           \       3      /           /
                    60          15  1----2   9          36         <- Y=0
                   /                          \           \
           62----61           4---- 5    7---- 8           35----34    -1
             \                       \  /                       /
              63                       6                      33       -2
                                                                \
           16----17    19----20                28----29    31----32    -3
                   \  /        \              /        \  /
                    18          21          27          30             -4
                               /              \
                             22----23    25----26                      -5
                                     \  /
                                      24                               -6

                                       ^
           -9 -8 -7 -6 -5 -4 -3 -2 -1 X=0 1  2  3  4  5  6  7  8  9

       The initial figure is the triangle N=1,2,3 then for the next level each straight side expands to 3x
       longer and a notch like N=4 through N=8,

             *---*     becomes     *---*   *---*
                                        \ /
                                         *

       The angle is maintained in each replacement, for example the segment N=5 to N=6 becomes N=20 to N=24 at
       the next level.

   Triangular Coordinates
       The X,Y coordinates are arranged as integers on a square grid per "Triangular Lattice" in
       Math::PlanePath, except the Y coordinates of the innermost triangle which is

                         N=3     X=0, Y=+2/3
                          *
                         / \
                        /   \
                       /     \
                      /   o   \
                     /         \
                N=1 *-----------* N=2
           X=-1, Y=-1/3      X=1, Y=-1/3

       These values are not integers, but they're consistent with the centring and scaling of the higher levels.
       If all-integer is desired then rounding gives Y=0 or Y=1 and doesn't overlap the subsequent points.

   Level Ranges
       Counting the innermost triangle as level 0, each ring is

           Nstart = 4^level
           length = 3*4^level    many points

       For example the outer ring shown above is level 2 starting N=4^2=16 and having length=3*4^2=48 points
       (through to N=63 inclusive).

       The X range at a given level is the initial triangle baseline iterated out.  Each level expands the sides
       by a factor of 3 so

            Xlo = -(3^level)
            Xhi = +(3^level)

       For example level 2 above runs from X=-9 to X=+9.  The Y range is the points N=6 and N=12 iterated out.
       Ylo in level 0 since there's no downward notch on that innermost triangle.

           Ylo = / -(2/3)*3^level if level >= 1
                 \ -1/3           if level == 0
           Yhi = +(2/3)*3^level

       Notice that for each level the extents grow by a factor of 3 but the notch introduced in each segment is
       not big enough to go past the corner positions.  They can equal the extents horizontally, for example in
       level 1 N=14 is at X=-3 the same as the corner N=4, and on the right N=10 at X=+3 the same as N=8, but
       they don't go past.

       The snowflake is an example of a fractal curve with ever finer structure.  The code here can be used for
       that by going from N=Nstart to N=Nstart+length-1 and scaling X/3^level Y/3^level to give a 2-wide 1-high
       figure of desired fineness.  See examples/koch-svg.pl for a complete program doing that as an SVG image
       file.

   Area
       The area of the snowflake at a given level can be calculated from the area under the Koch curve per
       "Area" in Math::PlanePath::KochCurve which is the 3 sides, and the central triangle

                        *          ^ Yhi
                       / \         |          height = 3^level
                      /   \        |
                     /     \       |
                    *-------*      v

                    <------->      width = 3^level - (- 3^level) = 2*3^level
                   Xlo      Xhi

           triangle_area = width*height/2 = 9^level

           snowflake_area[level] = triangle_area[level] + 3*curve_area[level]
                                 = 9^level + 3*(9^level - 4^level)/5
                                 = (8*9^level - 3*4^level) / 5

       If the snowflake is conceived as a fractal of fixed initial triangle size and ever-smaller notches then
       the area is divided by that central triangle area 9^level,

           unit_snowflake[level] = snowflake_area[level] / 9^level
                                 = (8 - 3*(4/9)^level) / 5
                                 -> 8/5      as level -> infinity

       Which is the well-known 8/5 * initial triangle area for the fractal snowflake.

FUNCTIONS

       See "FUNCTIONS" in Math::PlanePath for behaviour common to all path classes.

       "$path = Math::PlanePath::KochSnowflakes->new ()"
           Create and return a new path object.

   Level Methods
       "($n_lo, $n_hi) = $path->level_to_n_range($level)"
           Return per "Level Ranges" above,

               (4**$level,
                4**($level+1) - 1)

FORMULAS

   Rectangle to N Range
       As noted in "Level Ranges" above, for a given level

                 -(3^level) <= X <= 3^level
           -(2/3)*(3^level) <= Y <= (2/3)*(3^level)

       So the maximum X,Y in a rectangle gives

           level = ceil(log3(max(abs(x1), abs(x2), abs(y1)*3/2, abs(y2)*3/2)))

       and the last point in that level is

           Nlevel = 4^(level+1) - 1

       Using this as an N range is an over-estimate, but an easy calculation.  It's not too difficult to trace
       down for an exact range

OEIS

       Entries in Sloane's Online Encyclopedia of Integer Sequences related to the Koch snowflake include the
       following.  See "OEIS" in Math::PlanePath::KochCurve for entries related to a single Koch side.

           <http://oeis.org/A164346> (etc)

           A164346   number of points in ring n, being 3*4^n
           A178789   number of acute angles in ring n, 4^n + 2
           A002446   number of obtuse angles in ring n, 2*4^n - 2

       The acute angles are those of +/-120 degrees and the obtuse ones +/-240 degrees.  Eg. in the outer ring=2
       shown above the acute angles are at N=18, 22, 24, 26, etc.  The angles are all either acute or obtuse, so
       A178789 + A002446 = A164346.

SEE ALSO

       Math::PlanePath, Math::PlanePath::KochCurve, Math::PlanePath::KochPeaks

       Math::PlanePath::QuadricIslands

HOME PAGE

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

LICENSE

       Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 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/>.