File Coverage

blib/lib/Math/Polygon.pm
Criterion Covered Total %
statement 70 124 56.4
branch 17 40 42.5
condition 7 16 43.7
subroutine 19 35 54.2
pod 28 29 96.5
total 141 244 57.7


line stmt bran cond sub pod time code
1             # Copyrights 2004-2018 by [Mark Overmeer].
2             # For other contributors see ChangeLog.
3             # See the manual pages for details on the licensing terms.
4             # Pod stripped from pm file by OODoc 2.02.
5             # This code is part of distribution Math::Polygon. Meta-POD processed with
6             # OODoc into POD and HTML manual-pages. See README.md
7             # Copyright Mark Overmeer. Licensed under the same terms as Perl itself.
8              
9             package Math::Polygon;
10 3     3   49739 use vars '$VERSION';
  3         10  
  3         124  
11             $VERSION = '1.10';
12              
13              
14 3     3   14 use strict;
  3         4  
  3         53  
15 3     3   12 use warnings;
  3         4  
  3         60  
16              
17 3     3   1125 use Math::Polygon::Calc;
  3         5  
  3         221  
18 3     3   1033 use Math::Polygon::Clip;
  3         6  
  3         126  
19 3     3   1250 use Math::Polygon::Transform;
  3         7  
  3         3883  
20              
21              
22             sub new(@)
23 12     12 1 1048 { my $thing = shift;
24 12   66     35 my $class = ref $thing || $thing;
25              
26 12         15 my @points;
27             my %options;
28 12 100       45 if(ref $thing)
29 3         5 { $options{clockwise} = $thing->{MP_clockwise};
30             }
31              
32 12         22 while(@_)
33 35 100       56 { if(ref $_[0] eq 'ARRAY') {push @points, shift}
  29         66  
34 6         6 else { my $k = shift; $options{$k} = shift }
  6         13  
35             }
36 12         20 $options{_points} = \@points;
37              
38 12         33 (bless {}, $class)->init(\%options);
39             }
40              
41             sub init($$)
42 12     12 0 21 { my ($self, $args) = @_;
43 12   66     40 $self->{MP_points} = $args->{points} || $args->{_points};
44 12         17 $self->{MP_clockwise} = $args->{clockwise};
45 12         28 $self->{MP_bbox} = $args->{bbox};
46 12         46 $self;
47             }
48              
49             #------------------
50              
51              
52 7     7 1 2946 sub nrPoints() { scalar @{shift->{MP_points}} }
  7         33  
53              
54              
55 1     1 1 1 sub order() { @{shift->{MP_points}} -1 }
  1         4  
