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

NAME

       Math::PlanePath::TriangularHypot -- points of triangular lattice in order of hypotenuse
       distance

SYNOPSIS

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

DESCRIPTION

       This path visits X,Y points on a triangular "A2" lattice in order of their distance from
       the origin 0,0 and anti-clockwise around from the X axis among those of equal distance.

                    58    47    39    46    57                 4

                 48    34    23    22    33    45              3

              40    24    16     9    15    21    38           2

           49    25    10     4     3     8    20    44        1

              35    17     5     1     2    14    32      <- Y=0

           50    26    11     6     7    13    31    55       -1

              41    27    18    12    19    30    43          -2

                 51    36    28    29    37    54             -3

                    60    52    42    53    61                -4

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

       The lattice is put on a square X,Y grid using every second point per "Triangular Lattice"
       in Math::PlanePath.  Scaling X/2,Y*sqrt(3)/2 gives equilateral triangles of side length 1
       making a distance from X,Y to the origin

           dist^2 = (X/2^2 + (Y*sqrt(3)/2)^2
                  = (X^2 + 3*Y^2) / 4

       For example N=19 at X=2,Y=-2 is sqrt((2**2+3*-2**2)/4) = sqrt(4) from the origin.  The
       next smallest after that is X=5,Y=1 at sqrt(7).  The key part is X^2 + 3*Y^2 as the
       distance measure to order the points.

   Equal Distances
       Points with the same distance are taken in anti-clockwise order around from the X axis.
       For example N=14 at X=4,Y=0 is sqrt(4) from the origin, and so are the rotated X=2,Y=2 and
       X=-2,Y=2 etc in other sixth segments, for a total 6 points N=14 to N=19 all the same
       distance.

       Symmetry means there's a set of 6 or 12 points with the same distance, so the count of
       same-distance points is always a multiple of 6 or 12.  There are 6 symmetric points when
       on the six radial lines X=0, X=Y or X=-Y, and on the lines Y=0, X=3*Y or X=-3*Y which are
       midway between them.  There's 12 symmetric points for anything else, ie. anything in the
       twelve slices between those twelve lines.  The first set of 12 equal is N=20 to N=31 all
       at sqrt(28).

       There can also be further ways for the same distance to arise, as multiple solutions to
       X^2+3*Y^3=d^2, but the 6-way or 12-way symmetry means there's always a multiple of 6 or 12
       in total.

   Odd Points
       Option "points => "odd"" visits just the odd points, meaning sum X+Y odd, which is X,Y one
       odd the other even.

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

                                 ^
              -6 -5 -4 -3 -2 -1 X=0 1  2  3  4  5  6

   All Points
       Option "points => "all"" visits all integer X,Y points.

           points => "all"

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

                                 ^
              -6 -5 -4 -3 -2 -1 X=0 1  2  3  4  5  6

   Hex Points
       Option "points => "hex"" visits X,Y points making a hexagonal grid,

           points => "hex"

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

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

       N=1 is at the origin X=0,Y=0, then N=2,3,4 are all at X^2+3Y^2=4 away from the origin,
       etc.  The joining lines drawn above show the grid pattern but points are in order of
       distance from the origin.

       The points are all integer X,Y with X+3Y mod 6 == 0 or 2.  This is a subset of the default
       "even" points in that X+Y is even but with 1 of each 3 points skipped to make the
       hexagonal outline.

   Hex Rotated Points
       Option "points => "hex_rotated"" is the same hexagonal points but rotated around so N=2 is
       at +60 degrees instead of on the X axis.

           points => "hex_rotated"

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

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

       Points are still numbered from the X axis clockwise.  The sets of points at equal
       hypotenuse distances are the same as plain "hex" but the numbering is changed by the
       rotation.

       The points visited are all integer X,Y with X+3Y mod 6 == 0 or 4.  This grid can be viewed
       either as a +60 degree or a +180 degree rotation of the plain hex.

   Hex Centred Points
       Option "points => "hex_centred"" is the same hexagonal grid as hex above, but with the
       origin X=0,Y=0 in the centre of a hexagon,

           points => "hex_centred"

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

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

       N=1,2,3,4,5,6 are all at X^2+3Y^2=4 away from the origin, then N=7,8,9,10,11,12, etc.  The
       points visited are all integer X,Y with X+3Y mod 6 == 2 or 4.

FUNCTIONS

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

       "$path = Math::PlanePath::TriangularHypot->new ()"
       "$path = Math::PlanePath::TriangularHypot->new (points => $str)"
           Create and return a new hypot path object.  The "points" option can be

               "even"          only points with X+Y even (the default)
               "odd"           only points with X+Y odd
               "all"           all integer X,Y
               "hex"           hexagonal X+3Y==0,2 mod 6
               "hex_rotated"   hexagonal X+3Y==0,4 mod 6
               "hex_centred"   hexagonal X+3Y==2,4 mod 6

           Create and return a new triangular hypot path object.

       "($x,$y) = $path->n_to_xy ($n)"
           Return the X,Y coordinates of point number $n on the path.

           For "$n < 1" the return is an empty list as the first point at X=0,Y=0 is N=1.

           Currently it's unspecified what happens if $n is not an integer.  Successive points
           are a fair way apart, so it may not make much sense to say give an X,Y position in
           between the integer $n.

       "$n = $path->xy_to_n ($x,$y)"
           Return an integer point number for coordinates "$x,$y".  Each integer N is considered
           the centre of a unit square and an "$x,$y" within that square returns N.

           For "even" and "odd" options only every second square in the plane has an N and if
           "$x,$y" is a position not covered then the return is "undef".

OEIS

       Entries in Sloane's Online Encyclopedia of Integer Sequences related to this path include,

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

           points="even" (the default)
             A003136  norms (X^2+3*Y^2)/4 which occur
             A004016  count of points of norm==n
             A035019    skipping zero counts
             A088534    counting only in the twelfth 0<=X<=Y

       The counts in these sequences are expressed as norm = x^2+x*y+y^2.  That x,y is related to
       the "even" X,Y on the path here by a -45 degree rotation,

           x = (Y-X)/2           X = 2*(x+y)
           y = (X+Y)/2           Y = 2*(y-x)

           norm = x^2+x*y+y^2
                = ((Y-X)/2)^2 + (Y-X)/2 * (X+Y)/2 + ((X+Y)/2)^2
                = (X^2 + 3*Y^2) / 4

       The X^2+3*Y^2 is the dist^2 described above for equilateral triangles of unit side.  The
       factor of /4 scales the distance but of course doesn't change the sets of points of the
       same distance.

           points="all"
             A092572  norms X^2+3*Y^2 which occur
             A158937  norms X^2+3*Y^2 which occur, X>0,Y>0 with repeats
             A092573  count of points norm==n for X>0,Y>0

             A092574  norms X^2+3*Y^2 which occur for X>0,Y>0, gcd(X,Y)=1
             A092575  count of points norm==n for X>0,Y>0, gcd(X,Y)=1
                        ie. X,Y no common factor

           points="hex"
             A113062  count of points norm=X^2+3*Y^2=4*n (theta series)
             A113063   divided by 3

           points="hex_centred"
             A217219  count of points norm=X^2+3*Y^2=4*n (theta series)

SEE ALSO

       Math::PlanePath, Math::PlanePath::Hypot, Math::PlanePath::HypotOctant,
       Math::PlanePath::PixelRings, Math::PlanePath::HexSpiral

HOME PAGE

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

LICENSE

       Copyright 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Kevin Ryde

       This file is part of Math-PlanePath.

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