1Math::PlanePath::CornerU(s3e)r Contributed Perl DocumentaMtaitohn::PlanePath::Corner(3)
2
3
4

NAME

6       Math::PlanePath::Corner -- points shaped around in a corner
7

SYNOPSIS

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

DESCRIPTION

14       This path puts points in layers working outwards from the corner of the
15       first quadrant.
16
17             5 | 26--...
18               |
19             4 | 17--18--19--20--21
20               |                  |
21             3 | 10--11--12--13  22
22               |              |   |
23             2 |  5-- 6-- 7  14  23
24               |          |   |   |
25             1 |  2-- 3   8  15  24
26               |  |   |   |   |   |
27           Y=0 |  1   4   9  16  25
28               +---------------------
29                X=0   1   2   3   4
30
31       The horizontal 1,4,9,16,etc along Y=0 is the perfect squares.  This is
32       since each further row/column "gnomon" added to a square makes a one-
33       bigger square,
34
35                                   10 11 12 13
36                      5  6  7       5  6  7 14
37           2  3       2  3  8       2  3  8 15
38           1  4       1  4  9       1  4  9 16
39
40            2x2        3x3           4x4
41
42       N=2,6,12,20,etc on the diagonal X=Y-1 up from X=0,Y=1 is the pronic
43       numbers k*(k+1) which are half way between the squares.
44
45       Each gnomon is 2 longer than the previous.  This is similar to the
46       "PyramidRows", "PyramidSides" and "SacksSpiral" paths.  The "Corner"
47       and the "PyramidSides" are the same but "PyramidSides" is stretched to
48       two quadrants instead of one for the "Corner" here.
49
50   Wider
51       An optional "wider => $integer" makes the path wider horizontally,
52       becoming a rectangle.  For example
53
54           wider => 3
55
56            4  |  29--30--31--...
57               |
58            3  |  19--20--21--22--23--24--25
59               |                           |
60            2  |  11--12--13--14--15--16  26
61               |                       |   |
62            1  |   5---6---7---8---9  17  27
63               |                   |   |   |
64           Y=0 |   1---2---3---4  10  18  28
65               |
66                -----------------------------
67                   ^
68                  X=0  1   2   3   4   5   6
69
70       Each gnomon has the horizontal part "wider" many steps longer.  Each
71       gnomon is still 2 longer than the previous since this widening is a
72       constant amount in each.
73
74   N Start
75       The default is to number points starting N=1 as shown above.  An
76       optional "n_start" can give a different start with the same shape etc.
77       For example to start at 0,
78
79           n_start => 0
80
81             5  |  25 ...
82             4  |  16 17 18 19 20
83             3  |   9 10 11 12 21
84             2  |   4  5  6 13 22
85             1  |   1  2  7 14 23
86           Y=0  |   0  3  8 15 24
87                 -----------------
88                  X=0   1   2   3
89
90       In Nstart=0, the squares are on the Y axis and the pronic numbers are
91       on the X=Y leading diagonal.
92

FUNCTIONS

94       See "FUNCTIONS" in Math::PlanePath for behaviour common to all path
95       classes.
96
97       "$path = Math::PlanePath::Corner->new ()"
98       "$path = Math::PlanePath::Corner->new (wider => $w, n_start => $n)"
99           Create and return a new path object.
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 < n_start()-0.5" the return is an empty list.  There's an
105           extra 0.5 before Nstart, but nothing further before there.
106
107       "$n = $path->xy_to_n ($x,$y)"
108           Return the point number for coordinates "$x,$y".
109
110           $x and $y are each rounded to the nearest integer, which has the
111           effect of treating each point as a square of side 1, so the
112           quadrant x>=-0.5 and y>=-0.5 is entirely covered.
113
114       "($n_lo, $n_hi) = $path->rect_to_n_range ($x1,$y1, $x2,$y2)"
115           The returned range is exact, meaning $n_lo and $n_hi are the
116           smallest and biggest in the rectangle.
117

FORMULAS

