Math::...hDelta(3pm)

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

✨ NAME ✨

Math::NumSeq::PlanePathDelta β€” bestie, this is a whole sequence of the changes and directions that happen as you walk along PlanePath coordinates πŸ¦‹ (it lives in the Math::...hDelta(3pm) corner of the manual, iykyk)


🌸 SYNOPSIS 🌸

use Math::NumSeq::PlanePathDelta;
my $seq = Math::NumSeq::PlanePathDelta->new
            (planepath => 'SquareSpiral',
             delta_type => 'dX');
my ($i, $value) = $seq->next;

πŸ’… DESCRIPTION πŸ’…

okay so basically this is a tie-in that takes the coordinate changes and directions from a Math::PlanePath module and serves them up as a NumSeq sequence. iconic behaviour honestly πŸ‘‘

The delta_type choices are, and yes we are listing ALL of them:

"dX"         change in X coordinate
"dY"         change in Y coordinate
"AbsdX"      abs(dX)
"AbsdY"      abs(dY)
"dSum"       change in X+Y, equals dX+dY
"dSumAbs"    change in abs(X)+abs(Y)
"dDiffXY"    change in X-Y, equals dX-dY
"dDiffYX"    change in Y-X, equals dY-dX
"dAbsDiff"   change in abs(X-Y)
"dRadius"    change in Radius sqrt(X^2+Y^2)
"dRSquared"  change in RSquared X^2+Y^2
"Dir4"       direction 0=East, 1=North, 2=West, 3=South
"TDir6"      triangular 0=E, 1=NE, 2=NW, 3=W, 4=SW, 5=SE

So in every case the value at i is per "$path->n_to_dxdy($i)" β€” that's the change from N=i to N=i+1, or from N=i to N=i+arms for paths with multiple "arms" (so it's following the arm, periodt). And the i values start from the usual "$path->n_start()" πŸ’–

πŸŽ€ AbsdX,AbsdY πŸŽ€

If a path always steps NSEW by 1 then AbsdX and AbsdY are literally just acting like a boolean telling you horizontal or vertical step:

NSEW steps by 1 gives

AbsdX = 0 vertical            AbsdY = 0 horizontal
        1 horizontal                  1 vertical

But if a path includes diagonal steps by 1 then those diagonals count as a non-zero delta, so the vibe check changes to:

NSEW and diagonals steps by 1 gives

AbsdX = 0 vertical            AbsdY = 0 horizontal
        1 non-vertical                1 non-horizontal
          ie. horiz or diag             ie. vert or diag

🌈 dSum 🌈

"dSum" is the change in X+Y and lowkey it's also just plain dX+dY because, watch this:

dSum = (Xnext+Ynext) - (X+Y)
     = (Xnext-X) + (Ynext-Y)
     = dX + dY

The sum X+Y counts anti-diagonals, as described over in Math::NumSeq::PlanePathCoord. So dSum is a move between diagonals, or 0 if a step just stays chillin' inside the same diagonal.

               \
                \  ^  dSum > 0      dSum = step dist to North-East
                 \/
                 /\
    dSum < 0    v  \
                    \

🧚 dSumAbs 🧚

"dSumAbs" is the change in the abs(X)+abs(Y) sum:

dSumAbs = (abs(Xnext)+abs(Ynext)) - (abs(X)+abs(Y))

As described in "SumAbs" in Math::NumSeq::PlanePathCoord, SumAbs is a "Manhattan" or "taxi-cab" distance from the origin β€” or, same thing, a move between diamond-shaped rings πŸ’Ž

For example "DiamondSpiral" follows a diamond shape ring around, so it has dSumAbs=0 until it steps out to each next diamond with dSumAbs=1.

A path might make a big X,Y jump that's only a small change in SumAbs. For example "PyramidRows" in its default step=2, going from the end of one row to the start of the next, has dSumAbs=2.

🫢 dDiffXY and dDiffYX 🫢

"dDiffXY" is the change in DiffXY = X-Y, and it's also simply dX-dY since:

dDiffXY = (Xnext-Ynext) - (X-Y)
        = (Xnext-X) - (Ynext-Y)
        = dX - dY

The difference X-Y counts diagonals downwards to the south-east, as described in "Sum and Diff" in Math::NumSeq::PlanePathCoord. So dDiffXY is movement between those diagonals, or 0 if a step stays inside the same diagonal.

    dDiffXY < 0       /
                  \  /             dDiffXY = step dist to South-East
                   \/
                   /\
                  /  v
                 /      dDiffXY > 0

"dDiffYX" is just the negative of dDiffXY. Whether you want X-Y or Y-X depends on which way you wanna measure diagonals, or which way around you want the sign for the changes. dDiffYX is based on Y-X and so counts diagonals upwards to the North-West ⬆️

⭐ dAbsDiff ⭐

"dAbsDiff" is the change in AbsDiff = abs(X-Y). AbsDiff can be read geometrically as the distance from the leading diagonal, as described in "AbsDiff" in Math::NumSeq::PlanePathCoord. So dAbsDiff is movement closer to or further away from that leading diagonal, measured perpendicular to it.

                / X=Y line
               /
              /  ^
             /    \
            /      *  dAbsDiff move towards or away from X=Y line
          |/        \
        --o--        v
         /|
        /

