#======================================================== # GraphData #======================================================== package GraphData; use Common; @ISA = qw(Common); use strict; use Rect; #@ISA = qw(Tk::Frame); #公開したいサブルーチン #@EXPORT = qw(); sub Index { return shift->{'Index'}; } #sub nData { my $pX=shift->GetXArrayRef(); return scalar @$pX; } sub Visible { return shift->{'Visible'}; } sub SetVisible { my ($this,$f)=@_; return shift->{'Visible'} = $f; } sub XMin { return shift->{'XMin'}; } sub XMax { return shift->{'XMax'}; } sub YMin { return shift->{'YMin'}; } sub YMax { return shift->{'YMax'}; } sub GetXMinMax { my $this = shift; return ($this->{'XMin'}, $this->{'XMax'}); } sub GetYMinMax { my $this = shift; return ($this->{'YMin'}, $this->{'YMax'}); } sub GetMinMax { my $this = shift; return ($this->{'XMin'}, $this->{'XMax'}, $this->{'YMin'}, $this->{'YMax'}); } sub XDataArray { my ($this,$i)=@_; return $this->{"x${i}"}; } sub SetXDataArray { my ($this,$i,$p)=@_; return $this->{"x${i}"} = $p; } sub YDataArray { my ($this,$i)=@_; return $this->{"y${i}"}; } sub SetYDataArray { my ($this,$i,$p)=@_; return $this->{"y${i}"} = $p; } sub XCaption { return shift->{'XCaption'}; } sub SetXCaption { my ($this,$c)=@_; return shift->{'XCaption'} = $c; } sub YCaption { return shift->{'YCaption'}; } sub SetYCaption { my ($this,$c)=@_; return shift->{'YCaption'} = $c; } sub XName { my ($this,$i)=@_; return $this->{"x${i}_Name"}; } sub SetXName { my ($this,$i,$n)=@_; return $this->{"x${i}_Name"} = $n; } sub YName { my ($this,$i)=@_; return $this->{"y${i}_Name"}; } sub SetYName { my ($this,$i,$n)=@_; return $this->{"y${i}_Name"} = $n; } sub SetSampleName { my ($this,$s)=@_; return $this->{'SampleName'} = $s; } sub SampleName { return shift->{'SampleName'}; } #============================================================ # コンストラクタ、デストラクタ #============================================================ BEGIN { } sub new { my ($module, $idx) = @_; my $this = {}; bless $this; $idx = 0 unless($idx); $this->SetIndex($idx); return $this; } sub DESTROY { my $this = shift; # $this->SUPER::DESTROY(@_); } sub GetDataArray { my ($this, $idx) = @_; return $this->{$idx}; } sub CalMinMax { my ($this) = @_; my $nData = $this->nData(); my $nX = $this->nXColumn(); my $xmin = $this->x(0); my $xmax = $this->x(0); for(my $idx = 0 ; $idx < $nX ; $idx++) { for(my $i = 1 ; $i < $nData ; $i++) { my $x = $this->x($idx, $i); next unless($x); if($xmin > $x) { $xmin = $x; } if($xmax < $x) { $xmax = $x; } } } my $nY = $this->nYColumn(); my $ymin = $this->y(0); my $ymax = $this->y(0); for(my $idx = 0 ; $idx < $nY ; $idx++) { my $pArray = $this->{"y$idx"}; last unless($pArray); for(my $i = 1 ; $i < $nData ; $i++) { my $y = $this->y($idx, $i); next unless($y); if($ymin > $y) { $ymin = $y; } if($ymax < $y) { $ymax = $y; } } } $this->{'XMin'} = $xmin; $this->{'XMax'} = $xmax; $this->{'YMin'} = $ymin; $this->{'YMax'} = $ymax; } sub nData { my ($this, $idx) = @_; $idx = 0 if(!defined $idx); my $pArray = $this->{"x$idx"}; #print "idx: $idx $pArray\n"; return scalar @$pArray; } sub nXColumn { my ($this) = @_; my $i = 0; for( ; ; $i++) { last unless($this->{"x$i"}); } return $i; } sub nYColumn { my ($this) = @_; my $i = 0; for( ; ; $i++) { last unless($this->{"y$i"}); } return $i; } sub x { my ($this, $idx, $i) = @_; unless(defined $i) { $i = $idx; $idx = 0; } my $pArray = $this->{"x$idx"}; my $v = $pArray->[$i]; return $pArray->[$i]; } sub y { my ($this, $idx, $i) = @_; unless(defined $i) { $i = $idx; $idx = 0; } my $pArray = $this->{"y$idx"}; my $v = $pArray->[$i]; return $pArray->[$i]; } sub XVal { my ($this, $idx, $y, $Debug) = @_; my $nData = $this->nData($idx); my ($imin, $imax) = (0, $nData - 1); while(1) { # last if($imax - $imin <= 1); my $ihalf = int(($imax+$imin)/2); my $xmin = $this->x($idx, $imin); my $ymin = $this->y($idx, $imin); my $xhalf = $this->x($idx, $ihalf); my $yhalf = $this->y($idx, $ihalf); my $xmax = $this->x($idx, $imax); my $ymax = $this->y($idx, $imax); print "i=$imin, $imax, $ihalf y=($ymin, $y, $ymax / $yhalf)\n" if($Debug); last if($imax - $imin <= 1); my $check0 = ($y - $ymin) * ($yhalf - $y); print " 0: $check0 = $y, $ymin / $yhalf, $y\n" if($Debug); if($check0 >= 0.0) { $imax = $ihalf; next; } my $check1 = ($y - $yhalf) * ($ymax - $y); print " 1: $check1 = $y, $ymin / $yhalf, $y\n" if($Debug); if($check1 >= 0.0) { $imin = $ihalf; next; } return undef; } my $xmin = $this->x($idx, $imin); my $ymin = $this->y($idx, $imin); my $xmax = $this->x($idx, $imax); my $ymax = $this->y($idx, $imax); my $x = $xmax + ($xmax-$xmin)/($ymax-$ymin) * ($y-$ymin); print "Last: i=$imin, $imax ($x, $y)\n" if($Debug); return $x; } sub YVal { my ($this, $idx, $x, $Debug) = @_; my $nData = $this->nData($idx); my $x0 = $this->x($idx, 0); my $x1 = $this->x($idx, $nData-1); if($Debug) { my $y0 = $this->y($idx, 0); my $y1 = $this->y($idx, $nData-1); my $t = $this->Title(); print "[$t] X: $x0 - $x1 Y: $y0 - $y1\n"; } my $i0 = 0; my $i1 = 0; if($x0 < $x1) { return $this->y($idx, 0) if($x <= $x0); return $this->y($idx, $nData-1) if($x >= $x1); for($i0 = 0 ; $i0 < $nData ; $i0++) { last if($x <= $this->x($idx, $i0)); } $i1 = $i0 - 1; $i1 = $i0 + 1 if($i1 < 0); } else { return $this->y($idx, $nData-1) if($x <= $x1); return $this->y($idx, 0) if($x >= $x0); for($i0 = $nData-1 ; $i0 >= 0 ; $i0--) { last if($x <= $this->x($idx, $i0)); } $i1 = $i0 + 1; $i1 = $i0 - 1 if($i1 >= $nData); } $x0 = $this->x($idx, $i0); $x1 = $this->x($idx, $i1); my $y0 = $this->y($idx, $i0); my $y1 = $this->y($idx, $i1); my $vy = $y0 + ($x - $x0) / ($x1 - $x0) * ($y1 - $y0); if($Debug) { printf "x=%6.3f i=%d,%d x=%6.3f,%6.3f y=%6.3f,%6.3f vy=%6.3f\n", $x, $i0, $i1, $x0, $x1, $y0, $y1, $vy; } return $vy; # return $this->y($idx, $i); } sub YValForConstantXStep { my ($this, $idx, $x, $Debug) = @_; my $nData = $this->nData($idx); my $x0 = $this->x($idx, 0); my $x1 = $this->x($idx, $nData-1); my $xstep = $this->x($idx, 1) - $x0; my $i0 = int(($x - $x0) / $xstep); #print "i0=$i0 x=$x x: $x0 - $x1\n"; #print "y=", $this->y($idx, 0) , "\n"; return $this->y($idx, 0) if($i0 < 0); return $this->y($idx, $nData-1) if($i0 >= $nData); my $i1 = $i0 + 1; $x0 = $this->x($idx, $i0); $x1 = $this->x($idx, $i1); my $y0 = $this->y($idx, $i0); my $y1 = $this->y($idx, $i1); my $vy = $y0 + ($x - $x0) / ($x1 - $x0) * ($y1 - $y0); return $vy; } sub Title { return shift->{'Title'}; } sub SetTitle { my ($this, $title) = @_; return $this->{'Title'} = $title; } sub SetIndex { my ($this, $idx) = @_; return $this->{'Index'} = $idx; } #======================================================== # GraphDataArray #======================================================== package GraphDataArray; sub nGraphData { my $da=shift->{'GraphDataArray'}; return @$da; } sub GetGraphDataArray { return shift->{'GraphDataArray'}; } sub GetGraphData { my ($this, $idx) = @_; my $pGraphDataArray = $this->GetGraphDataArray(); return $pGraphDataArray->[$idx]; } sub Index { return 0; } sub SetTitle { my ($this, $title) = @_; my $pGraphDataArray = $this->GetGraphDataArray(); for(my $i = 0 ; $i < @$pGraphDataArray ; $i++) { $pGraphDataArray->[$i]->SetTitle($title); } return $title; } BEGIN { } sub new { my ($module) = @_; my $this = {}; bless $this; my @array; $this->{'GraphDataArray'} = \@array; return $this; } sub DESTROY { my $this = shift; # $this->SUPER::DESTROY(@_); } sub AddGraphData { my ($this, $GraphData) = @_; my $pGraphDataArray = $this->GetGraphDataArray(); my $idx = @$pGraphDataArray; unless($GraphData) { $GraphData = new GraphData($idx); } push(@$pGraphDataArray, $GraphData); } 1;