---------------------------- [ ] ---------------------------- [ ] ---------------------------- [ . ] ---------------------------- [ ] ---------------------------- [ ] ---------------------------- #### int(X/W), int(Y/W), Z #### for my $xBand ( int(($X1-$R1-$M)/$W) .. int(($X1-$R1-$M)/$W) ) { #### for my $yBand ( int(($Y1-$R1-$M)/W) .. int(($Y1-$R1-$M)/$W) ) { #### my $start= BuildKey( $xBand, $yBand, $Z1-$R1-$M ); my $end= BuildKey( $xBand, $yBand, $Z1+$R1+$M ); ... "select * from shapes where key between $start and $end" my $record; while( $record= Fetch( ... ) ) { if( Overlap( $record, ... ) ) { Report( ... ); return 1; } } } } return 0; #### my @bandWidth= ( 3, 15, 0 ); sub BuildKey { my( $radius, $x, $y, $z )= @_; my $sizeRange= $radius <= 2 ? 0 : $radius <= 10 ? 1 : 2; my $width= $bandWidth[$sizeRange]; if( 0 == $width ) { return ConcatForKey( $sizeRange, 0, 0, 0 ); } return ConcatForKey( $sizeRange, int($x/$width), int($y/$width), $z ); } #### real x real y real z real radius int size int xBand int yBand index size,xBand,yBand,z #### sub BuildKey { my( $radius, $x, $y, $z )= @_; my $sizeRange= $radius <= 2 ? 0 : $radius <= 10 ? 1 : 2; my $width= $bandWidth[$sizeRange]; if( 0 == $width ) { return pack "c", $sizeRange; } for my $c ( $x, $y, $z ) { $c= int($c/$width); $c ^= 0x8000_0000; } return return pack "cNNN", $sizeRange, $x, $y, $z; }