119   N to X,Y
120       Counting d=0 for the first L-shaped gnomon at Y=0, then the start of
121       the gnomon is
122
123           StartN(d) = d^2 + 1 = 1,2,5,10,17,etc
124
125       The current n_to_xy() code extends to the left by an extra 0.5 for
126       fractional N, so for example N=9.5 is at X=-0.5,Y=3.  With this the
127       starting N for each gnomon d is
128
129           StartNfrac(d) = d^2 + 0.5
130
131       Inverting gives the gnomon d number for an N,
132
133           d = floor(sqrt(N - 0.5))
134
135       Subtracting the gnomon start gives an offset into that gnomon
136
137           OffStart = N - StartNfrac(d)
138
139       The corner point 1,3,7,13,etc where the gnomon turns down is at d+0.5
140       into that remainder, and it's convenient to subtract that so negative
141       for the horizontal and positive for the vertical,
142
143           Off = OffStart - (d+0.5)
144               = N - (d*(d+1) + 1)
145
146       Then the X,Y coordinates are
147
148           if (Off < 0)  then  X=d+Off, Y=d
149           if (Off >= 0) then  X=d,     Y=d-Off
150
151   X,Y to N
152       For a given X,Y the bigger of X or Y determines the d gnomon.
153
154       If Y>=X then X,Y is on the horizontal part.  At X=0 have N=StartN(d)
155       per the Start(N) formula above, and any further X is an offset from
156       there.
157
158           if Y >= X then
159             d=Y
160             N = StartN(d) + X
161               = Y^2 + 1 + X
162
163       Otherwise if Y<X then X,Y is on the vertical part.  At Y=0 N is the
164       last point on the gnomon, and one back from the start of the following
165       gnomon,
166
167           if Y <= X then
168             d=X
169             LastN(d) = StartN(d+1) - 1
170                      = (d+1)^2
171             N = LastN(d) - Y
172               = (X+1)^2 - Y
173
174   Rectangle N Range
175       For rect_to_n_range(), in each row increasing X is increasing N so the
176       smallest N is in the leftmost column and the biggest N in the rightmost
177       column.
178
179           |
180           |  ------>  N increasing
181           |
182            -----------------------
183
184       Going up a column, N values are increasing away from the X=Y diagonal
185       up or down, and all N values above X=Y are bigger than the ones below.
186
187           |    ^  N increasing up from X=Y diagonal
188           |    |
189           |    |/
190           |    /
191           |   /|
192           |  / |  N increasing down from X=Y diagonal
193           | /  v
194           |/
195            -----------------------
196
197       This means the biggest N is the top right corner if that corner is
198       Y>=X, otherwise the bottom right corner.
199
200                                                  max N at top right
201           |      /                          | --+     if corner Y>=X
202           |     / --+                       |   | /
203           |    /    |                       |   |/
204           |   /     |                       |   |
205           |  /  ----v                       |  /|
206           | /     max N at bottom right     | --+
207           |/        if corner Y<=X          |/
208            ----------                        -------
209
210       For the smallest N, if the bottom left corner has Y>X then it's in the
211       "increasing" part and that bottom left corner is the smallest N.
212       Otherwise Y<=X means some of the "decreasing" part is covered and the
213       smallest N is at Y=min(X,Ymax), ie. either the Y=X diagonal if it's in
214       the rectangle or the top right corner otherwise.
215
216           |      /
217           | |   /
218           | |  /  min N at bottom left
219           | +----  if corner Y>X
220           |  /
221           | /
222           |/
223            ----------
224
225           |      /                           |      /
226           |   | /                            |     /
227           |   |/  min N at X=Y               |    /
228           |   *    if diagonal crossed       |   / +-- min N at top left
229           |  /|                              |  /  |    if corner Y<X
230           | / +-----                         | /   |
231           |/                                 |/
232            ----------                         ----------
233
234           min N at Xmin,Ymin            if Ymin >= Xmin
235                    Xmin,min(Xmin,Ymax)  if Ymin <= Xmin
236

OEIS

238       This path is in Sloane's Online Encyclopedia of Integer Sequences as,
239
240           <http://oeis.org/A196199> (etc)
241
242           wider=0, n_start=1 (the defaults)
243             A213088    X+Y sum
244             A196199    X-Y diff, being runs -n to +n
245             A053615    abs(X-Y), runs n to 0 to n, distance to next pronic
246
247             A000290    N on X axis, perfect squares starting from 1
248             A002522    N on Y axis, Y^2+1
249             A002061    N on X=Y diagonal, extra initial 1
250             A004201    N on and below X=Y diagonal, so X>=Y
251
252             A020703    permutation N at transpose Y,X
253             A060734    permutation N by diagonals up from X axis
254             A064790     inverse
255             A060736    permutation N by diagonals down from Y axis
256             A064788     inverse
257
258             A027709    boundary length of N unit squares
259             A078633    grid sticks of N points
260
261           n_start=0
262             A000196    max(X,Y), being floor(sqrt(N))
263
264             A005563    N on X axis, n*(n+2)
265             A000290    N on Y axis, perfect squares
266             A002378    N on X=Y diagonal, pronic numbers
267
268           n_start=2
269             A059100    N on Y axis, Y^2+2
270             A014206    N on X=Y diagonal, pronic+2
271
272           wider=1
273             A053188    abs(X-Y), dist to nearest square, extra initial 0
274           wider=1, n_start=0
275             A002378    N on Y axis, pronic numbers
276             A005563    N on X=Y diagonal, n*(n+2)
277           wider=1, n_start=2
278             A014206    N on Y axis, pronic+2
279
280           wider=2, n_start=1
281             A028387    N on X=Y diagonal, k*(k+3) + 1
282           wider=2, n_start=0
283             A005563    N on Y axis, (Y+1)^2-1
284             A028552    N on X=Y diagonal, k*(k+3)
285
286           wider=3, n_start=0
287             A028552    N on Y axis, k*(k+3)
288

SEE ALSO

290       Math::PlanePath, Math::PlanePath::PyramidSides,
291       Math::PlanePath::PyramidRows, Math::PlanePath::SacksSpiral,
292       Math::PlanePath::Diagonals
293

HOME PAGE

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

LICENSE

298       Copyright 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
299       2020, 2021 Kevin Ryde
300
301       This file is part of Math-PlanePath.
302
303       Math-PlanePath is free software; you can redistribute it and/or modify
304       it under the terms of the GNU General Public License as published by
305       the Free Software Foundation; either version 3, or (at your option) any
306       later version.
307
308       Math-PlanePath is distributed in the hope that it will be useful, but
309       WITHOUT ANY WARRANTY; without even the implied warranty of
310       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
311       General Public License for more details.
312
313       You should have received a copy of the GNU General Public License along
314       with Math-PlanePath.  If not, see <http://www.gnu.org/licenses/>.
315
316
317
318perl v5.36.0                      2023-01-20        Math::PlanePath::Corner(3)
Impressum