sub Diferencias { # Cálculo de las diferencias entre dos polígonos my ($base,$i,$sup,$j) = @_; # Creamos objeto polígono base my $gpc_base = Math::Geometry::Planar::GPC::Polygon->new(); # Añadir primero el contorno principal $gpc_base->add_polygon(\@{$Contornos{$base}[$i][0]}, 0); # Añadir luego los agujeros que tenga my $num_pol = @{$Contornos{$base}[$i]}; foreach my $agujero ( 1 .. $num_pol-1 ) { $gpc_base->add_polygon(\@{$Contornos{$base}[$i][$agujero]}, 1); } # Idem para el polígono a restart my $gpc_sup = Math::Geometry::Planar::GPC::Polygon->new(); $gpc_sup->add_polygon(\@{$Contornos{$sup}[$j][0]}, 0); # Calcular diferencias my $gpc_res = $gpc_base->clip_to($gpc_sup, 'DIFFERENCE'); undef $gpc_base; undef $gpc_sup; my $res = $gpc_res->as_string(); # Si no hay diferencias, salir inmediatamente # If the result of operation is null, the two polygons aren't coincidences. return if $res eq ''; # Almacenar resultado my @p = $gpc_res->get_polygons; @{$Contornos{$base}[$i]} = (); # A new definition of this contour foreach my $poly ( 0..$#p ) { # HERE ARE THE TRICK: # WE READ THE @p LIST OF POLYGONS RESULT OF DIFFERENCE OPERATION ->and<- # HOPE THIS N-1 ->FIRST<- POLYGONS ARE THE HOLES OF THE BIGGER POLYGON, THAT # THESE POINTS ARE IN THE ->LAST<- POLYGON OF @p LIST. # SO, WE READ THE LIST IN ->REVERSE<- ($#p-$poly) TO READ FIRST THE BIG POLYGON (the convex hull) # AND NEXT, THE HOLES. # We need to use the clone method of Clone module to make a copy of all struct return by gpc, because # are freed afterwards. # Here, I'm storing the points in a 4D struct: # $base is the value (altitude) of the contour base we are subtracting $sup contour # $i is the number of contour into $base value contours # $j is the number of contour into $sup value contours # %Contornos is a hash of arrays to arrays to arrays. # Every key of %Contornos is a altitude value (or the physic value you set to the contours) # Every altitude value is an array of contours of the same physic value ($base). # Every $i-contour of $base value is an array of polygons ($poly). # -> THE FIRST POLYGON IS THE 'BIG' POLYGON AND NEXT ARE THE HOLES OF THIS POLYGON <- # And every polygon is an array of points (the parent @{}): @{ $Contornos{$base}[$i][$poly] } = @{ clone(\@{$p[$#p - $poly]}) }; # # (These lines work the same the one above) # my $k = $#p - $poly; # foreach my $j ( @{$p[$k]} ) # { # $Contornos{$base}[$i][$poly][$j][0] = $p[$k][$j][0]; # $Contornos{$base}[$i][$poly][$j][1] = $p[$k][$j][1]; # } } # important: free memory undef $gpc_res; }