----------------------------
[ ]
----------------------------
[ ]
----------------------------
[ . ]
----------------------------
[ ]
----------------------------
[ ]
----------------------------
####
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;
}