The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

# NAME

Math::PlanePath::CornerAlternating -- points shaped around a corner alternately

# SYNOPSIS

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

# DESCRIPTION

This path is points in layers around a square outwards from a corner in the first quadrant, alternately upward or downward. Each row/column "gnomon" added to a square makes a one-bigger square.

``````      4 | 17--18--19--20--21 ...
|  |               |   |
3 | 16--15--14--13  22  29
|              |   |   |
2 |  5---6---7  12  23  28
|  |       |   |   |   |
1 |  4---3   8  11  24  27
|      |   |   |   |   |
Y=0 |  1---2   9--10  25--26
+-------------------------
X=0   1   2   3   4   5``````

This is like the Corner path, but here gnomons go back and forward and in particular so points are always a unit step apart.

## Wider

An optional `wider => \$integer` makes the path wider horizontally, becoming a rectangle. For example

``````     4  |  29--30--31--32--33--34--35--36  ...
|   |                           |   |
3  |  28--27--26--25--24--23--22  37  44      wider => 3
|                           |   |   |
2  |  11--12--13--14--15--16  21  38  43
|   |                   |   |   |   |
1  |  10---9---8---7---6  17  20  39  42
|                   |   |   |   |   |
Y=0 |   1---2---3---4---5  18--19  40--41
+--------------------------------------
X=0   1   2   3   4   5   6   7   8``````

Each gnomon has the horizontal part `wider` many steps longer. For wider=3 shown, the additional points are 2,3,4 in the first row, then 5..10 are the next gnomon. Each gnomon is still 2 longer than the previous since this widening is a constant amount in each.

## N Start

The default is to number points starting N=1 as shown above. An optional `n_start` can give a different start with the same shape etc. For example to start at 0,

``````      4  |  16  17  18  19  20
3  |  15  14  13  12  21      n_start => 0
2  |   4   5   6  11  22
1  |   3   2   7  10  23
Y=0  |   0   1   8   9  24
---------------------
X=0   1   2   3   4``````

With Nstart=0, the pronic numbers are on the X=Y leading diagonal.

# FUNCTIONS

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

`\$path = Math::PlanePath::CornerAlternating->new ()`
`\$path = Math::PlanePath::CornerAlternating->new (wider => \$w, n_start => \$n)`

Create and return a new path object.

`(\$x,\$y) = \$path->n_to_xy (\$n)`

Return the X,Y coordinates of point number `\$n` on the path.

For `\$n < n_start()` the return is an empty list. Fractional `\$n` gives an X,Y position along a straight line between the integer positions.

`\$n = \$path->xy_to_n (\$x,\$y)`

Return the point number for coordinates `\$x,\$y`.

`\$x` and `\$y` are each rounded to the nearest integer, which has the effect of treating each point as a square of side 1, so the quadrant x>=-0.5 and y>=-0.5 is entirely covered.

`(\$n_lo, \$n_hi) = \$path->rect_to_n_range (\$x1,\$y1, \$x2,\$y2)`

The returned range is exact, meaning `\$n_lo` and `\$n_hi` are the smallest and biggest in the rectangle.

# FORMULAS

Most calculations are similar to the Corner path (without the 0.5 fractional part), and a reversal applied when the d gnomon number is odd. When wider>0, that reversal must allow for the horizontals and verticals different lengths.

## Rectangle N Range

For `rect_to_n_range()`, the largest gnomon is either the top or right of the rectangle, depending where the top right corner x2,y2 falls relative to the leading diagonal,

``````    |  A---B /    x2<y2         |       /       x2>y2
|  |   |/     top           |  +------B     right
|  |   |      row           |  |  /   |     side
|  |  /|     biggest        |  | /    |     biggest
|  +---+     gnomon         |  +------C     gnomon
|   /                       |  /
+---------                  +-----------``````

Then the maximum is at A or B, or B or C according as which way that gnomon goes, so odd or even.

If it happens that B is on the diagonal, so x2=y2, then it's either A or C according as the gnomon odd or even

``````    |        /
|  A----+     x2=y2
|  |   /|
|  |  / |
|  +----C
|   /
+-----------``````

For wider > 0, the diagonal shifts across so that x2-wider <=> y2 is the relevant test.

# OEIS

This path is in Sloane's Online Encyclopedia of Integer Sequences as,

``````    wider=0, n_start=1 (the defaults)
A220603    X+1 coordinate
A220604    Y+1 coordinate
A213088    X+Y sum
A081346    N on X axis
A081345    N on Y axis
A002061    N on X=Y diagonal, extra initial 1
A081344    permutation N by diagonals
A194280      inverse
A020703    permutation N at transpose Y,X

A027709    boundary length of N unit squares
A078633    grid sticks of N points

n_start=0
A319290    X coordinate
A319289    Y coordinate
A319514    Y,X coordinate pairs
A329116    X-Y diff
A053615    abs(X-Y) diff
A000196    max(X,Y), being floor(sqrt(N))
A339265    dX-dY increments (runs +1,-1)
A002378    N on X=Y diagonal, pronic numbers
A220516    permutation N by diagonals

n_start=2
A014206    N on X=Y diagonal, pronic+2

wider=1, n_start=1
A081347    N on X axis
A081348    N on Y axis
A080335    N on X=Y diagonal
A093650    permutation N by diagonals

wider=1, n_start=0
A180714    X-Y diff

wider=2, n_start=1
A081350    N on X axis
A081351    N on Y axis
A081352    N on X=Y diagonal
A081349    permutation N by diagonals``````

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