1Math::PlanePath::DiagonUaslesr(3C)ontributed Perl DocumeMnattaht:i:oPnlanePath::Diagonals(3)
2
3
4

NAME

6       Math::PlanePath::Diagonals -- points in diagonal stripes
7

SYNOPSIS

9        use Math::PlanePath::Diagonals;
10        my $path = Math::PlanePath::Diagonals->new;
11        my ($x, $y) = $path->n_to_xy (123);
12

DESCRIPTION

14       This path follows successive diagonals going from the Y axis down to
15       the X axis.
16
17             6  |  22
18             5  |  16  23
19             4  |  11  17  24
20             3  |   7  12  18  ...
21             2  |   4   8  13  19
22             1  |   2   5   9  14  20
23           Y=0  |   1   3   6  10  15  21
24                +-------------------------
25                  X=0   1   2   3   4   5
26
27       N=1,3,6,10,etc on the X axis is the triangular numbers.
28       N=1,2,4,7,11,etc on the Y axis is the triangular plus 1, the next point
29       visited after the X axis.
30
31   Direction
32       Option "direction => 'up'" reverses the order within each diagonal to
33       count upward from the X axis.
34
35           direction => "up"
36
37             5  |  21
38             4  |  15  20
39             3  |  10  14  19 ...
40             2  |   6   9  13  18  24
41             1  |   3   5   8  12  17  23
42           Y=0  |   1   2   4   7  11  16  22
43                +-----------------------------
44                  X=0   1   2   3   4   5   6
45
46       This is merely a transpose changing X,Y to Y,X, but it's the same as in
47       "DiagonalsOctant" and can be handy to control the direction when
48       combining "Diagonals" with some other path or calculation.
49
50   N Start
51       The default is to number points starting N=1 as shown above.  An
52       optional "n_start" can give a different start, in the same diagonals
53       sequence.  For example to start at 0,
54
55           n_start => 0,                    n_start=>0
56           direction=>"down"                direction=>"up"
57
58             4  |  10                       |  14
59             3  |   6 11                    |   9 13
60             2  |   3  7 12                 |   5  8 12
61             1  |   1  4  8 13              |   2  4  7 11
62           Y=0  |   0  2  5  9 14           |   0  1  3  6 10
63                +-----------------          +-----------------
64                  X=0  1  2  3  4             X=0  1  2  3  4
65
66       N=0,1,3,6,10,etc on the Y axis of "down" or the X axis of "up" is the
67       triangular numbers Y*(Y+1)/2.
68
69   X,Y Start
70       Options "x_start => $x" and "y_start => $y" give a starting position
71       for the diagonals.  For example to start at X=1,Y=1
72
73             7  |   22               x_start => 1,
74             6  |   16 23            y_start => 1
75             5  |   11 17 24
76             4  |    7 12 18 ...
77             3  |    4  8 13 19
78             2  |    2  5  9 14 20
79             1  |    1  3  6 10 15 21
80           Y=0  |
81                +------------------
82                X=0  1  2  3  4  5
83
84       The effect is merely to add a fixed offset to all X,Y values taken and
85       returned, but it can be handy to have the path do that to step through
86       non-negatives or similar.
87

FUNCTIONS

89       See "FUNCTIONS" in Math::PlanePath for behaviour common to all path
90       classes.
91
92       "$path = Math::PlanePath::Diagonals->new ()"
93       "$path = Math::PlanePath::Diagonals->new (direction => $str, n_start =>
94       $n, x_start => $x, y_start => $y)"
95           Create and return a new path object.  The "direction" option (a
96           string) can be
97
98               direction => "down"       the default
99               direction => "up"         number upwards from the X axis
100
101       "($x,$y) = $path->n_to_xy ($n)"
102           Return the X,Y coordinates of point number $n on the path.
103
104           For "$n < 0.5" the return is an empty list, it being considered the
105           path begins at 1.
106
107       "$n = $path->xy_to_n ($x,$y)"
108           Return the point number for coordinates "$x,$y".  $x and $y are
109           each rounded to the nearest integer, which has the effect of
110           treating each point $n as a square of side 1, so the quadrant
111           x>=-0.5, y>=-0.5 is entirely covered.
112
113       "($n_lo, $n_hi) = $path->rect_to_n_range ($x1,$y1, $x2,$y2)"
114           The returned range is exact, meaning $n_lo and $n_hi are the
115           smallest and biggest in the rectangle.
116

FORMULAS

