.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Math::PlanePath::Corner 3pm" .TH Math::PlanePath::Corner 3pm "2021-01-23" "perl v5.32.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Math::PlanePath::Corner \-\- points shaped around in a corner .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 3 \& use Math::PlanePath::Corner; \& my $path = Math::PlanePath::Corner\->new; \& my ($x, $y) = $path\->n_to_xy (123); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This path puts points in layers working outwards from the corner of the first quadrant. .PP .Vb 10 \& 5 | 26\-\-... \& | \& 4 | 17\-\-18\-\-19\-\-20\-\-21 \& | | \& 3 | 10\-\-11\-\-12\-\-13 22 \& | | | \& 2 | 5\-\- 6\-\- 7 14 23 \& | | | | \& 1 | 2\-\- 3 8 15 24 \& | | | | | | \& Y=0 | 1 4 9 16 25 \& +\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& X=0 1 2 3 4 .Ve .PP The horizontal 1,4,9,16,etc along Y=0 is the perfect squares. This is since each further row/column \*(L"gnomon\*(R" added to a square makes a one-bigger square, .IX Xref "Gnomon Square numbers" .PP .Vb 4 \& 10 11 12 13 \& 5 6 7 5 6 7 14 \& 2 3 2 3 8 2 3 8 15 \& 1 4 1 4 9 1 4 9 16 \& \& 2x2 3x3 4x4 .Ve .PP N=2,6,12,20,etc on the diagonal X=Y\-1 up from X=0,Y=1 is the pronic numbers k*(k+1) which are half way between the squares. .IX Xref "Pronic numbers" .PP Each gnomon is 2 longer than the previous. This is similar to the \&\f(CW\*(C`PyramidRows\*(C'\fR, \f(CW\*(C`PyramidSides\*(C'\fR and \f(CW\*(C`SacksSpiral\*(C'\fR paths. The \f(CW\*(C`Corner\*(C'\fR and the \f(CW\*(C`PyramidSides\*(C'\fR are the same but \f(CW\*(C`PyramidSides\*(C'\fR is stretched to two quadrants instead of one for the \f(CW\*(C`Corner\*(C'\fR here. .SS "Wider" .IX Subsection "Wider" An optional \f(CW\*(C`wider => $integer\*(C'\fR makes the path wider horizontally, becoming a rectangle. For example .PP .Vb 1 \& wider => 3 \& \& 4 | 29\-\-30\-\-31\-\-... \& | \& 3 | 19\-\-20\-\-21\-\-22\-\-23\-\-24\-\-25 \& | | \& 2 | 11\-\-12\-\-13\-\-14\-\-15\-\-16 26 \& | | | \& 1 | 5\-\-\-6\-\-\-7\-\-\-8\-\-\-9 17 27 \& | | | | \& Y=0 | 1\-\-\-2\-\-\-3\-\-\-4 10 18 28 \& | \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& ^ \& X=0 1 2 3 4 5 6 .Ve .PP Each gnomon has the horizontal part \f(CW\*(C`wider\*(C'\fR many steps longer. Each gnomon is still 2 longer than the previous since this widening is a constant amount in each. .SS "N Start" .IX Subsection "N Start" The default is to number points starting N=1 as shown above. An optional \&\f(CW\*(C`n_start\*(C'\fR can give a different start with the same shape etc. For example to start at 0, .PP .Vb 1 \& n_start => 0 \& \& 5 | 25 ... \& 4 | 16 17 18 19 20 \& 3 | 9 10 11 12 21 \& 2 | 4 5 6 13 22 \& 1 | 1 2 7 14 23 \& Y=0 | 0 3 8 15 24 \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& X=0 1 2 3 .Ve .PP In Nstart=0, the squares are on the Y axis and the pronic numbers are on the X=Y leading diagonal. .SH "FUNCTIONS" .IX Header "FUNCTIONS" See \*(L"\s-1FUNCTIONS\*(R"\s0 in Math::PlanePath for behaviour common to all path classes. .ie n .IP """$path = Math::PlanePath::Corner\->new ()""" 4 .el .IP "\f(CW$path = Math::PlanePath::Corner\->new ()\fR" 4 .IX Item "$path = Math::PlanePath::Corner->new ()" .PD 0 .ie n .IP """$path = Math::PlanePath::Corner\->new (wider => $w, n_start => $n)""" 4 .el .IP "\f(CW$path = Math::PlanePath::Corner\->new (wider => $w, n_start => $n)\fR" 4 .IX Item "$path = Math::PlanePath::Corner->new (wider => $w, n_start => $n)" .PD Create and return a new path object. .ie n .IP """($x,$y) = $path\->n_to_xy ($n)""" 4 .el .IP "\f(CW($x,$y) = $path\->n_to_xy ($n)\fR" 4 .IX Item "($x,$y) = $path->n_to_xy ($n)" Return the X,Y coordinates of point number \f(CW$n\fR on the path. .Sp For \f(CW\*(C`$n < n_start()\-0.5\*(C'\fR the return is an empty list. There's an extra 0.5 before Nstart, but nothing further before there. .ie n .IP """$n = $path\->xy_to_n ($x,$y)""" 4 .el .IP "\f(CW$n = $path\->xy_to_n ($x,$y)\fR" 4 .IX Item "$n = $path->xy_to_n ($x,$y)" Return the point number for coordinates \f(CW\*(C`$x,$y\*(C'\fR. .Sp \&\f(CW$x\fR and \f(CW$y\fR 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. .ie n .IP """($n_lo, $n_hi) = $path\->rect_to_n_range ($x1,$y1, $x2,$y2)""" 4 .el .IP "\f(CW($n_lo, $n_hi) = $path\->rect_to_n_range ($x1,$y1, $x2,$y2)\fR" 4 .IX Item "($n_lo, $n_hi) = $path->rect_to_n_range ($x1,$y1, $x2,$y2)" The returned range is exact, meaning \f(CW$n_lo\fR and \f(CW$n_hi\fR are the smallest and biggest in the rectangle. .SH "FORMULAS" .IX Header "FORMULAS" .SS "N to X,Y" .IX Subsection "N to X,Y" Counting d=0 for the first L\-shaped gnomon at Y=0, then the start of the gnomon is .PP .Vb 1 \& StartN(d) = d^2 + 1 = 1,2,5,10,17,etc .Ve .PP The current \f(CW\*(C`n_to_xy()\*(C'\fR code extends to the left by an extra 0.5 for fractional N, so for example N=9.5 is at X=\-0.5,Y=3. With this the starting N for each gnomon d is .PP .Vb 1 \& StartNfrac(d) = d^2 + 0.5 .Ve .PP Inverting gives the gnomon d number for an N, .PP .Vb 1 \& d = floor(sqrt(N \- 0.5)) .Ve .PP Subtracting the gnomon start gives an offset into that gnomon .PP .Vb 1 \& OffStart = N \- StartNfrac(d) .Ve .PP The corner point 1,3,7,13,etc where the gnomon turns down is at d+0.5 into that remainder, and it's convenient to subtract that so negative for the horizontal and positive for the vertical, .PP .Vb 2 \& Off = OffStart \- (d+0.5) \& = N \- (d*(d+1) + 1) .Ve .PP Then the X,Y coordinates are .PP .Vb 2 \& if (Off < 0) then X=d+Off, Y=d \& if (Off >= 0) then X=d, Y=d\-Off .Ve .SS "X,Y to N" .IX Subsection "X,Y to N" For a given X,Y the bigger of X or Y determines the d gnomon. .PP If Y>=X then X,Y is on the horizontal part. At X=0 have N=StartN(d) per the Start(N) formula above, and any further X is an offset from there. .PP .Vb 4 \& if Y >= X then \& d=Y \& N = StartN(d) + X \& = Y^2 + 1 + X .Ve .PP Otherwise if Y N increasing \& | \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- .Ve .PP Going up a column, N values are increasing away from the X=Y diagonal up or down, and all N values above X=Y are bigger than the ones below. .PP .Vb 9 \& | ^ N increasing up from X=Y diagonal \& | | \& | |/ \& | / \& | /| \& | / | N increasing down from X=Y diagonal \& | / v \& |/ \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- .Ve .PP This means the biggest N is the top right corner if that corner is Y>=X, otherwise the bottom right corner. .PP .Vb 9 \& max N at top right \& | / | \-\-+ if corner Y>=X \& | / \-\-+ | | / \& | / | | |/ \& | / | | | \& | / \-\-\-\-v | /| \& | / max N at bottom right | \-\-+ \& |/ if corner Y<=X |/ \& \-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\- .Ve .PP For the smallest N, if the bottom left corner has Y>X then it's in the \&\*(L"increasing\*(R" part and that bottom left corner is the smallest N. Otherwise Y<=X means some of the \*(L"decreasing\*(R" part is covered and the smallest N is at Y=min(X,Ymax), ie. either the Y=X diagonal if it's in the rectangle or the top right corner otherwise. .PP .Vb 8 \& | / \& | | / \& | | / min N at bottom left \& | +\-\-\-\- if corner Y>X \& | / \& | / \& |/ \& \-\-\-\-\-\-\-\-\-\- \& \& | / | / \& | | / | / \& | |/ min N at X=Y | / \& | * if diagonal crossed | / +\-\- min N at top left \& | /| | / | if corner Y= Xmin \& Xmin,min(Xmin,Ymax) if Ymin <= Xmin .Ve .SH "OEIS" .IX Header "OEIS" This path is in Sloane's Online Encyclopedia of Integer Sequences as, .Sp .RS 4 (etc) .RE .PP .Vb 4 \& wider=0, n_start=1 (the defaults) \& A213088 X+Y sum \& A196199 X\-Y diff, being runs \-n to +n \& A053615 abs(X\-Y), runs n to 0 to n, distance to next pronic \& \& A000290 N on X axis, perfect squares starting from 1 \& A002522 N on Y axis, Y^2+1 \& A002061 N on X=Y diagonal, extra initial 1 \& A004201 N on and below X=Y diagonal, so X>=Y \& \& A020703 permutation N at transpose Y,X \& A060734 permutation N by diagonals up from X axis \& A064790 inverse \& A060736 permutation N by diagonals down from Y axis \& A064788 inverse \& \& A027709 boundary length of N unit squares \& A078633 grid sticks of N points \& \& n_start=0 \& A000196 max(X,Y), being floor(sqrt(N)) \& \& A005563 N on X axis, n*(n+2) \& A000290 N on Y axis, perfect squares \& A002378 N on X=Y diagonal, pronic numbers \& \& n_start=2 \& A059100 N on Y axis, Y^2+2 \& A014206 N on X=Y diagonal, pronic+2 \& \& wider=1 \& A053188 abs(X\-Y), dist to nearest square, extra initial 0 \& wider=1, n_start=0 \& A002378 N on Y axis, pronic numbers \& A005563 N on X=Y diagonal, n*(n+2) \& wider=1, n_start=2 \& A014206 N on Y axis, pronic+2 \& \& wider=2, n_start=1 \& A028387 N on X=Y diagonal, k*(k+3) + 1 \& wider=2, n_start=0 \& A005563 N on Y axis, (Y+1)^2\-1 \& A028552 N on X=Y diagonal, k*(k+3) \& \& wider=3, n_start=0 \& A028552 N on Y axis, k*(k+3) .Ve .SH "SEE ALSO" .IX Header "SEE ALSO" Math::PlanePath, Math::PlanePath::PyramidSides, Math::PlanePath::PyramidRows, Math::PlanePath::SacksSpiral, Math::PlanePath::Diagonals .SH "HOME PAGE" .IX Header "HOME PAGE" .SH "LICENSE" .IX Header "LICENSE" Copyright 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021 Kevin Ryde .PP This file is part of Math-PlanePath. .PP Math-PlanePath is free software; you can redistribute it and/or modify it under the terms of the \s-1GNU\s0 General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. .PP Math-PlanePath is distributed in the hope that it will be useful, but \&\s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of \s-1MERCHANTABILITY\s0 or \s-1FITNESS FOR A PARTICULAR PURPOSE.\s0 See the \s-1GNU\s0 General Public License for more details. .PP You should have received a copy of the \s-1GNU\s0 General Public License along with Math-PlanePath. If not, see .