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           direction=down, x_start=1, y_start=1
209             A057555    X,Y pairs
210             A057046    X at N=2^k
211             A057047    Y at N=2^k
212
213           direction=down, n_start=0
214             A057554    X,Y pairs
215             A023531    dSum = dX+dY, being 1 at N=triangular+1 (and 0)
216             A000096    N on X axis, X*(X+3)/2
217             A000217    N on Y axis, the triangular numbers
218             A129184    turn 1=left,0=right
219             A103451    turn 1=left or right,0=straight, but extra initial 1
220             A103452    turn 1=left,0=straight,-1=right, but extra initial 1
221           direction=up, n_start=0
222             A129184    turn 0=left,1=right
223
224           direction=up, n_start=-1
225             A023531    turn 1=left,0=right
226           direction=down, n_start=-1
227             A023531    turn 0=left,1=right
228
229           in direction=up the X,Y coordinate forms are the same but swap X,Y
230
231           either direction
232             A038722    permutation N at transpose Y,X
233                          which is direction=down <-> direction=up
234
235           either direction, x_start=1, y_start=1
236             A003991    X*Y coordinate product
237             A003989    GCD(X,Y) greatest common divisor starting (1,1)
238             A003983    min(X,Y)
239             A051125    max(X,Y)
240
241           either direction, n_start=0
242             A049581    abs(X-Y) coordinate diff
243             A004197    min(X,Y)
244             A003984    max(X,Y)
245             A004247    X*Y coordinate product
246             A048147    X^2+Y^2
247             A109004    GCD(X,Y) greatest common divisor starting (0,0)
248             A004198    X bit-and Y
249             A003986    X bit-or Y
250             A003987    X bit-xor Y
251             A156319    turn 0=straight,1=left,2=right
252
253             A061579    permutation N at transpose Y,X
254                          which is direction=down <-> direction=up
255

SEE ALSO

257       Math::PlanePath, Math::PlanePath::DiagonalsAlternating,
258       Math::PlanePath::DiagonalsOctant, Math::PlanePath::Corner,
259       Math::PlanePath::Rows, Math::PlanePath::Columns
260

HOME PAGE

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

LICENSE

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