package Viewport; ##################################################### ### Copyright (c) 2002 Russell B Cecala. All rights ### reserved. This program is free software; you can ### redistribute it and/or modify it under the same ### terms as Perl itself. ##################################################### use strict; use Exporter; use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); $VERSION = 0.01; @ISA = qw(Exporter); @EXPORT = (); @EXPORT_OK = qw(&new); %EXPORT_TAGS = ( DEFAULT => [qw(&new)], Both => [qw(&new)]); use constant BIG => 1.0e+30; sub new { my ($pkg) = @_; bless { _xmin => BIG, _ymin => BIG, _xmax => -1 * BIG, _ymax => -1 * BIG, _xC => 0, _yC => 0, _XC => 0, _YC => 0, _f => 0, _windowset => 0 }, $pkg; } sub getxmin { my $obj = shift; return $obj->{_xmin}; } sub getymin { my $obj = shift; return $obj->{_ymin}; } sub getxmax { my $obj = shift; return $obj->{_xmax}; } sub getymax { my $obj = shift; return $obj->{_ymax}; } sub getxC { my $obj = shift; return $obj->{_xC}; } sub getyC { my $obj = shift; return $obj->{_yC}; } sub getXC { my $obj = shift; return $obj->{_XC}; } sub getYC { my $obj = shift; return $obj->{_YC}; } sub getf { my $obj = shift; return $obj->{_f}; } sub getwindowset { my $obj = shift; return $obj->{_windowset}; } sub setxmin { my $obj = shift; my $v = shift; $obj->{_xmin} = $v; } sub setymin { my $obj = shift; my $v = shift; $obj->{_ymin} = $v; } sub setxmax { my $obj = shift; my $v = shift; $obj->{_xmax} = $v; } sub setymax { my $obj = shift; my $v = shift; $obj->{_ymax} = $v; } sub setxC { my $obj = shift; my $v = shift; $obj->{_xC} = $v; } sub setyC { my $obj = shift; my $v = shift; $obj->{_yC} = $v; } sub setXC { my $obj = shift; my $v = shift; $obj->{_XC} = $v; } sub setYC { my $obj = shift; my $v = shift; $obj->{_YC} = $v; } sub setf { my $obj = shift; my $v = shift; $obj->{_f} = $v; } sub setwindowset { my $obj = shift; my $v = shift; $obj->{_windowset} = $v; } sub resetwindow { my $obj = shift; $obj->setxmin( BIG ); $obj->setymin( BIG ); $obj->setxmax( -1 * BIG ); $obj->setymax( -1 * BIG ); $obj->setxC( 0 ); $obj->setyC( 0 ); $obj->setXC( 0 ); $obj->setYC( 0 ); $obj->setf( 0 ); } sub updatewindowboundaries { my $obj = shift; my $x = shift; my $y = shift; my $xmin = $obj->getxmin(); my $xmax = $obj->getxmax(); my $ymin = $obj->getymin(); my $ymax = $obj->getymax(); if ($x < $xmin) { $obj->setxmin( $x ); } if ($x > $xmax) { $obj->setxmax( $x ); } if ($y < $ymin) { $obj->setymin( $y ); } if ($y > $ymax) { $obj->setymax( $y ); } $obj->setwindowset( 1 ); } sub viewportboundaries { my $obj = shift; my $Xmin = shift; my $Xmax = shift; my $Ymin = shift; my $Ymax = shift; my $reductionfactor = shift; my $xmin = $obj->getxmin(); my $xmax = $obj->getxmax(); my $ymin = $obj->getymin(); my $ymax = $obj->getymax(); my ( $fx, $fy ); my $windowset = $obj->getwindowset(); if ( $windowset == 0 ) { die "Viewport::updatewindowboundaries() has not been called\n"; } $obj->setXC( 0.5 * ( $Xmin + $Xmax )); $obj->setYC( 0.5 * ( $Ymin + $Ymax )); $fx = ($Xmax-$Xmin) / ( $xmax - $xmin + 1.0E-7); $fy = ($Ymax-$Ymin) / ( $ymax - $ymin + 1.0E-7); $obj->setf( $reductionfactor * ($fx<$fy?$fx:$fy)); $obj->setxC( 0.5 * ( $xmin + $xmax )); $obj->setyC( 0.5 * ( $ymin + $ymax )); } sub x_viewport { my $obj = shift; my $x = shift; my $xC = $obj->getxC(); my $XC = $obj->getXC(); my $f = $obj->getf(); my $rc = $XC + $f * ($x - $xC); return $rc; } sub y_viewport { my $obj = shift; my $y = shift; my $yC = $obj->getyC(); my $YC = $obj->getYC(); my $f = $obj->getf(); my $rc = $YC + $f * ($yC-$y); #works but upside down my $rc = $YC + $f * ($y-$yC); return $rc; } sub print { my $obj = shift; print "$obj->{_xmin}:$obj->{_ymin}:" . "$obj->{_xmax}:$obj->{_ymax}:" . "$obj->{_xC}:$obj->{_yC}:$obj->{_XC}:" . "$obj->{_YC}:$obj->{_f}\n"; } 1;