Math::...rHypot(3pm)

πŸ“¦
version 129 Β· 3 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸ’– Math::PlanePath::TriangularHypot πŸ’–

okay bestie, quick vibe check: this is a Perl man page from the User Contributed Perl Documentation. The header calls it Math::...rHypot(3pm) but the actual module is Math::PlanePath::TriangularHypot, and it is so much cooler than that name makes it sound. We're doing triangular lattice points ordered by hypotenuse distance and honestly? iconic. πŸ’…


✨ NAME ✨

Math::PlanePath::TriangularHypot β€” points of triangular lattice in order of hypotenuse distance. periodt. πŸŽ€

✨ SYNOPSIS ✨

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

✨ DESCRIPTION ✨

So here's the whole thing, bestie: this path visits X,Y points on a triangular "A2" lattice in order of how far they are from the origin 0,0, and then, among all the points that are the exact same distance away, it goes anti-clockwise around starting from the X axis. main character energy fr. 🌸

                 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 gets plopped onto a square X,Y grid using every second point per "Triangular Lattice" in Math::PlanePath. Scale things by X/2,Y*sqrt(3)/2 and you get equilateral triangles of side length 1, which makes the distance from X,Y to the origin be:

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

Example time ✨ β€” 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, the whole moment, is X^2 + 3*Y^2 as the distance measure used to order the points. πŸ’œ

πŸŒ€ Equal Distances πŸŒ€

Points with the same distance get 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 the other sixth segments β€” so that's a total of 6 points, N=14 to N=19, all the same distance. 🎯

Because of symmetry there's always a set of 6 or 12 points at the same distance, so the count of same-distance points is always a multiple of 6 or 12. You get 6 symmetric points when you're on the six radial lines X=0, X=Y or X=-Y, and also on the lines Y=0, X=3*Y or X=-3*Y which sit midway between them. You get 12 symmetric points for anything else, i.e. anything in the twelve slices between those twelve lines. The very 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 show up, as multiple solutions to X^2+3*Y^3=d^2, but the 6-way or 12-way symmetry means the total is always a multiple of 6 or 12. no cap.

🌈 Odd Points 🌈

Option points => "odd" visits just the odd points β€” meaning sum X+Y odd, so X,Y with one odd and 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. every single one, we're thorough like that πŸ’–

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 that make a hexagonal grid. it's giving honeycomb, it's giving geometry, we love her 🫢

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 the points themselves are in order of distance from the origin. don't get it twisted. ⭐

The points visited 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 so you get that hexagonal outline. πŸ’…

🌸 Hex Rotated Points 🌸

Option points => "hex_rotated" is the same hexagonal points, just rotated around so that N=2 is at +60 degrees instead of sitting on the X axis. a lil spin, a lil twist, we love a glow-up ✨

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. cute right? πŸŽ€

🧚 Hex Centred Points 🧚

Option points => "hex_centred" is the same hexagonal grid as hex above, except the origin X=0,Y=0 sits in the centre of a hexagon instead. centred, as she deserves. πŸ‘‘

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. πŸ’œ


bestie this is only part 1 of 2 β€” there's more of this page coming, don't go anywhere πŸ’–

✨ FUNCTIONS ✨

Okay so first thing bestie, hit up "FUNCTIONS" in Math::PlanePath for all the behaviour that every path class shares, because this page only spills the tea about the stuff that's special to TriangularHypot. πŸ’–

  • $path = Math::PlanePath::TriangularHypot->new ()
  • $path = Math::PlanePath::TriangularHypot->new (points => $str) β€” makes you a brand new hypot path object and hands it over. The points option can be any of these little icons:
"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. πŸŽ€ (yes that's the whole vibe, it literally just builds the thing and gives it to you)

  • ($x,$y) = $path->n_to_xy ($n) β€” gimme the X,Y coords of point number $n on the path. πŸ¦‹

For $n < 1 you get an empty list back, because the very first point sitting at X=0,Y=0 is N=1. No point zero, she doesn't exist.

Also right now it's unspecified what happens if $n isn't a whole integer. And honestly? The points are pretty far apart from each other, so asking for an X,Y that's chillin' in between two integer $n values doesn't really make sense anyway. Not me defending the design, just reporting the facts. 😭

  • $n = $path->xy_to_n ($x,$y) β€” reverse girlypop move: hand it coordinates $x,$y and it hands you back an integer point number. Every integer N is treated as the centre of a unit square, so any $x,$y that lands inside that square gives you that N. Slay. πŸ’…

BUT heads up for the "even" and "odd" options: only every second square in the whole plane actually has an N. So if $x,$y is somewhere that's not covered, you get undef back. Tragic but true. πŸ™ˆ


🌈 OEIS 🌈

Entries in Sloane's Online Encyclopedia of Integer Sequences that are 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

So the counts in those sequences are written as norm = x^2+x*y+y^2. That x,y is related to the "even" X,Y on the path right here by a -45 degree rotation, like:

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

And that X^2+3*Y^2? That's the dist^2 we talked about earlier for equilateral triangles of unit side. The /4 factor just rescales the distance, but obviously it doesn't change which sets of points share the same distance. Math stays math. 🧚

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 πŸ‘‘

Go check these out bestie, they're all in the same friend group:

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, 2018, 2019, 2020 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/>.


okay that's the whole page bestie, you made it to the end, iconic behaviour honestly 🫢

And that's a wrap! This lil' doc is from perl v5.32.0, dated 2021-01-23, and it's the Math::...rHypot(3pm) page itself. Byeee, go plot some triangles! β­πŸ’–πŸŒΈ