When an X,Y jumps from one side of the diagonal to the other, dAbsDiff is still the change in distance from the diagonal. So for example if X,Y is followed by the mirror point Y,X then dAbsDiff=0. That kind of thing happens for example in the "Diagonals" path when it jumps from the end of one run to the start of the next. In the "Diagonals" case it's a move just 1 further away from the X=Y centre line β€” even though it's a big jump in overall distance 😭

πŸ’œ dRadius, dRSquared πŸ’œ

"dRadius" and "dRSquared" are the change in the Radius and RSquared as described in "Radius and RSquared" in Math::NumSeq::PlanePathCoord.

dRadius   = next_Radius   - Radius
dRSquared = next_RSquared - RSquared

dRadius can be read geometrically as movement towards (negative values) or away from (positive values) the origin, ignoring direction.

Notice that dRadius is not sqrt(dRSquared), since sqrt(n^2-t^2) != n-t unless n or t is zero. Here that would mean a step either going to or coming from the origin 0,0.

πŸ‘‘ Dir4 πŸ‘‘

"Dir4" is the curve step direction as an angle in the range 0 <= Dir4 < 4. The cardinal directions E,N,W,S are 0,1,2,3. Angles in between are a fraction.

Dir4 = atan2(dY,dX)  scaled as range 0 <= Dir4 < 4

1.5   1   0.5
    \ | /
     \|/
2 ----o---- 0
     /|\
    / | \
2.5   3   3.5

If a row such as Y=-1,X>0 just below the X axis gets visited then the Dir4 approaches 4, without ever actually reaching it. The "$seq->value_maximum()" is 4 in this case, as a supremum. so close bestie 😭

🌸 TDir6 🌸

"TDir6" is the curve step direction 0 <= TDir6 < 6, taken in the triangular style of "Triangular Lattice" in Math::PlanePath. So dX=1,dY=1 is taken to be 60 degrees, which is TDir6=1.

      2   1.5   1        TDir6
         \ | /
          \|/
      3 ---o--- 0
          /|\
         / | \
      4   4.5   5

Angles in between the six cardinal directions are fractions. North is 1.5 and South is 4.5.

The direction angle is calculated as if dY was scaled by a factor sqrt(3) to make the lattice into equilateral triangles β€” or equivalently as a circle stretched vertically by sqrt(3) to become an ellipse πŸ₯š

TDir6 = atan2(dY*sqrt(3), dX)      in range 0 <= TDir6 < 6

Notice that angles on the axes dX=0 or dY=0 are not changed by the sqrt(3) factor. So TDir6 has ENWS 0, 1.5, 3, 4.5 which is steps of 1.5. Verticals North and South normally don't occur in the triangular lattice paths which go by unit steps, but TDir6 can be applied on any path.

The sqrt(3) factor increases angles in the middle of the quadrants. For example dX=1,dY=1 becomes TDir6=1 whereas a plain angle would be only 45/360*6=0.75 in the same 0 to 6 scale. The sqrt(3) is a continuous scaling, so a plain angle and a TDir6 are a one-to-one mapping. As the direction progresses through the quadrant TDir6 grows first faster and then slower than the plain angle. no cap πŸ“ˆπŸ“‰


πŸ’– FUNCTIONS πŸ’–

See "FUNCTIONS" in Math::NumSeq for behaviour common to all sequence classes.

  • "$seq = Math::NumSeq::PlanePathDelta->new (key=>value,...)" β€” Create and return a new sequence object. The options are:
planepath          string, name of a PlanePath module
planepath_object   PlanePath object
delta_type         string, as described above

"planepath" can be either the module part such as "SquareSpiral" or a full class name "Math::PlanePath::SquareSpiral".

  • "$value = $seq->ith($i)" β€” Return the change at N=$i in the PlanePath.
  • "$i = $seq->i_start()" β€” Return the first index $i in the sequence. This is the position "$seq->rewind()" returns to.

This is "$path->n_start()" from the PlanePath.


πŸ’€ BUGS πŸ’€

Some path sequences don't have "oeis_anum()" and are not available through Math::NumSeq::OEIS entry, because the path "n_start()" doesn't match the OEIS "offset". Paths with an "n_start" parameter get suitable adjustments applied, but the ones without are omitted from the Math::NumSeq::OEIS mechanism presently. sad but true πŸ™ˆ


πŸ¦‹ SEE ALSO πŸ¦‹

Math::NumSeq, Math::NumSeq::PlanePathCoord, Math::NumSeq::PlanePathTurn, Math::NumSeq::PlanePathN

Math::PlanePath


🌈 HOME PAGE 🌈

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


πŸ“œ LICENSE πŸ“œ

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


and that's the whole page bestie πŸ’… this one came from the User Contributed Perl Documentation, running on perl v5.32.0, dated 2021-01-23 β€” go forth and slay those deltas πŸŽ€βœ¨