line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Kevin Ryde |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# This file is part of Math-PlanePath. |
4
|
|
|
|
|
|
|
# |
5
|
|
|
|
|
|
|
# Math-PlanePath is free software; you can redistribute it and/or modify |
6
|
|
|
|
|
|
|
# it under the terms of the GNU General Public License as published by the |
7
|
|
|
|
|
|
|
# Free Software Foundation; either version 3, or (at your option) any later |
8
|
|
|
|
|
|
|
# version. |
9
|
|
|
|
|
|
|
# |
10
|
|
|
|
|
|
|
# Math-PlanePath is distributed in the hope that it will be useful, but |
11
|
|
|
|
|
|
|
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
12
|
|
|
|
|
|
|
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
13
|
|
|
|
|
|
|
# for more details. |
14
|
|
|
|
|
|
|
# |
15
|
|
|
|
|
|
|
# You should have received a copy of the GNU General Public License along |
16
|
|
|
|
|
|
|
# with Math-PlanePath. If not, see . |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
# cute groupings |
21
|
|
|
|
|
|
|
# AztecDiamondRings, FibonacciWord fibonacci_word_type plain, 10x10 scale 15 |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
package Math::PlanePath::AztecDiamondRings; |
25
|
1
|
|
|
1
|
|
1383
|
use 5.004; |
|
1
|
|
|
|
|
4
|
|
26
|
1
|
|
|
1
|
|
7
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
67
|
|
27
|
|
|
|
|
|
|
#use List::Util 'min', 'max'; |
28
|
|
|
|
|
|
|
*min = \&Math::PlanePath::_min; |
29
|
|
|
|
|
|
|
*max = \&Math::PlanePath::_max; |
30
|
|
|
|
|
|
|
|
31
|
1
|
|
|
1
|
|
6
|
use vars '$VERSION', '@ISA'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
74
|
|
32
|
|
|
|
|
|
|
$VERSION = 129; |
33
|
1
|
|
|
1
|
|
796
|
use Math::PlanePath; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
53
|
|
34
|
|
|
|
|
|
|
@ISA = ('Math::PlanePath'); |
35
|
|
|
|
|
|
|
*_sqrtint = \&Math::PlanePath::_sqrtint; |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
use Math::PlanePath::Base::Generic |
38
|
1
|
|
|
1
|
|
6
|
'round_nearest'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
47
|
|
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
# uncomment this to run the ### lines |
41
|
|
|
|
|
|
|
# use Smart::Comments; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
|
44
|
1
|
|
|
|
|
50
|
use constant parameter_info_array => |
45
|
|
|
|
|
|
|
[ |
46
|
|
|
|
|
|
|
Math::PlanePath::Base::Generic::parameter_info_nstart1(), |
47
|
1
|
|
|
1
|
|
5
|
]; |
|
1
|
|
|
|
|
2
|
|
48
|
|
|
|
|
|
|
|
49
|
1
|
|
|
1
|
|
6
|
use constant n_frac_discontinuity => 0; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
39
|
|
50
|
1
|
|
|
1
|
|
6
|
use constant xy_is_visited => 1; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
113
|
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub x_negative_at_n { |
53
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
54
|
0
|
|
|
|
|
0
|
return $self->n_start + 1; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
sub y_negative_at_n { |
57
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
58
|
0
|
|
|
|
|
0
|
return $self->n_start + 2; |
59
|
|
|
|
|
|
|
} |
60
|
1
|
|
|
1
|
|
8
|
use constant dx_minimum => -1; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
60
|
|
61
|
1
|
|
|
1
|
|
7
|
use constant dx_maximum => 1; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
56
|
|
62
|
1
|
|
|
1
|
|
7
|
use constant dy_minimum => -1; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
45
|
|
63
|
1
|
|
|
1
|
|
6
|
use constant dy_maximum => 1; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
88
|
|
64
|
1
|
|
|
|
|
57
|
use constant 1.02 _UNDOCUMENTED__dxdy_list => (1,0, # E |
65
|
|
|
|
|
|
|
1,1, # NE |
66
|
|
|
|
|
|
|
# not North |
67
|
|
|
|
|
|
|
-1,1, # NW |
68
|
|
|
|
|
|
|
-1,0, # W |
69
|
|
|
|
|
|
|
-1,-1, # SW |
70
|
|
|
|
|
|
|
0,-1, # S |
71
|
1
|
|
|
1
|
|
8
|
1,-1); # SE; |
|
1
|
|
|
|
|
14
|
|
72
|
1
|
|
|
1
|
|
5
|
use constant dsumxy_minimum => -2; # diagonals |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
54
|
|
73
|
1
|
|
|
1
|
|
7
|
use constant dsumxy_maximum => 2; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
45
|
|
74
|
1
|
|
|
1
|
|
7
|
use constant ddiffxy_minimum => -2; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
65
|
|
75
|
1
|
|
|
1
|
|
7
|
use constant ddiffxy_maximum => 2; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
56
|
|
76
|
1
|
|
|
1
|
|
7
|
use constant dir_maximum_dxdy => (1,-1); # South-East |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
47
|
|
77
|
1
|
|
|
1
|
|
6
|
use constant turn_any_right => 0; # only left or straight |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
624
|
|
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
#------------------------------------------------------------------------------ |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub new { |
83
|
6
|
|
|
6
|
1
|
892
|
my $self = shift->SUPER::new(@_); |
84
|
6
|
100
|
|
|
|
25
|
if (! defined $self->{'n_start'}) { |
85
|
5
|
|
|
|
|
24
|
$self->{'n_start'} = $self->default_n_start; |
86
|
|
|
|
|
|
|
} |
87
|
6
|
|
|
|
|
16
|
return $self; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# starting from X axis and n_start=0 |
91
|
|
|
|
|
|
|
# d = [ 1, 2, 3, 4, 5 ] |
92
|
|
|
|
|
|
|
# n = [ 0,4,12,24,40 ] |
93
|
|
|
|
|
|
|
# N = (2 d^2 - 2 d) |
94
|
|
|
|
|
|
|
# = (2*$d**2 - 2*$d) |
95
|
|
|
|
|
|
|
# = ((2*$d - 2)*$d) |
96
|
|
|
|
|
|
|
# d = 1/2 + sqrt(1/2 * $n + 1/4) |
97
|
|
|
|
|
|
|
# = (sqrt(2*$n+1) + 1)/2 |
98
|
|
|
|
|
|
|
# |
99
|
|
|
|
|
|
|
# X negative axis |
100
|
|
|
|
|
|
|
# d = [ 1, 2, 3, 4,5 ] |
101
|
|
|
|
|
|
|
# n = [ 2, 8, 18, 32, 50 ] |
102
|
|
|
|
|
|
|
# N = (2 d^2) |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
sub n_to_xy { |
105
|
115
|
|
|
115
|
1
|
9380
|
my ($self, $n) = @_; |
106
|
|
|
|
|
|
|
#### n_to_xy: $n |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# adjust to N=0 at origin X=0,Y=0 |
109
|
115
|
|
|
|
|
189
|
$n = $n - $self->{'n_start'}; |
110
|
115
|
50
|
|
|
|
257
|
if ($n < 0) { return; } |
|
0
|
|
|
|
|
0
|
|
111
|
|
|
|
|
|
|
|
112
|
115
|
|
|
|
|
300
|
my $d = int( (_sqrtint(2*$n+1) + 1)/2 ); |
113
|
115
|
|
|
|
|
216
|
$n -= 2*$d*$d; # to $n=0 half way around at horiz Y=-1 X<-1 |
114
|
|
|
|
|
|
|
|
115
|
115
|
100
|
|
|
|
218
|
if ($n < 0) { |
116
|
73
|
|
|
|
|
125
|
my $x = -$d-$n-1; |
117
|
73
|
100
|
|
|
|
134
|
if ($n < -$d) { |
118
|
|
|
|
|
|
|
# top-right |
119
|
55
|
|
|
|
|
125
|
return ($x, |
120
|
|
|
|
|
|
|
min($n+2*$d, $d-1)); |
121
|
|
|
|
|
|
|
} else { |
122
|
|
|
|
|
|
|
# top-left |
123
|
18
|
|
|
|
|
40
|
return (max($x, -$d), |
124
|
|
|
|
|
|
|
-1-$n); |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
} else { |
127
|
42
|
|
|
|
|
67
|
my $x = $n-$d; |
128
|
42
|
100
|
|
|
|
64
|
if ($n < $d) { |
129
|
|
|
|
|
|
|
# bottom-left |
130
|
18
|
|
|
|
|
26
|
my $y = -1-$n; |
131
|
18
|
|
|
|
|
39
|
return ($x, |
132
|
|
|
|
|
|
|
max($y, -$d)); |
133
|
|
|
|
|
|
|
} else { |
134
|
|
|
|
|
|
|
# bottom-right |
135
|
24
|
|
|
|
|
49
|
return (min($x, $d-1), |
136
|
|
|
|
|
|
|
$n-2*$d); |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub xy_to_n { |
142
|
52
|
|
|
52
|
1
|
1016
|
my ($self, $x, $y) = @_; |
143
|
|
|
|
|
|
|
### AztecDiamondRings xy_to_n(): "$x, $y" |
144
|
|
|
|
|
|
|
|
145
|
52
|
|
|
|
|
100
|
$x = round_nearest ($x); |
146
|
52
|
|
|
|
|
102
|
$y = round_nearest ($y); |
147
|
|
|
|
|
|
|
|
148
|
52
|
100
|
|
|
|
98
|
if ($x >= 0) { |
149
|
31
|
|
|
|
|
54
|
my $d = $x + abs($y); |
150
|
31
|
|
|
|
|
90
|
return (2*$d + 2)*$d + $y + $self->{'n_start'}; |
151
|
|
|
|
|
|
|
} |
152
|
21
|
100
|
|
|
|
37
|
if ($y >= 0) { |
153
|
14
|
|
|
|
|
18
|
my $d = $y - $x; |
154
|
14
|
|
|
|
|
51
|
return 2*$d*$d - 1 - $y + $self->{'n_start'}; |
155
|
|
|
|
|
|
|
} else { |
156
|
7
|
|
|
|
|
12
|
my $d = $y + $x; |
157
|
7
|
|
|
|
|
20
|
return (2*$d + 4)*$d + 1 - $y + $self->{'n_start'}; |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
# | | x2>=-x1 | |
163
|
|
|
|
|
|
|
# M---+ | M-------M | +---M |
164
|
|
|
|
|
|
|
# | | | | | | | | | |
165
|
|
|
|
|
|
|
# +---m | +----m--+ | m---+ |
166
|
|
|
|
|
|
|
# | | | |
167
|
|
|
|
|
|
|
# -----+------ -------+------- -----+-------- |
168
|
|
|
|
|
|
|
# | | | |
169
|
|
|
|
|
|
|
# |
170
|
|
|
|
|
|
|
# | | | |
171
|
|
|
|
|
|
|
# M---+ | M-------M y2>=-y1 | +---M |
172
|
|
|
|
|
|
|
# | | | | | | | | | |
173
|
|
|
|
|
|
|
# | m | | | | | m | |
174
|
|
|
|
|
|
|
# -------+------ -------m------- -----+-------- |
175
|
|
|
|
|
|
|
# | | | | | | | | | |
176
|
|
|
|
|
|
|
# M---+ | M-------M | +---M |
177
|
|
|
|
|
|
|
# | | | |
178
|
|
|
|
|
|
|
# |
179
|
|
|
|
|
|
|
# | | | |
180
|
|
|
|
|
|
|
# -----+------ -------+------- -----+-------- |
181
|
|
|
|
|
|
|
# | | | |
182
|
|
|
|
|
|
|
# +---m | +--m----+ | m---+ |
183
|
|
|
|
|
|
|
# | | | | | | | | | |
184
|
|
|
|
|
|
|
# M---+ | M-------M | +---M |
185
|
|
|
|
|
|
|
# | | | |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
# exact |
188
|
|
|
|
|
|
|
sub rect_to_n_range { |
189
|
22
|
|
|
22
|
1
|
1882
|
my ($self, $x1,$y1, $x2,$y2) = @_; |
190
|
|
|
|
|
|
|
### AztecDiamondRings rect_to_n_range(): "$x1,$y1, $x2,$y2" |
191
|
|
|
|
|
|
|
|
192
|
22
|
|
|
|
|
52
|
$x1 = round_nearest ($x1); |
193
|
22
|
|
|
|
|
43
|
$y1 = round_nearest ($y1); |
194
|
22
|
|
|
|
|
43
|
$x2 = round_nearest ($x2); |
195
|
22
|
|
|
|
|
44
|
$y2 = round_nearest ($y2); |
196
|
|
|
|
|
|
|
|
197
|
22
|
100
|
|
|
|
50
|
($x1,$x2) = ($x2,$x1) if $x1 > $x2; |
198
|
22
|
100
|
|
|
|
42
|
($y1,$y2) = ($y2,$y1) if $y1 > $y2; |
199
|
|
|
|
|
|
|
|
200
|
22
|
|
|
|
|
83
|
my $min_x = 0; |
201
|
22
|
100
|
|
|
|
60
|
my $min_y = ($y2 < 0 ? ($min_x = -1, $y2) |
|
|
100
|
|
|
|
|
|
202
|
|
|
|
|
|
|
: $y1 > 0 ? $y1 |
203
|
|
|
|
|
|
|
: 0); |
204
|
22
|
100
|
|
|
|
48
|
if ($x2 < $min_x) { $min_x = $x2 } # right edge if 0/-1 not covered |
|
4
|
100
|
|
|
|
7
|
|
205
|
3
|
|
|
|
|
4
|
elsif ($x1 > $min_x) { $min_x = $x1 } # left edge if 0/-1 not covered |
206
|
|
|
|
|
|
|
|
207
|
22
|
100
|
|
|
|
42
|
my $max_y = ($y2 >= -$y1 ? $y2 : $y1); |
208
|
22
|
100
|
|
|
|
45
|
my $max_x = ($x2 >= -$x1-($max_y<0) ? $x2 : $x1); |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
### min at: "$min_x, $min_y" |
211
|
|
|
|
|
|
|
### max at: "$max_x, $max_y" |
212
|
22
|
|
|
|
|
45
|
return ($self->xy_to_n($min_x,$min_y), |
213
|
|
|
|
|
|
|
$self->xy_to_n($max_x,$max_y)); |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
1; |
217
|
|
|
|
|
|
|
__END__ |