package bbox; # 14.4.2001 IK bugfix # some constant values (modify in streambuf::GetPos too!) ($SB_C, $SB_R, $SB_T, $SB_TL, $SB_TR, $SB_L, $SB_B, $SB_BR, $SB_BL) = (0, 1, 2, 3, 4, 5, 6, 7, 8); # # create new box object. # $box1 = box->new() create with default (0,0,0,0) # $box2 = box->new(xu,yu,xo,yo) create with (xu,yu,xo,yo) # $box3 = box->new($loc) create with (x,y,x,y) # $box4 = $box1->new() clone $loc1 # sub new { my $r_bbox; my $pck = shift; # first parameter is class name if (ref($pck)) # called as instance method $locobject->new() { $r_bbox = { "xu" => $pck->{"xu"}, "yu" => $pck->{"yu"}, "xo" => $pck->{"xo"}, "yo" => $pck->{"yo"} }; } else # called as class method loc->new() { if (@_) { if (ref($p1 = $_[0]) eq "loc") { $xu = $xo = $p1->{"x"}; $yu = $yo = $p1->{"y"}; } else { if (scalar(@_)==2) { $xu = $xo = $_[0]; $yu = $yo = $_[1]; } else { $xu = $_[0]; $yu = $_[1]; $xo = $_[2]; $yo = $_[3]; } } } else { $xu = $yu = $xo = $yo = 0; } $r_bbox = { "xu" => $xu, "yu" => $yu, "xo" => $xo, "yo" => $yo }; } bless $r_bbox, 'bbox'; return $r_bbox; } # # initialize existing box # $box->init() # $box->init(x,y) # $box->init($loc) # sub init { my $r_bbox = shift; my ($xu, $yu, $xo, $yo); if (@_) # called with arguments { if (ref($p1 = $_[0]) eq "loc") # called with location object { $xu = $xo = $p1->{"x"}; $yu = $yo = $p1->{"y"}; } else # called with numbers { $xu = $xo = $_[0]; $yu = $yo = $_[1]; } } else # no arguments { $xu = $yu = $xo = $yo = 0; } $r_bbox->{"xu"} = $xu; $r_bbox->{"yu"} = $yu; $r_bbox->{"xo"} = $xo; $r_bbox->{"yo"} = $yo; } # # copy box dimensions # $box->eq($box1) # sub eq { my $r_bbox = shift; my ($r_box1) = @_; $r_bbox->{"xu"} = $r_box1->{"xu"}; $r_bbox->{"yu"} = $r_box1->{"yu"}; $r_bbox->{"xo"} = $r_box1->{"xo"}; $r_bbox->{"yo"} = $r_box1->{"yo"}; } # # returns width and height of box # sub width { my $r_bbox = shift; return ($r_bbox->{"xo"} - $r_bbox->{"xu"}); } sub height { my $r_bbox = shift; return ($r_bbox->{"yo"} - $r_bbox->{"yu"}); } # # $box1->minmax(x,y) # $box1->minmax($loc) # $box1->minmax($box) # sub MinMax { my $r_bbox = shift; my $p1 = shift; if (ref($p1) eq "bbox") # box extends box { $r_bbox->{"xu"} = $p1->{"xu"} if $p1->{"xu"} < $r_bbox->{"xu"}; $r_bbox->{"yu"} = $p1->{"yu"} if $p1->{"yu"} < $r_bbox->{"yu"}; $r_bbox->{"xo"} = $p1->{"xo"} if $p1->{"xo"} > $r_bbox->{"xo"}; $r_bbox->{"yo"} = $p1->{"yo"} if $p1->{"yo"} > $r_bbox->{"yo"}; } else { if (ref($p1) eq "loc") # location object extends box { $r_bbox->{"xu"} = $p1->{"x"} if $p1->{"x"} < $r_bbox->{"xu"}; $r_bbox->{"yu"} = $p1->{"y"} if $p1->{"y"} < $r_bbox->{"yu"}; $r_bbox->{"xo"} = $p1->{"x"} if $p1->{"x"} > $r_bbox->{"xo"}; $r_bbox->{"yo"} = $p1->{"y"} if $p1->{"y"} > $r_bbox->{"yo"}; } else # point given { my $p2 = shift; $r_bbox->{"xu"} = $p1 if $p1 < $r_bbox->{"xu"}; $r_bbox->{"yu"} = $p2 if $p2 < $r_bbox->{"yu"}; $r_bbox->{"xo"} = $p1 if $p1 > $r_bbox->{"xo"}; $r_bbox->{"yo"} = $p2 if $p2 > $r_bbox->{"yo"}; } } } # # determines $loc so that $loc is in relation $iPos to $box # $box->ToConPoint($iPos, $loc) # sub ToConPoint { my ($r_bbox, $iPos, $r_loc) = @_; $r_loc->{"x"} = $r_bbox->{"xo"} if grep($iPos==$_, ($SB_R, $SB_TR, $SB_BR)); $r_loc->{"x"} = $r_bbox->{"xu"} if grep($iPos==$_, ($SB_L, $SB_TL, $SB_BL)); $r_loc->{"x"} = ($r_bbox->{"xu"} + $r_bbox->{"xo"})/2 if grep($iPos==$_, ($SB_T, $SB_C, $SB_B)); $r_loc->{"y"} = $r_bbox->{"yo"} if grep($iPos==$_, ($SB_TR, $SB_T, $SB_TL)); $r_loc->{"y"} = $r_bbox->{"yu"} if grep($iPos==$_, ($SB_BR, $SB_B, $SB_BL)); $r_loc->{"y"} = ($r_bbox->{"yu"} + $r_bbox->{"yo"})/2 if grep($iPos==$_, ($SB_L, $SB_C, $SB_R)); } # # determines $loc so that $box is in relation $iPos to $locg # $box->OrigConPoint($iPos, $loc, $locg) # sub OrigConPoint { my ($r_bbox, $iPos, $r_loc, $r_locg) = @_; $r_loc->{"x"} = $r_locg->{"x"} - $r_bbox->{"xo"} if grep($iPos==$_, ($SB_R, $SB_TR, $SB_BR)); $r_loc->{"x"} = $r_locg->{"x"} - $r_bbox->{"xu"} if grep($iPos==$_, ($SB_L, $SB_TL, $SB_BL)); $r_loc->{"x"} = $r_locg->{"x"} - ($r_bbox->{"xu"} + $r_bbox->{"xo"})/2 if grep($iPos==$_, ($SB_T, $SB_C, $SB_B)); $r_loc->{"y"} = $r_locg->{"y"} - $r_bbox->{"yo"} if grep($iPos==$_, ($SB_TR, $SB_T, $SB_TL)); $r_loc->{"y"} = $r_locg->{"y"} - $r_bbox->{"yu"} if grep($iPos==$_, ($SB_BR, $SB_B, $SB_BL)); $r_loc->{"y"} = $r_locg->{"y"} - ($r_bbox->{"yu"} + $r_bbox->{"yo"})/2 if grep($iPos==$_, ($SB_L, $SB_C, $SB_R)); } # # adds offset $loc2 or vec(x,y) to $bbox # $box->translate(x,y) # $box->translate($loc2) # sub translate { my $r_box = shift; my $p1 = shift; if (ref($p1) eq "loc") { $r_box->{"xu"} += $p1->{"x"}; $r_box->{"yu"} += $p1->{"y"}; $r_box->{"xo"} += $p1->{"x"}; $r_box->{"yo"} += $p1->{"y"}; } else { my $p2 = shift; $r_box->{"xu"} += $p1; $r_box->{"yu"} += $p2; $r_box->{"xo"} += $p1; $r_box->{"yo"} += $p2; } } # # show values # $loc->dump( [name]) # sub dump { my $r_bbox = shift; my $name = shift; printf "%s (BBOX): xu = %f, yu = %f xo = %f yo = %f\n", $name, $r_bbox->{"xu"}, $r_bbox->{"yu"}, $r_bbox->{"xo"}, $r_bbox->{"yo"}; } 1;