.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Math::Polygon::Calc 3pm" .TH Math::Polygon::Calc 3pm "2022-10-13" "perl v5.34.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Math::Polygon::Calc \- Simple polygon calculations .SH "INHERITANCE" .IX Header "INHERITANCE" .Vb 2 \& Math::Polygon::Calc \& is a Exporter .Ve .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& 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; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" This package contains a wide variaty of relatively easy polygon calculations. More complex calculations are put in separate packages. .SH "FUNCTIONS" .IX Header "FUNCTIONS" .IP "\fBpolygon_area\fR(@points)" 4 .IX Item "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. .Sp The algorithm was found at , and sounds: .Sp .Vb 1 \& A = abs( 1/2 * (x1y2\-x2y1 + x2y3\-x3y2 ...) .Ve .IP "\fBpolygon_bbox\fR(@points)" 4 .IX Item "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. .ie n .IP "\fBpolygon_beautify\fR( [\e%options], @points )" 4 .el .IP "\fBpolygon_beautify\fR( [\e%options], \f(CW@points\fR )" 4 .IX Item "polygon_beautify( [%options], @points )" Polygons, certainly after some computations, can have a lot of horrible artifacts: points which are double, spikes, etc. The optional \s-1HASH\s0 contains the \f(CW%options\fR. .Sp .Vb 2 \& \-Option \-\-Default \& remove_spikes .Ve .RS 4 .IP "remove_spikes => \s-1BOOLEAN\s0" 2 .IX 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. .Sp At the moment, only pure horizontal and pure vertical spikes are removed. .RE .RS 4 .RE .IP "\fBpolygon_centroid\fR(@points)" 4 .IX Item "polygon_centroid(@points)" Returns the centroid location of the polygon. The last point of the list must be the same as the first to produce a correct result. .Sp The algorithm was found at \&\fIhttp://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon\fR .IP "\fBpolygon_clockwise\fR(@points)" 4 .IX Item "polygon_clockwise(@points)" Be sure the polygon points are in clockwise order. .ie n .IP "\fBpolygon_contains_point\fR($point, @points)" 4 .el .IP "\fBpolygon_contains_point\fR($point, \f(CW@points\fR)" 4 .IX Item "polygon_contains_point($point, @points)" Returns 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. .IP "\fBpolygon_counter_clockwise\fR(@points)" 4 .IX Item "polygon_counter_clockwise(@points)" Be sure the polygon points are in counter-clockwise order. .ie n .IP "\fBpolygon_distance\fR($point, @polygon)" 4 .el .IP "\fBpolygon_distance\fR($point, \f(CW@polygon\fR)" 4 .IX Item "polygon_distance($point, @polygon)" [1.05] calculate the shortest distance between a point and any vertex of a closed polygon. .IP "\fBpolygon_equal\fR( \e@points1, \e@points2, [$tolerance] )" 4 .IX Item "polygon_equal( @points1, @points2, [$tolerance] )" Compare two polygons, on the level of points. When the polygons are the same but rotated, this will return false. See \fBpolygon_same()\fR. .ie n .IP "\fBpolygon_format\fR($format, @points)" 4 .el .IP "\fBpolygon_format\fR($format, \f(CW@points\fR)" 4 .IX Item "polygon_format($format, @points)" [1.07] Map the \f(CW$format\fR over all \f(CW@points\fR, 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. .Sp The format is anything supported by \fBprintf()\fR, for instance \*(L"%5.2f\*(R". Or, you can pass a code reference which accepts a single value. .IP "\fBpolygon_is_clockwise\fR(@points)" 4 .IX Item "polygon_is_clockwise(@points)" .PD 0 .IP "\fBpolygon_is_closed\fR(@points)" 4 .IX Item "polygon_is_closed(@points)" .IP "\fBpolygon_perimeter\fR(@points)" 4 .IX Item "polygon_perimeter(@points)" .PD 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. .Sp This is simply Pythagoras. .Sp .Vb 1 \& $l = sqrt((x1\-x0)^2 + (y1\-y0)^2) + sqrt((x2\-x1)^2+(y2\-y1)^2) + ... .Ve .IP "\fBpolygon_same\fR( \e@points1, \e@points2, [$tolerance] )" 4 .IX Item "polygon_same( @points1, @points2, [$tolerance] )" Compare two polygons, where the polygons may be rotated wrt each other. This is (much) slower than \fBpolygon_equal()\fR, but some algorithms will cause un unpredictable rotation in the result. .IP "\fBpolygon_start_minxy\fR(@points)" 4 .IX Item "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. .IP "\fBpolygon_string\fR(@points)" 4 .IX Item "polygon_string(@points)" .SH "SEE ALSO" .IX Header "SEE ALSO" This module is part of Math-Polygon distribution version 1.10, built on January 03, 2018. Website: \fIhttp://perl.overmeer.net/CPAN/\fR .SH "LICENSE" .IX Header "LICENSE" Copyrights 2004\-2018 by [Mark Overmeer]. For other contributors see ChangeLog. .PP This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See \fIhttp://dev.perl.org/licenses/\fR