118   X,Y to N
119       The sum d=X+Y numbers each diagonal from d=0 upwards, corresponding to
120       the Y coordinate where the diagonal starts (or X if direction=up).
121
122           d=2
123               \
124           d=1  \
125               \ \
126           d=0  \ \
127               \ \ \
128
129       N is then given by
130
131           d = X+Y
132           N = d*(d+1)/2 + X + Nstart
133
134       The d*(d+1)/2 shows how the triangular numbers fall on the Y axis when
135       X=0 and Nstart=0.  For the default Nstart=1 it's 1 more than the
136       triangulars, as noted above.
137
138       d can be expanded out to the following quite symmetric form.  This
139       almost suggests something parabolic but is still the straight line
140       diagonals.
141
142               X^2 + 3X + 2XY + Y + Y^2
143           N = ------------------------ + Nstart
144                          2
145
146   N to X,Y
147       The above formula N=d*(d+1)/2 can be solved for d as
148
149           d = floor( (sqrt(8*N+1) - 1)/2 )
150           # with n_start=0
151
152       For example N=12 is d=floor((sqrt(8*12+1)-1)/2)=4 as that N falls in
153       the fifth diagonal.  Then the offset from the Y axis NY=d*(d-1)/2 is
154       the X position,
155
156           X = N - d*(d-1)/2
157           Y = d - X
158
159       In the code fractional N is handled by imagining each diagonal
160       beginning 0.5 back from the Y axis.  That's handled by adding 0.5 into
161       the sqrt, which is +4 onto the 8*N.
162
163           d = floor( (sqrt(8*N+5) - 1)/2 )
164           # N>=-0.5
165
166       The X and Y formulas are unchanged, since N=d*(d-1)/2 is still the Y
167       axis.  But each diagonal d begins up to 0.5 before that and therefor X
168       extends back to -0.5.
169
170   Rectangle to N Range
171       Within each row increasing X is increasing N, and in each column
172       increasing Y is increasing N.  So in a rectangle the lower left corner
173       is minimum N and the upper right is maximum N.
174
175           |            \     \ N max
176           |       \ ----------+
177           |        |     \    |\
178           |        |\     \   |
179           |       \| \     \  |
180           |        +----------
181           |  N min  \  \     \
182           +-------------------------
183

OEIS

185       Entries in Sloane's Online Encyclopedia of Integer Sequences related to
186       this path include
187
188           <http://oeis.org/A002262> (etc)
189
190           direction=down (the default)
191             A002262    X coordinate, runs 0 to k
192             A025581    Y coordinate, runs k to 0
193             A003056    X+Y coordinate sum, k repeated k+1 times
194             A114327    Y-X coordinate diff
195             A101080    HammingDist(X,Y)
196
197             A127949    dY, change in Y coordinate
198
199             A000124    N on Y axis, triangular numbers + 1
200             A001844    N on X=Y diagonal
201
202             A185787    total N in row to X=Y diagonal
203             A185788    total N in row to X=Y-1
204             A100182    total N in column to Y=X diagonal
205             A101165    total N in column to Y=X-1
206             A185506    total N in rectangle 0,0 to X,Y
207
208           either direction=up,down
209             A097806    turn 0=straight, 1=not straight
210
211           direction=down, x_start=1, y_start=1
212             A057555    X,Y pairs
213             A057046    X at N=2^k
214             A057047    Y at N=2^k
215
216           direction=down, n_start=0
217             A057554    X,Y pairs
218             A023531    dSum = dX+dY, being 1 at N=triangular+1 (and 0)
219             A000096    N on X axis, X*(X+3)/2
220             A000217    N on Y axis, the triangular numbers
221             A129184    turn 1=left,0=right
222             A103451    turn 1=left or right,0=straight, but extra initial 1
223             A103452    turn 1=left,0=straight,-1=right, but extra initial 1
224           direction=up, n_start=0
225             A129184    turn 0=left,1=right
226
227           direction=up, n_start=-1
228             A023531    turn 1=left,0=right
229           direction=down, n_start=-1
230             A023531    turn 0=left,1=right
231
232           in direction=up the X,Y coordinate forms are the same but swap X,Y
233
234           either direction=up,down
235             A038722    permutation N at transpose Y,X
236                          which is direction=down <-> direction=up
237
238           either direction, x_start=1, y_start=1
239             A003991    X*Y coordinate product
240             A003989    GCD(X,Y) greatest common divisor starting (1,1)
241             A003983    min(X,Y)
242             A051125    max(X,Y)
243
244           either direction, n_start=0
245             A049581    abs(X-Y) coordinate diff
246             A004197    min(X,Y)
247             A003984    max(X,Y)
248             A004247    X*Y coordinate product
249             A048147    X^2+Y^2
250             A109004    GCD(X,Y) greatest common divisor starting (0,0)
251             A004198    X bit-and Y
252             A003986    X bit-or Y
253             A003987    X bit-xor Y
254             A156319    turn 0=straight,1=left,2=right
255
256             A061579    permutation N at transpose Y,X
257                          which is direction=down <-> direction=up
258

SEE ALSO

260       Math::PlanePath, Math::PlanePath::DiagonalsAlternating,
261       Math::PlanePath::DiagonalsOctant, Math::PlanePath::Corner,
262       Math::PlanePath::Rows, Math::PlanePath::Columns
263

HOME PAGE

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

LICENSE

268       Copyright 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019
269       Kevin Ryde
270
271       This file is part of Math-PlanePath.
272
273       Math-PlanePath is free software; you can redistribute it and/or modify
274       it under the terms of the GNU General Public License as published by
275       the Free Software Foundation; either version 3, or (at your option) any
276       later version.
277
278       Math-PlanePath is distributed in the hope that it will be useful, but
279       WITHOUT ANY WARRANTY; without even the implied warranty of
280       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
281       General Public License for more details.
282
283       You should have received a copy of the GNU General Public License along
284       with Math-PlanePath.  If not, see <http://www.gnu.org/licenses/>.
285
286
287
288perl v5.30.1                      2020-01-30     Math::PlanePath::Diagonals(3)
Impressum