
| Current Path : /var/www/web-klick.de/dsh/50_dev2017/1310__algorithms/geo/Geo/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : /var/www/web-klick.de/dsh/50_dev2017/1310__algorithms/geo/Geo/Grid1.pm |
package Geo::Grid1;
use strict;
use Data::Dumper;
use Cwd;
sub DELIVER { 2 }
#**************************************************
sub new {
my $class = shift;
my $self = {};
$self->{'FILE'} = shift;
$self->{'PRECISION'} = shift; # Anzahl der Kommastellen, mit denen die Punkte aufgenommen werden
$self->{'TRIANG'} = 0;
bless($self,$class);
return($self);
}
#******************************************************
sub grid { # Einlesen der normierten Tabelle, Format: x y z (0|1) (inside/outside)
# ODER:
# Einlesen der Triangulation: Format: x y z nr11 nr2 nr3
# Punkt ist Bestandteil der
# Dreiecke mit den Nummern nr...
my $self = shift;
my $o; my $o1; my $text; my $zeile;
my $grid = [];
if (!($self->{'GRID'})) {
open(FFILE,"<".$self->{'FILE'});
$text = join("",<FFILE>);
close(FFILE);
foreach $o (split(/\n/,$text)) { # einlesen der Tabelle
$zeile = "";
if ($o =~ /^ *(\d+\.\d+) *(\d+\.\d+) *(\d+\.\d+) *(\d+\.\d+) *(\d+\.\d+) *(\d+\.\d+) *(\d+\.\d+) *(\d+\.\d+) *(\d+\.\d+)/) {
$zeile = [$1,$2,$3,$4,$5,$6,$7,$8,$9];
$self->{'TRIANG'} = 1;
}
elsif ($o !~ /^ *(\d+\.\d+) *(\d+\.\d+) *(\d+\.\d+) *(0|1)/) {
$zeile = [$1,$2,$3,$4];
}
if ($zeile) {
foreach $o1 (@$zeile) {
$o1 = sprintf("%7.5f",$o1);
}
push(@$grid,$zeile);
}
}
$self->{'GRID'} = $grid;
}
return($self->{'GRID'});
}
#******************************************************
sub is_inside {
my $self = shift;
my $o = shift;
my $o1 = shift;
my $p = shift;
$p = [$o,$o1,$p];
if ($self->{'TRIANG'}) {
return($self->is_inside_triang($p));
}
my $o; my $o1; my $abstand; my $inside;
my $abstand = 4; # Abstand immer weiter minimieren
my $inside = 0;
foreach $o (@{$self->{'GRID'}}) {
next if (abs($p->[0] - $o->[0]) > $abstand);
next if (abs($p->[1] - $o->[1]) > $abstand);
next if (abs($p->[2] - $o->[2]) > $abstand);
$o1 = ($p->[0] - $o->[0])**2 + ($p->[1] - $o->[1])**2 + ($p->[2] - $o->[2])**2;
$o1 = sqrt($o1);
next if ($abstand < $o1);
$abstand = $o1;
$inside = $o->[3];
}
return($inside);
}
#********************************************************
sub enlarge_dataset {
my $self = shift;
my $geo = shift; # Urspruengliche Geometrie
my $nr = shift; # Anzahl der Punkte, die hinzugefuegt werden sollen
my $zaehler = 1;
my $inside; my $x; my $y; my $z; my $zeile; my $z1; my $z2;
open(FFILE,"<".$self->{'FILE'});
my $text = join("",<FFILE>);
close(FFILE);
open(FFILE,">".$self->{'FILE'});
while (0 == 0) {
$z1 = $z1 + 1;
$z2 = $z2 + 1;
$x = rand();
$y = rand();
$z = rand();
$inside = $geo->is_inside($x,$y,$z);
next if ($inside == $self->is_inside($x,$y,$z));
$zeile = sprintf("%13.5f",$x) . " " .
sprintf("%13.5f",$y) . " " .
sprintf("%13.5f",$z) . " " . $inside .
" " . sprintf("%5u",$zaehler) . " " . sprintf("%6u",$z1) .
" " . sprintf("%9.2f",$z2/$zaehler) . "\n";
push(@{$self->{'GRID'}},[$x,$y,$z,$inside]);
print $zeile;
print FFILE $zeile;
$zaehler = $zaehler + 1;
$z1 = 0;
last if ($zaehler > $nr);
}
}
#********************************************************
sub is_inside_triang {
my $self = shift;
my $p = shift;
$p->[0] = sprintf("%7.5f",$p->[0]) + 0.000005;
$p->[1] = sprintf("%7.5f",$p->[1]) + 0.000005;
$p->[2] = sprintf("%7.5f",$p->[2]) + 0.000005;
my $inside_counter = [0,0,0];
my $x; my $y; my $z; my $per; my $o; my $a; my $b; my $c; my $p0;
my $rho; my $lambda; my $mu; my $per1; my $per0; my $maxrho;
foreach $o ( @{$self->{'GRID'}} ) {
foreach $per ( [0,1,2], [1,2,0], [2,0,1] ) {
$x = $per->[0];
$y = $per->[1];
$z = $per->[2];
$maxrho = 0;
$per0 = [];
foreach $per1 ( [0,3,6], [3,6,0], [6,0,3] ) {
$a = $per1->[0];
$b = $per1->[1];
$c = $per1->[2];
$rho = ( ($o->[$b+$y]) - ($o->[$a+$y]) ) * ( ($o->[$c+$x]) - ($o->[$a+$x]) ) -
( ($o->[$b+$x]) - ($o->[$a+$x]) ) * ( ($o->[$c+$y]) - ($o->[$a+$y]) );
if (abs($rho) > abs($maxrho)) { # diejenige Perspektive suchen, die am guenstigsten ist
$maxrho = $rho;
$per0 = [@$per1];
}
}
return("___RHO_IS_ZERO___") if (!@$per0);
$a = $per0->[0];
$b = $per0->[1];
$c = $per0->[2];
$lambda = ( ($o->[$b+$y]) - ($o->[$a+$y]) ) * ( ($p->[$x]) - ($o->[$a+$x]) ) -
( ($o->[$b+$x]) - ($o->[$a+$x]) ) * ( ($p->[$y]) - ($o->[$a+$y]) );
$mu = ( ($o->[$c+$y]) - ($o->[$a+$y]) ) * ( ($p->[$x]) - ($o->[$a+$x]) ) -
( ($o->[$c+$x]) - ($o->[$a+$x]) ) * ( ($p->[$y]) - ($o->[$a+$y]) );
$lambda = $lambda / $maxrho;
$mu = - $mu / $maxrho;
$p0->[0] = $o->[$a+$x] + $mu * ( ($o->[$b+$x]) - ($o->[$a+$x]) ) + $lambda * ( ($o->[$c+$x]) - ($o->[$a+$x]) );
$p0->[1] = $o->[$a+$y] + $mu * ( ($o->[$b+$y]) - ($o->[$a+$y]) ) + $lambda * ( ($o->[$c+$y]) - ($o->[$a+$y]) );
$p0->[2] = $o->[$a+$z] + $mu * ( ($o->[$b+$z]) - ($o->[$a+$z]) ) + $lambda * ( ($o->[$c+$z]) - ($o->[$a+$z]) );
# print "$per0->[0] ZZ: $lambda $mu -- $p0->[0] $p0->[1] $p0->[2] .. $z $p->[$z] \n";
next if ($lambda < 0); # uberpruefe
next if ($mu < 0); # Dreiecks-
next if ($lambda + $mu > 1); # bedingung
$inside_counter->[ $per->[0] ] = $inside_counter->[ $per->[0] ] + 1 if ($p0->[2] > $p->[$z]);
}
# print Dumper($o); print Dumper($inside_counter);
}
$o = -1;
foreach $per (0,1,2) {
next if ($inside_counter->[$per] == -1);
return("___ERROR___") if ($o > -1 and $o != ($inside_counter->[$per] % 2));
$o = ($inside_counter->[$per] % 2);
}
return($o);
}
1;