#!/usr/bin/perl -w
# Copyright 2010, 2011, 2012, 2013, 2014 Kevin Ryde
# This file is part of Math-PlanePath.
#
# 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/>.
use 5.004;
use strict;
use Test;
plan tests => 376;
use lib 't';
use MyTestHelpers;
BEGIN { MyTestHelpers::nowarnings(); }
require Math::PlanePath::SquareSpiral;
#------------------------------------------------------------------------------
# VERSION
{
my $want_version = 115;
ok ($Math::PlanePath::SquareSpiral::VERSION, $want_version,
'VERSION variable');
ok (Math::PlanePath::SquareSpiral->VERSION, $want_version,
'VERSION class method');
ok (eval { Math::PlanePath::SquareSpiral->VERSION($want_version); 1 },
1,
"VERSION class check $want_version");
my $check_version = $want_version + 1000;
ok (! eval { Math::PlanePath::SquareSpiral->VERSION($check_version); 1 },
1,
"VERSION class check $check_version");
my $path = Math::PlanePath::SquareSpiral->new;
ok ($path->VERSION, $want_version, 'VERSION object method');
ok (eval { $path->VERSION($want_version); 1 },
1,
"VERSION object check $want_version");
ok (! eval { $path->VERSION($check_version); 1 },
1,
"VERSION object check $check_version");
}
#------------------------------------------------------------------------------
# formulas in pod
{
my $path = Math::PlanePath::SquareSpiral->new;
my $d = 3;
my $Nbase = 4*$d**2 - 4*$d + 2;
ok ($Nbase, 26);
{ my $N = $Nbase;
my $dd = int (1/2 + sqrt($N/4 - 1/4));
ok ($dd, $d, 'd');
$dd = int ((1+sqrt($N-1)) / 2);
ok ($dd, $d, 'd');
}
{ my $N = $Nbase + 8*$d-1;
my $dd = int (1/2 + sqrt($N/4 - 1/4));
ok ($dd, $d, 'd');
$dd = int ((1+sqrt($N-1)) / 2);
ok ($dd, $d, 'd');
}
{ my $N = $Nbase + 8*$d-1 + 1;
my $dd = int (1/2 + sqrt($N/4 - 1/4));
ok ($dd, $d+1, 'd');
$dd = int ((1+sqrt($N-1)) / 2);
ok ($dd, $d+1, 'd');
}
# right upwards
{ my $Nrem = 0;
my ($want_x,$want_y) = $path->n_to_xy($Nbase+$Nrem);
ok ($d, $want_x, 'X');
ok (-$d+1+$Nrem, $want_y, 'Y');
}
{ my $Nrem = 2*$d-1;
my ($want_x,$want_y) = $path->n_to_xy($Nbase+$Nrem);
ok ($d, $want_x, 'X');
ok (-$d+1+$Nrem, $want_y, 'Y');
}
# top
{ my $Nrem = 2*$d-1;
my ($want_x,$want_y) = $path->n_to_xy($Nbase+$Nrem);
ok (3*$d-1-$Nrem, $want_x, 'X');
ok ($d, $want_y, 'Y');
}
{ my $Nrem = 4*$d-1;
my ($want_x,$want_y) = $path->n_to_xy($Nbase+$Nrem);
ok (3*$d-1-$Nrem, $want_x, 'X');
ok ($d, $want_y, 'Y');
}
# left downwards
{ my $Nrem = 4*$d-1;
my ($want_x,$want_y) = $path->n_to_xy($Nbase+$Nrem);
ok (-$d, $want_x, 'X');
ok (5*$d-1-$Nrem, $want_y, 'Y');
}
{ my $Nrem = 6*$d-1;
my ($want_x,$want_y) = $path->n_to_xy($Nbase+$Nrem);
ok (-$d, $want_x, 'X');
ok (5*$d-1-$Nrem, $want_y, 'Y');
}
# bottom
{ my $Nrem = 6*$d-1;
my ($want_x,$want_y) = $path->n_to_xy($Nbase+$Nrem);
ok (-7*$d+1+$Nrem, $want_x, 'X');
ok (-$d, $want_y, 'Y');
}
{ my $Nrem = 8*$d;
my ($want_x,$want_y) = $path->n_to_xy($Nbase+$Nrem);
ok (-7*$d+1+$Nrem, $want_x, 'X');
ok (-$d, $want_y, 'Y');
}
# right upwards
my $Nzero = $Nbase + 4*$d-1;
{ my $Nsig = -(4*$d-1);
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok ($d, $want_x, 'X');
ok (3*$d+$Nsig, $want_y, 'Y');
}
{ my $Nsig = -2*$d;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok ($d, $want_x, 'X');
ok (3*$d+$Nsig, $want_y, 'Y');
}
# top
{ my $Nsig = -2*$d;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok (-$d-$Nsig, $want_x, 'X');
ok ($d, $want_y, 'Y');
}
{ my $Nsig = 0;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok (-$d-$Nsig, $want_x, 'X');
ok ($d, $want_y, 'Y');
}
# left downwards
{ my $Nsig = 0;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok (-$d, $want_x, 'X');
ok ($d-$Nsig, $want_y, 'Y');
}
{ my $Nsig = 2*$d;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok (-$d, $want_x, 'X');
ok ($d-$Nsig, $want_y, 'Y');
}
# bottom
{ my $Nsig = 2*$d;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok ($Nsig-3*$d, $want_x, 'X');
ok (-$d, $want_y, 'Y');
}
{ my $Nsig = 4*$d+1;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok ($Nsig-3*$d, $want_x, 'X');
ok (-$d, $want_y, 'Y');
}
}
#------------------------------------------------------------------------------
# formulas in pod -- wider
{
my $path = Math::PlanePath::SquareSpiral->new (wider => 7);
my $d = 3;
my $w = 7;
my $Nbase = 4*$d**2 + (-4+2*$w)*$d + 2-$w;
ok ($Nbase, 61);
my $wl = int(($w+1)/2); # ceil
my $wr = int($w/2); # floor
ok ($wl, 4);
ok ($wr, 3);
{ my $N = $Nbase;
my $dd = int ((2-$w + sqrt(4*$N + $w**2 - 4)) / 4);
ok ($dd, $d, 'd');
}
{ my $N = $Nbase + 8*$d+2*$w-1;
my $dd = int ((2-$w + sqrt(4*$N + $w**2 - 4)) / 4);
ok ($dd, $d, 'd');
}
{ my $N = $Nbase + 8*$d+2*$w-1 + 1;
my $dd = int ((2-$w + sqrt(4*$N + $w**2 - 4)) / 4);
ok ($dd, $d+1, 'd');
}
# right upwards
my $Nzero = $Nbase + 4*$d-1+$w;
{ my $Nsig = -(4*$d-1+$w);
ok ($Nzero+$Nsig, $Nbase);
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok ($d+$wr, $want_x, 'X');
ok (3*$d+$w+$Nsig, $want_y, 'Y');
}
{ my $Nsig = -(2*$d+$w);
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok ($d+$wr, $want_x, 'X');
ok (3*$d+$w+$Nsig, $want_y, 'Y');
}
# top
{ my $Nsig = -(2*$d+$w);
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok (-$d-$wl-$Nsig, $want_x, 'X');
ok ($d, $want_y, 'Y');
}
{ my $Nsig = 0;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok (-$d-$wl-$Nsig, $want_x, 'X');
ok ($d, $want_y, 'Y');
}
# left downwards
{ my $Nsig = 0;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok (-$d-$wl, $want_x, 'X');
ok ($d-$Nsig, $want_y, 'Y');
}
{ my $Nsig = 2*$d;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok (-$d-$wl, $want_x, 'X');
ok ($d-$Nsig, $want_y, 'Y');
}
# bottom
{ my $Nsig = 2*$d;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok ($Nsig-$wl-3*$d, $want_x, 'X');
ok (-$d, $want_y, 'Y');
}
{ my $Nsig = 4*$d+1+$w;
my ($want_x,$want_y) = $path->n_to_xy($Nzero+$Nsig);
ok ($Nsig-$wl-3*$d, $want_x, 'X');
ok (-$d, $want_y, 'Y');
}
}
#------------------------------------------------------------------------------
# n_start, x_negative, y_negative
{
my $path = Math::PlanePath::SquareSpiral->new;
ok ($path->n_start, 1, 'n_start()');
ok ($path->x_negative, 1, 'x_negative() instance method');
ok ($path->y_negative, 1, 'y_negative() instance method');
ok ($path->class_x_negative, 1, 'class_x_negative()');
ok ($path->class_y_negative, 1, 'class_y_negative()');
}
{
my @pnames = map {$_->{'name'}}
Math::PlanePath::SquareSpiral->parameter_info_list;
ok (join(',',@pnames), 'wider,n_start');
}
#------------------------------------------------------------------------------
# n_to_xy
# 17 16 15 14 13
# 18 5 4 3 12
# 19 6 1 2 11
# 20 7 8 9 10
# 21 22 23 24 25 26
{
my @data = ([ 1, 0,0 ],
[ 2, 1,0 ],
[ 3, 1,1 ], # top
[ 4, 0,1 ],
[ 5, -1,1 ], # left
[ 6, -1,0 ],
[ 7, -1,-1 ], # bottom
[ 8, 0,-1 ],
[ 9, 1,-1 ],
[ 10, 2,-1 ], # right
[ 11, 2, 0 ],
[ 12, 2, 1 ],
[ 13, 2,2 ], # top
[ 14, 1,2 ],
[ 15, 0,2 ],
[ 16, -1,2 ],
[ 17, -2, 2 ], # left
[ 18, -2, 1 ],
[ 19, -2, 0 ],
[ 20, -2,-1 ],
[ 21, -2,-2 ], # bottom
[ 22, -1,-2 ],
[ 23, 0,-2 ],
[ 24, 1,-2 ],
[ 25, 2,-2 ],
[ 26, 3,-2 ], # right
[ 27, 3,-1 ],
);
my $path = Math::PlanePath::SquareSpiral->new;
foreach my $elem (@data) {
my ($n, $want_x, $want_y) = @$elem;
my ($got_x, $got_y) = $path->n_to_xy ($n);
ok ($got_x, $want_x, "x at n=$n");
ok ($got_y, $want_y, "y at n=$n");
}
foreach my $elem (@data) {
my ($want_n, $x, $y) = @$elem;
my $got_n = $path->xy_to_n ($x, $y);
ok ($got_n, $want_n, "n at x=$x,y=$y");
}
}
#------------------------------------------------------------------------------
# random n_to_dxdy()
{
foreach my $wider (0 .. 10) {
my $path = Math::PlanePath::SquareSpiral->new (wider => $wider);
# for (my $n = 1.25; $n < 40; $n++) {
foreach (1 .. 10) {
my $bits = int(rand(25)); # 0 to 25, inclusive
my $n = int(rand(2**$bits)) + 1; # 1 to 2^bits, inclusive
my ($x,$y) = $path->n_to_xy ($n);
my ($next_x,$next_y) = $path->n_to_xy ($n+1);
my $delta_dx = $next_x - $x;
my $delta_dy = $next_y - $y;
my ($func_dx,$func_dy) = $path->n_to_dxdy($n);
if ($func_dx == 0) { $func_dx = '0'; } # avoid -0 in perl 5.6
if ($func_dy == 0) { $func_dy = '0'; } # avoid -0 in perl 5.6
ok ($func_dx, $delta_dx, "n_to_dxdy($n) wider=$wider dx at xy=$x,$y");
ok ($func_dy, $delta_dy, "n_to_dxdy($n) wider=$wider dy at xy=$x,$y");
}
}
}
exit 0;