# -*- perl -*- # # $Id: BBBikeUtil.pm,v 1.20 2004/06/10 22:28:18 eserte Exp $ # Author: Slaven Rezic # # Copyright (C) 1998 Slaven Rezic. All rights reserved. # This package is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # # Mail: eserte@cs.tu-berlin.de # WWW: http://user.cs.tu-berlin.de/~eserte/ # package BBBikeUtil; $VERSION = sprintf("%d.%02d", q$Revision: 1.20 $ =~ /(\d+)\.(\d+)/); use strict; use vars qw(@ISA @EXPORT @EXPORT_OK); require Exporter; @ISA = qw(Exporter); @EXPORT = qw(is_in_path catfile file_name_is_absolute int_round sqr s2hm s2ms h2hm m2km pi deg2rad rad2deg schnittwinkel float_prec cp850_iso iso_cp850 nil kmh2ms STAT_MODTIME); @EXPORT_OK = qw(min max); use constant STAT_MODTIME => 9; # REPO BEGIN # REPO NAME is_in_path /home/e/eserte/src/repository # REPO MD5 ccab6618d5af7a1e314eb8e0e448ff2c sub is_in_path { my($prog) = @_; return $prog if (file_name_is_absolute($prog) and -f $prog and -x $prog); require Config; my $sep = $Config::Config{'path_sep'} || ':'; foreach (split(/$sep/o, $ENV{PATH})) { if ($^O eq 'MSWin32') { return "$_\\$prog" if (-x "$_\\$prog.bat" || -x "$_\\$prog.com" || -x "$_\\$prog.exe"); } else { return "$_/$prog" if (-x "$_/$prog"); } } undef; } # REPO END sub catfile { my(@args) = @_; my $path; eval { require File::Spec; $path = File::Spec->catfile(@args); }; if ($@) { $path = join("/", @args); } $path; } # REPO BEGIN # REPO NAME file_name_is_absolute /home/e/eserte/src/repository # REPO MD5 47355e35bcf03edac9ea12c6f8fff9a3 sub file_name_is_absolute { my $file = shift; my $r; eval { require File::Spec; $r = File::Spec->file_name_is_absolute($file); }; if ($@) { if ($^O eq 'MSWin32') { $r = ($file =~ m;^([a-z]:(/|\\)|\\\\|//);i); } else { $r = ($file =~ m|^/|); } } $r; } # REPO END sub int_round { int($_[0]+0.5) } # Quadrat sub sqr { $_[0] * $_[0]; } # Sekunden in HH:MM-Schreibweise sub s2hm { my $s = shift; sprintf "%d:%02d", $s/3600, ($s%3600)/60; } # Sekunden in MM:SS-Schreibweise sub s2ms { my $s = shift; sprintf "%d:%02d", $s/60, $s%60; } # gebrochene Stunden in HH:MM-Schreibweise sub h2hm { my $s = shift; sprintf "%d:%02d", $s, 60*($s - int($s)); } # Meter in Kilometer umwandeln. $dig gibt die Anzahl der Nachkommastellen # (Default: 1) an. Mit $sigdig (optional) kann die Anzahl der # signifikaten Nachkommastellen angegeben werden (um Scheingenauigkeiten # zu vermeiden): Beispiel m2km(1234,3,2) => 1.230. Dabei wird nicht gerundet. sub m2km { my($s, $dig, $sigdig) = @_; return 0 unless $s =~ /\d/; $dig = 1 unless defined $dig; my $r = sprintf "%." . $dig . "f", $s/1000; if (defined $sigdig) { $r =~ s/\.(\d{$sigdig})(.*)/".$1" . ("0"x length($2))/e; } $r . " km"; } sub kmh2ms { $_[0]/3.6 } # damit ich nicht Math::Trig und Math::Complex laden muß sub pi () { 4 * atan2(1, 1) } # 3.141592653 sub deg2rad { ($_[0]*pi)/180 } sub rad2deg { ($_[0]*180)/pi } # Berechnet den Schnittwinkel # Eingabe: $p1(x|y) und $p2(x|y): äußere Punkte # $pm(x|y): Punkt in der Mitte (Schnittpunkt) sub schnittwinkel { my($p1x, $p1y, $pmx, $pmy, $p2x, $p2y) = @_; my $acos; # XXX do not duplicate code (Strassen::Util) if (!eval { require POSIX }) { # from Math::Complex $acos = sub { my $z = $_[0]; return CORE::atan2(CORE::sqrt(1-$z*$z), $z) if (! ref $z) && CORE::abs($z) <= 1; warn "Fallback to Math::Trig::acos because of $z\n"; require Math::Trig; Math::Trig::acos($z); }; } else { $acos = \&POSIX::acos; } my $x1 = $pmx-$p1x; my $y1 = $pmy-$p1y; my $x2 = $p2x-$pmx; my $y2 = $p2y-$pmy; my $richtung = ($x1*$y2-$y1*$x2 > 0 ? 'l' : 'r'); my $winkel = 0; eval { $winkel = &$acos( ($x1*$x2+$y1*$y2) / (sqrt(sqr($x1)+sqr($y1)) * sqrt(sqr($x2)+sqr($y2))) ); }; ($winkel, $richtung); } sub float_prec { my($float, $prec) = @_; no locale; sprintf "%.${prec}f", $float; } # Führt ein co auf die angegebene Datei $file aus. # Rückgabewert: 1: OK, 0: bei "co" ist ein Fehler aufgetreten # Exceptions: bei chdir sub rcs_co { my $file = shift; require File::Basename; require Cwd; my $cwd = Cwd::cwd(); my($f, $dir) = File::Basename::fileparse($file); chdir $dir or die "Kann kein chdir zum Verzeichnis $dir durchführen: $!"; system("co -l $f"); my $ok = 1; if ($? != 0) { $ok = 0; } chdir $cwd; $ok; } # Zeichensatz-Konvertierungen sub cp850_iso { my $s = shift; $s =~ tr/\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/\307\374\351\342\344\340\345\347\352\353\350\357\356\354\304\305\311\346\306\364\366\362\373\371\377\326\334\370\243\330\327F\341\355\363\372\361\321\252\272\277\256\254\275\274\241\253\273\.\:\?\|\+\301\302\300\251\+\|\+\+\242\245\+\+\+\+\+\-\+\343\303\+\+\+\+\+\=\+\244\360\320\312\313\310i\315\316\317\+\+FL\246\314T\323\337\324\322\365\325\265\336\376\332\333\331\375\335\-\264\255\261\=\276\266\247\367\270\260\250\'\271\263\262f\240/; $s; } sub iso_cp850 { my $s = shift; $s =~ tr/\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \377\255\275\234\317\276\335\365\371\270\246\256\252\360\251\47\370\361\375\374\357\346\364\56\47\373\247\257\254\253\363\250\267\265\266\307\216\217\222\200\324\220\322\323\336\326\327\330\321\245\343\340\342\345\231\236\235\353\351\352\232\355\347\341\205\240\203\306\204\206\221\207\212\202\210\211\215\241\214\213\320\244\225\242\223\344\224\366\233\227\243\226\201\354\350\230/; $s; } # keine Zeichensatz-Konvertierung sub nil { $_[0] } BEGIN { if (eval { require List::Util; 1 }) { *min = \&List::Util::min; *max = \&List::Util::max; } else { *min = sub { my $min; for (@_) { $min = $_ if (!defined $min || $min > $_); } $min; }; *max = sub { my $max; for (@_) { $max = $_ if (!defined $max || $max < $_); } $max; }; } } 1;