package Manticore::Geometry::Polygon; use strict; use warnings; use POSIX; use Math::Trig; use Manticore::Geometry::Vector; # Data representation: # List of {p=>polygon, v=>value} # Each of these polygons shall be normalized, hence intersection free with itself # Value is summarized if several polygons are around the same point # Polygons are a list of points sub new { my ($pkg, $pts) = @_; return bless $pts; } # Angle between 3 points A B C, that is between the line segments AB and BC sub _threePointAngular { my ($A, $B, $C) = @_; my $AB = $B->diff($A); my $BC = $C->diff($B); #$_ = $_->asFloatVector($_) for $AB, $BC; #my $cos = $AB->scalar($BC)/$AB->size()/$BC->size(); #my $phi = acos($cos); #$phi -= 2*pi if $phi>pi; #return $phi; my $phi = $BC->angle() - $AB->angle(); $phi -= 2*pi if $phi>pi; $phi += 2*pi if $phi<-pi; return $phi } # Count of full circles done by the polygon, that is the # Angular sum over all corners divided by 2pi; # shall be 1 for normalized polygons # computed as floats as we only need the precision of what multiple # of 2pi it is # the result is then rounded to the next integer number sub fullCircles { my $self = shift; my $sum = 0; for(0..$#$self) { $sum += _threePointAngular(@{$self}[$_-2,$_-1,$_]); } my $ret = $sum/(2*pi); floor($ret+0.5) } 1;