logo
Free, unlimited AI code reviews that run on commit
git-lrc git-lrc GitHub Install Now We'd appreciate a star git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

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

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.

   TriangularCoordinates
       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.

   LevelRanges
       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.

Formulas

RectangletoNRange
       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

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.

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

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

Home Page

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/>.

perl v5.32.0                                       2021-01-23               Math::PlanePath::KochSnowflakes(3pm)

Name

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

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

Synopsis

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

See Also