1Math::PlanePath::DiagonUaslesr(3C)ontributed Perl DocumeMnattaht:i:oPnlanePath::Diagonals(3)
2
3
4
6 Math::PlanePath::Diagonals -- points in diagonal stripes
7
9 use Math::PlanePath::Diagonals;
10 my $path = Math::PlanePath::Diagonals->new;
11 my ($x, $y) = $path->n_to_xy (123);
12
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
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
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
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
257 Math::PlanePath, Math::PlanePath::DiagonalsAlternating,
258 Math::PlanePath::DiagonalsOctant, Math::PlanePath::Corner,
259 Math::PlanePath::Rows, Math::PlanePath::Columns
260
262 <http://user42.tuxfamily.org/math-planepath/index.html>
263
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.1 2017-12-03 Math::PlanePath::Diagonals(3)