The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Math::PlanePath -- points on a path through a 2-D plane

SYNOPSIS

 use Math::PlanePath;
 # only a base class, see the subclasses for actual operation

DESCRIPTION

This is a base class for some mathematical paths which turn an integer position $n into coordinates $x,$y. The current classes include

    SquareSpiral           four-sided spiral
    DiamondSpiral          four-sided spiral, looping faster
    PyramidSpiral          square base pyramid
    TriangleSpiral         equilateral triangle
    TriangleSpiralSkewed   equilateral skewed for compactness
    PentSpiralSkewed       five-sided spiral, compact
    HexSpiral              six-sided spiral
    HexSpiralSkewed        six-sided spiral skewed for compactness
    SacksSpiral            quadratic on an Archimedean spiral
    VogelFloret            seeds in a sunflower
    KnightSpiral           an infinite knight's tour

    Rows                   fixed-width rows
    Columns                fixed-height columns
    Diagonals              diagonals between X and Y axes
    Corner                 expanding stripes around a corner
    PyramidRows            expanding rows pyramid
    PyramidSides           along the sides of a 45-degree pyramid

The paths are object oriented to allow parameters, though currently only a few subclasses actually have any parameters.

The classes are generally oriented towards integer $n positions and those designed for a square grid turn an integer $n into integer $x,$y. Usually they can give in-between positions for fractional $n too. Classes not on a square grid, like SacksSpiral and VogelFloret, are scaled for a unit circle at each $n but they too can give in-between positions on request.

In general there's no parameters for scaling, or an offset for the 0,0 origin, or a reflection up or down. Those things are thought better done by a general coordinate transformer if expanding or inverting for display. Even clockwise instead of counter-clockwise spiralling can be done just by negating $x (or negate $y to stay starting at the right).

Loop Step

The paths can be characterized by how much longer each spiral or repetition is than the preceding one. For example each loop of the SquareSpiral is 8 longer than the preceding.

     0     Rows, Columns
     1     Diagonals
     2     PyramidRows, PyramidSides, Corner, SacksSpiral
     4     DiamondSpiral
     5     PentSpiralSkewed
     6     HexSpiral, HexSpiralSkewed
     8     SquareSpiral, PyramidSpiral
     9     TriangleSpiral, TriangleSpiralSkewed
    32     KnightSpiral (counting the 2-wide trip as the reps)

The step determines which quadratic number sequences fall on straight lines. For example gap between successive perfect squares increases by 2 each time (4 to 9 is 5, 9 to 16 is 7, 16 to 25 is 9, etc), so the perfect squares make a straight line in the PyramidRows and others of step 2.

FUNCTIONS

$path = Math::PlanePath::Foo->new (key=>value, ...)

Create and return a new path object. Optional key/value parameters may control aspects of the object. Foo here is one of the various subclasses, see the list under "SEE ALSO".

($x,$y) = $path->n_to_xy ($n)

Return x,y coordinates of point $n on the path. If there's no point $n then the return is an empty list, so for example

    my ($x,$y) = $path->n_to_xy (-123)
      or next;   # likely no negatives in $path

Currently all paths start from N=1, though some will give a position for N=0 or N=0.5 too.

$n = $path->xy_to_n ($x,$y)

Return the point number for coordinates $x,$y. If there's nothing at $x,$y then return undef.

    my $n = $path->xy_to_n(20,20);
    if (! defined $n) {
      next;   # nothing at this x,y
    }

$x and $y can be fractional and the path classes will give an integer $n which contains $x,$y within a unit square, circle, or intended figure centred on that $n.

For paths which completely tile the plane there's always an $n to return, but for the spread-out paths an $x,$y position may fall in between (no $n close enough).

($n_lo, $n_hi) = $path->rect_to_n_range ($x1,$y1, $x2,$y2)

Return a range of N values which occur in a rectangle with corners at $x1,$y1 and $x2,$y2. The range is inclusive, so for instance

     my ($n_lo, $n_hi) = $path->rect_to_n_range (-5,-5, 5,5);
     foreach my $n ($n_lo .. $n_hi) {
         my ($x, $y) = $path->n_to_xy ($n) or next;
         print "$n  $x,$y";
     }

Note the return may be an over-estimate, and of course some of the points between $n_lo and $n_hi may go outside the rectangle. $n_hi is usually no more than an extra partial row or revolution. $n_lo is often just the starting point 1, which is correct if you always want the origin 0,0, but a rectangle away from the origin could start higher.

$x1,$y1 and $x2,$y2 can be fractional and if they partly overlap some N figures then those N's are included in the return. If there's no points in the rectangle then the return is a "crossed" range like $n_lo=1, $n_hi=0 (which makes a foreach do no loops).

$bool = $path->x_negative
$bool = $path->y_negative

Return true if the path extends into negative X coordinates and/or negative Y coordinates respectively.

$str = $path->figure

Return the name of the figure (shape) intended to be drawn at each $n position. Currently this is one of

    square         side 1 centred on $x,$y
    circle         diameter 1 centred on $x,$y

Of course this is only a suggestion as PlanePath doesn't draw anything itself. A figure like a diamond for instance would work well too.

SEE ALSO

Math::PlanePath::SquareSpiral, Math::PlanePath::DiamondSpiral, Math::PlanePath::HexSpiral, Math::PlanePath::HexSpiralSkewed, Math::PlanePath::SacksSpiral, Math::PlanePath::VogelFloret, Math::PlanePath::KnightSpiral

Math::PlanePath::Rows, Math::PlanePath::Columns, Math::PlanePath::Diagonals, Math::PlanePath::Corner, Math::PlanePath::PyramidRows, Math::PlanePath::PyramidSides

HOME PAGE

http://user42.tuxfamily.org/math-planepath/index.html

LICENSE

Math-PlanePath is Copyright 2010 Kevin Ryde

Math-PlanePath is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.

Math-PlanePath is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Math-PlanePath. If not, see <http://www.gnu.org/licenses/>.