# [complex-hull.pm] 31.01.1999 R.Scholz <Voland@Jena.Thur.de> # # Time-stamp: <31.01.1999, 22:01:07, mrz@isun24> # # This modul calculates the complex hull of a data file # # It implements the wrap-algorithm you find in the book from Sedgewick sub theta { my($rp1, $rp2)=@_; my($dx,$dy,$ax,$ay,$t, %p1,%p2); %p1=%$rp1; %p2=%$rp2; $dx=$p2{x} - $p1{x}; $ax=abs($dx); $dy=$p2{y} - $p1{y}; $ay=abs($dy); if($dx==0 && $dy==0) { $t=0; } else { $t=$dy/($ax+$ay);} if($dx<0) { $t=2-$t; } elsif($dy<0) { $t+=4; } return($t*90.0); } sub wrap { my($max, @points)=@_; my($i, $min, $M, $minangle, $tp); $min=0; $tp={}; for($i=1; $i<=$max; $i++) { $min=$i if( ($points[$i]{y}) < ($points[$min]{y}) ); } $points[$max+1]{x}=$points[$min]{x}; $points[$max+1]{y}=$points[$min]{y}; $minangle=0.0; $M=-1; do { $M++; $tp->{x}=$points[$M]{x}; $tp->{y}=$points[$M]{y}; $tp->{D}=$points[$M]{D}; $points[$M]{x}=$points[$min]{x}; $points[$M]{y}=$points[$min]{y}; $points[$M]{D}=$points[$min]{D}; $points[$min]{x}=$tp->{x}; $points[$min]{y}=$tp->{y}; $points[$min]{D}=$tp->{D}; $min=$max+1; $v=$minangle; $minangle=360.0; for($i=$M+1; $i<=$max+1; $i++) { if(&theta($points[$M], $points[$i]) > $v) { if(&theta($points[$M], $points[$i]) < $minangle) { $min=$i; $minangle=&theta($points[$M], $points[$min]); } } } } until($min == ($max+1) ); return($M); # last point of the complex hull } # read data (aka: GNUPLOT-Data) # x and y are the first two with whitespace seperated # numbers of the line sub read_data { my(@points)=@_; my $point; while(<>) { next if(/^\s*\#|^\s*$/); s/^\s+//; /(\S+)\s+(\S+)/; $point={}; $point->{x}=$1; $point->{y}=$2; $point->{D}=$_; push(@points, $point) } return(@points); } # write all data lines of the convex hull to stdio: sub write_konvexhull_data { my($last, @points)=@_; my($i); foreach $i (0..$last) { print $points[$i]{D}; } } # END 1;