File: Calc.pod

package info (click to toggle)
libmath-polygon-perl 2.00-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 256 kB
  • sloc: perl: 1,618; makefile: 2
file content (199 lines) | stat: -rw-r--r-- 5,430 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
=encoding utf8

=head1 NAME

Math::Polygon::Calc - Simple polygon calculations

=head1 INHERITANCE

 Math::Polygon::Calc
   is an Exporter

=head1 SYNOPSIS

  my @poly = ( [1,2], [2,4], [5,7], [1, 2] );

  my ($xmin, $ymin, $xmax, $ymax) = polygon_bbox @poly;

  my $area = polygon_area @poly;
  MY $L    = polygon_perimeter @poly;
  if(polygon_is_clockwise @poly) { ... };

  my @rot  = polygon_start_minxy @poly;

=head1 DESCRIPTION

This package contains a wide variaty of relatively easy polygon
calculations.  More complex calculations are put in separate
packages.

=head1 FUNCTIONS

=over 4

=item B<polygon_area>(@points)

Returns the area enclosed by the polygon.  The last point of the list
must be the same as the first to produce a correct result.

The algorithm was found at L<https://mathworld.wolfram.com/PolygonArea.html>,
and sounds:

  A = abs( 1/2 * (x1y2-x2y1 + x2y3-x3y2 ...)

=item B<polygon_bbox>(@points)

Returns a list with four elements: (xmin, ymin, xmax, ymax), which describe
the bounding box of the polygon (all points of the polygon are within that
area.

=item B<polygon_beautify>( [\%options], @points )

Polygons, certainly after some computations, can have a lot of
horrible artifacts: points which are double, spikes, etc.
The optional HASH contains the C<%options>.

 -Option       --Default
  remove_spikes  <C<false>>

=over 2

=item remove_spikes => BOOLEAN

Spikes contain of three successive points, where the first is on the
line between the second and the third.  The line goes from first to
second, but then back to get to the third point.

At the moment, only pure horizontal and pure vertical spikes are
removed.

=back

=item B<polygon_centroid>( [%options|\%options], @points )

Returns the centroid location of the polygon.

The last point of the list must be the same as the first (must be
'closed') to produce a correct result.

B<warning:> When the polygon is very flat, it will not produce a
stable result: minor changes in single coordinates will move the
centroid too far.

The algorithm was found at
L<https://en.wikipedia.org/wiki/Centroid#Of_a_polygon>

 -Option  --Default
  is_large  false

=over 2

=item is_large => BOOLEAN

When the polygon is small and far from the origin C<(0,0)> (as often
happens when processing geo coordinates), then rounding errors will have a
large impact on result of the algorithm.  To avoid this, we will move the
poly first close to the origin, and move the calculated center point back.

This transform, which cost modest performance, can be disabled with
this option.  The transformation will also not happen when the first
C<x> coordinate is an object, like Math::BigFloat.

=back

=item B<polygon_clockwise>(@points)

Be sure the polygon points are in clockwise order.

=item B<polygon_contains_point>($point, @points)

Returns C<true> if the point is inside the closed polygon.  On an edge will
be flagged as 'inside'.  But be warned of rounding issues, caused by
the floating-point calculations used by this algorithm.

=item B<polygon_counter_clockwise>(@points)

Be sure the polygon points are in counter-clockwise order.

=item B<polygon_distance>($point, @polygon)

[1.05] calculate the shortest distance between a point and any vertex of
a closed polygon.

=item B<polygon_equal>( \@points1, \@points2, [$tolerance] )

Compare two polygons, on the level of points. When the polygons are
the same but rotated, this will return C<false>. See L<polygon_same()|Math::Polygon::Calc/"FUNCTIONS">.

=item B<polygon_format>($format, @points)

[1.07] Map the C<$format> over all C<@points>, both the X and Y coordinate.  This
is especially useful to reduce the number of digits in the stringification.
For instance, when you want reproducible results in regression scripts.

The format is anything supported by C<printf()>, for instance C<"%5.2f">.  Or,
you can pass a code reference which accepts a single value.

=item B<polygon_is_clockwise>(@points)

Z<>

=item B<polygon_is_closed>(@points)

Z<>

=item B<polygon_perimeter>(@points)

The length of the line of the polygon.  This can also be used to compute
the length of any line: of the last point is not equal to the first, then
a line is presumed; for a polygon they must match.

This is simply Pythagoras.

  $l = sqrt((x1-x0)^2 + (y1-y0)^2) + sqrt((x2-x1)^2+(y2-y1)^2) + ...

=item B<polygon_same>( \@points1, \@points2, [$tolerance] )

[1.12] Compare two polygons, where the polygons may be rotated or mirrored
wrt each other. This is (much) slower than L<polygon_equal()|Math::Polygon::Calc/"FUNCTIONS">, but some
algorithms will cause un unpredictable rotation in the result.

=item B<polygon_start_minxy>(@points)

Returns the polygon, where the point which is closest to the left-bottom
corner of the bounding box is made first.

=item B<polygon_string>(@points)

Z<>

=back

=head1 DIAGNOSTICS

=over 4

=item Error: empty polygon is neither closed nor open

Cast by polygon_is_closed()

=item Error: polygon points on a line, so no centroid

Cast by polygon_centroid()

=back

=head1 SEE ALSO

This module is part of Math-Polygon version 2.00,
built on September 04, 2025. Website: F<http://perl.overmeer.net/CPAN/>

=head1 LICENSE

For contributors see file ChangeLog.

This software is copyright (c) 2004-2025 by Mark Overmeer.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.