56              
57              
58             sub points(;$)
59 15     15 1 25 { my ($self, $format) = @_;
60 15         18 my $points = $self->{MP_points};
61 15 100       26 $points = [ polygon_format $format, @$points ] if $format;
62 15 100       52 wantarray ? @$points : $points;
63             }
64              
65              
66             sub point(@)
67 3     3 1 914 { my $points = shift->{MP_points};
68 3 100       8 wantarray ? @{$points}[@_] : $points->[shift];
  1         4  
69             }
70              
71             #------------------
72              
73              
74             sub bbox()
75 0     0 1 0 { my $self = shift;
76 0 0       0 return @{$self->{MP_bbox}} if $self->{MP_bbox};
  0         0  
77              
78 0         0 my @bbox = polygon_bbox $self->points;
79 0         0 $self->{MP_bbox} = \@bbox;
80 0         0 @bbox;
81             }
82              
83              
84             sub area()
85 1     1 1 2 { my $self = shift;
86 1 50       3 return $self->{MP_area} if defined $self->{MP_area};
87 1         3 $self->{MP_area} = polygon_area $self->points;
88             }
89              
90             sub centroid()
91 0     0 1 0 { my $self = shift;
92 0 0       0 return $self->{MP_centroid} if $self->{MP_centroid};
93 0         0 $self->{MP_centroid} = polygon_centroid $self->points;
94             }
95              
96              
97             sub isClockwise()
98 3     3 1 5 { my $self = shift;
99 3 100       10 return $self->{MP_clockwise} if defined $self->{MP_clockwise};
100 1         2 $self->{MP_clockwise} = polygon_is_clockwise $self->points;
101             }
102              
103              
104             sub clockwise()
105 0     0 1 0 { my $self = shift;
106 0 0       0 return $self if $self->isClockwise;
107              
108 0         0 $self->{MP_points} = [ reverse $self->points ];
109 0         0 $self->{MP_clockwise} = 1;
110 0         0 $self;
111             }
112              
113              
114             sub counterClockwise()
115 0     0 1 0 { my $self = shift;
116 0 0       0 return $self unless $self->isClockwise;
117              
118 0         0 $self->{MP_points} = [ reverse $self->points ];
119 0         0 $self->{MP_clockwise} = 0;
120 0         0 $self;
121             }
122              
123              
124 0     0 1 0 sub perimeter() { polygon_perimeter shift->points }
125              
126              
127             sub startMinXY()
128 2     2 1 5 { my $self = shift;
129 2         4 $self->new(polygon_start_minxy $self->points);
130             }
131              
132              
133             sub beautify(@)
134 0     0 1 0 { my ($self, %opts) = @_;
135 0         0 my @beauty = polygon_beautify \%opts, $self->points;
136 0 0       0 @beauty > 2 ? $self->new(points => \@beauty) : ();
137             }
138              
139              
140             sub equal($;@)
141 3     3 1 877 { my $self = shift;
142 3         4 my ($other, $tolerance);
143 3 100 66     11 if(@_ > 2 || ref $_[1] eq 'ARRAY') { $other = \@_ }
  2         3  
144             else
145 1 50       11 { $other = ref $_[0] eq 'ARRAY' ? shift : shift->points;
146 1         2 $tolerance = shift;
147             }
148 3         5 polygon_equal scalar($self->points), $other, $tolerance;
149             }
150              
151              
152             sub same($;@)
153 2     2 1 3 { my $self = shift;
154 2         2 my ($other, $tolerance);
155 2 50 33     7 if(@_ > 2 || ref $_[1] eq 'ARRAY') { $other = \@_ }
  2         3  
156             else
157 0 0       0 { $other = ref $_[0] eq 'ARRAY' ? shift : shift->points;
158 0         0 $tolerance = shift;
159             }
160 2         4 polygon_same scalar($self->points), $other, $tolerance;
161             }
162              
163              
164             sub contains($)
165 0     0 1 0 { my ($self, $point) = @_;
166 0         0 polygon_contains_point($point, $self->points);
167             }
168              
169              
170             sub distance($)
171 0     0 1 0 { my ($self, $point) = @_;
172 0         0 polygon_distance($point, $self->points);
173             }
174              
175              
176 0     0 1 0 sub isClosed() { polygon_is_closed(shift->points) }
177              
178             #------------------
179              
180              
181             sub resize(@)
182 0     0 1 0 { my $self = shift;
183              
184 0         0 my $clockwise = $self->{MP_clockwise};
185 0 0       0 if(defined $clockwise)
186 0         0 { my %args = @_;
187 0   0     0 my $xscale = $args{xscale} || $args{scale} || 1;
188 0   0     0 my $yscale = $args{yscale} || $args{scale} || 1;
189 0 0       0 $clockwise = not $clockwise if $xscale * $yscale < 0;
190             }
191              
192 0         0 (ref $self)->new
193             ( points => [ polygon_resize @_, $self->points ]
194             , clockwise => $clockwise
195             # we could save the bbox calculation as well
196             );
197             }
198              
199              
200             sub move(@)
201 0     0 1 0 { my $self = shift;
202              
203             (ref $self)->new
204             ( points => [ polygon_move @_, $self->points ]
205             , clockwise => $self->{MP_clockwise}
206             , bbox => $self->{MP_bbox}
207 0         0 );
208             }
209              
210              
211             sub rotate(@)
212 0     0 1 0 { my $self = shift;
213              
214             (ref $self)->new
215             ( points => [ polygon_rotate @_, $self->points ]
216             , clockwise => $self->{MP_clockwise}
217             # we could save the bbox calculation as well
218 0         0 );
219             }
220              
221              
222             sub grid(@)
223 0     0 1 0 { my $self = shift;
224              
225             (ref $self)->new
226             ( points => [ polygon_grid @_, $self->points ]
227             , clockwise => $self->{MP_clockwise} # probably
228             # we could save the bbox calculation as well
229 0         0 );
230             }
231              
232              
233             sub mirror(@)
234 0     0 1 0 { my $self = shift;
235              
236 0         0 my $clockwise = $self->{MP_clockwise};
237 0 0       0 $clockwise = not $clockwise if defined $clockwise;
238              
239 0         0 (ref $self)->new
240             ( points => [ polygon_mirror @_, $self->points ]
241             , clockwise => $clockwise
242             # we could save the bbox calculation as well
243             );
244             }
245              
246              
247             sub simplify(@)
248 0     0 1 0 { my $self = shift;
249              
250             (ref $self)->new
251             ( points => [ polygon_simplify @_, $self->points ]
252             , clockwise => $self->{MP_clockwise} # probably
253             , bbox => $self->{MP_bbox} # protect bounds
254 0         0 );
255             }
256              
257             #------------------
258              
259              
260             sub lineClip($$$$)
261 1     1 1 2 { my ($self, @bbox) = @_;
262 1         3 polygon_line_clip \@bbox, $self->points;
263             }
264              
265              
266             sub fillClip1($$$$)
267 0     0 1 0 { my ($self, @bbox) = @_;
268 0         0 my @clip = polygon_fill_clip1 \@bbox, $self->points;
269 0 0       0 @clip or return undef;
270 0         0 $self->new(points => \@clip);
271             }
272              
273             #-------------
274              
275              
276             sub string(;$)
277 3     3 1 3217 { my ($self, $format) = @_;
278 3         8 polygon_string($self->points($format));
279             }
280              
281             1;