package Geometry::Primitive::Polygon; use Moose; use MooseX::Storage; extends 'Geometry::Primitive'; with qw(Geometry::Primitive::Shape MooseX::Clone); with Storage(format => 'JSON', io => 'File'); has 'points' => ( traits => [ qw(Array Clone) ], is => 'rw', isa => 'ArrayRef[Geometry::Primitive::Point]', default => sub { [] }, handles => { add_point => 'push', clear_points=> 'clear', get_point => 'get', point_count => 'count' } ); sub area { my ($self) = @_; # http://mathworld.wolfram.com/PolygonArea.html my $area = 0; my $last = $self->get_point(0); for (my $i = 1; $i < $self->point_count; $i++) { my $curr = $self->get_point($i); $area += ($last->x * $curr->y) - ($curr->x * $last->y); $last = $curr; } return abs($area / 2); } sub point_end { my ($self) = @_; return $self->get_point($self->point_count - 1); } sub point_start { my ($self) = @_; return $self->get_point(0); } sub scale { my ($self, $amount) = @_; foreach my $p (@{ $self->points }) { $p->x($p->x * $amount); $p->y($p->y * $amount); } } __PACKAGE__->meta->make_immutable; no Moose; 1; __END__ =head1 NAME Geometry::Primitive::Polygon - Closed shape with an arbitrary number of points. =head1 DESCRIPTION Geometry::Primitive::Polygon represents a two dimensional figure bounded by a series of points that represent a closed path. =head1 SYNOPSIS use Geometry::Primitive::Polygon; my $poly = Geometry::Primitive::Polygon->new; $poly->add_point($point1); $poly->add_point($point2); $poly->add_point($point3); # No need to close the path, it's handled automatically =head1 ATTRIBUTES =head2 points Set/Get the arrayref of points that make up this Polygon. =head1 METHODS =head2 new Creates a new Geometry::Primitive::Polygon =head2 area Area of this polygon. Assumes it is non-self-intersecting. =head2 add_point Add a point to this polygon. =head2 clear_points Clears all points from this polygon. =head2 point_count Returns the number of points that bound this polygon. =head2 get_point Returns the point at the specified offset. =head2 point_end Get the end point. Provided for Shape role. =head2 point_start Get the start point. Provided for Shape role. =head2 scale ($amount) Scale this this polygon by the supplied amount. =head1 AUTHOR Cory Watson =head1 COPYRIGHT & LICENSE You can redistribute and/or modify this code under the same terms as Perl itself.