package org.andork.spatial;
import javax.vecmath.*;
public class BBox
{
public static void main( String[ ] args )
{
BBox b1 = new BBox( new Point3d( Double.NEGATIVE_INFINITY , Double.NEGATIVE_INFINITY , Double.NEGATIVE_INFINITY ) , new Point3d( 0 , 0 , 0 ) );
BBox b2 = new BBox( new Point3d( -5 , -5 , -5 ) , new Point3d( -2 , -2 , -2 ) );
System.out.println( b1.contains( b2 ) );
System.out.println( 5 - Double.NEGATIVE_INFINITY );
b1.setCenterRadius( new Point3d( ) , 5 );
b2.setInfinite( );
System.out.println( b2.contains( b1 ) );
}
private final Point3d lower = new Point3d( );
private final Point3d upper = new Point3d( );
public BBox( )
{
setVoid( );
}
// Constructor added to take floats.
public BBox( float[ ] pLow , float[ ] pHigh )
{
if( pLow.length != pHigh.length )
throw new IllegalArgumentException( );
lower.x = Math.min( pLow[ 0 ] , pHigh[ 0 ] );
lower.y = Math.min( pLow[ 1 ] , pHigh[ 1 ] );
lower.z = Math.min( pLow[ 2 ] , pHigh[ 2 ] );
upper.x = Math.max( pLow[ 0 ] , pHigh[ 0 ] );
upper.y = Math.max( pLow[ 1 ] , pHigh[ 1 ] );
upper.z = Math.max( pLow[ 2 ] , pHigh[ 2 ] );
}
public BBox( double[ ] pLow , double[ ] pHigh )
{
if( pLow.length != pHigh.length )
throw new IllegalArgumentException( );
lower.y = Math.min( pLow[ 1 ] , pHigh[ 1 ] );
lower.z = Math.min( pLow[ 2 ] , pHigh[ 2 ] );
upper.x = Math.max( pLow[ 0 ] , pHigh[ 0 ] );
upper.y = Math.max( pLow[ 1 ] , pHigh[ 1 ] );
upper.z = Math.max( pLow[ 2 ] , pHigh[ 2 ] );
}
public BBox( Point3d c1 , Point3d c2 )
{
lower.x = Math.min( c1.x , c2.x );
lower.y = Math.min( c1.y , c2.y );
lower.z = Math.min( c1.z , c2.z );
upper.x = Math.max( c1.x , c2.x );
upper.y = Math.max( c1.y , c2.y );
upper.z = Math.max( c1.z , c2.z );
}
public BBox( BBox r )
{
lower.set( r.lower );
upper.set( r.upper );
}
public boolean equals( Object o )
{
if( o instanceof BBox )
{
BBox r = ( BBox ) o;
return lower.equals( r.lower ) && upper.equals( r.upper );
}
return false;
}
//
// Cloneable interface
//
public BBox clone( )
{
return new BBox( this );
}
public void setInfinite( )
{
lower.set( Double.NEGATIVE_INFINITY , Double.NEGATIVE_INFINITY , Double.NEGATIVE_INFINITY );
upper.set( Double.POSITIVE_INFINITY , Double.POSITIVE_INFINITY , Double.POSITIVE_INFINITY );
}
public void setVoid( )
{
lower.set( Double.NaN , Double.NaN , Double.NaN );
upper.set( Double.NaN , Double.NaN , Double.NaN );
}
public boolean isVoid( )
{
return Double.isNaN( lower.x ) || Double.isNaN( lower.y ) || Double.isNaN( lower.z ) || Double.isNaN( upper.x ) || Double.isNaN( upper.y ) || Double.isNaN( upper.z );
}
public Point3d getCenter( Point3d buffer )
{
buffer.interpolate( lower , upper , 0.5 );
return buffer;
}
public int getDimension( )
{
return 3;
}
public double getVolume( )
{
return ( upper.x - lower.x ) * ( upper.y - lower.y ) * ( upper.z - lower.z );
}
public boolean intersects( BBox r )
{
return lower.x <= r.upper.x && lower.y <= r.upper.y && lower.z <= r.upper.z && upper.x >= r.lower.x && upper.y >= r.lower.y && upper.z >= r.lower.z;
}
public boolean contains( BBox r )
{
return lower.x <= r.lower.x && upper.x >= r.upper.x && lower.y <= r.lower.y && upper.y >= r.upper.y && lower.z <= r.lower.z && upper.z >= r.upper.z;
}
public boolean contains( Point3d p )
{
return p.x >= lower.x && p.x <= upper.x && p.y >= lower.y && p.y <= upper.y && p.z >= lower.z && p.z <= upper.z;
}
public void setLower( Point3d newLoc )
{
lower.x = Math.min( upper.x , newLoc.x );
lower.y = Math.min( upper.y , newLoc.y );
lower.z = Math.min( upper.z , newLoc.z );
upper.x = Math.max( upper.x , newLoc.x );
upper.y = Math.max( upper.y , newLoc.y );
upper.z = Math.max( upper.z , newLoc.z );
}
public void setUpper( Point3d newLoc )
{
upper.x = Math.max( lower.x , newLoc.x );
upper.y = Math.max( lower.y , newLoc.y );
upper.z = Math.max( lower.z , newLoc.z );
lower.x = Math.min( lower.x , newLoc.x );
lower.y = Math.min( lower.y , newLoc.y );
lower.z = Math.min( lower.z , newLoc.z );
}
public void setLower( int index , double value )
{
switch( index )
{
case 0:
lower.x = value;
if( lower.x > upper.x )
{
lower.x = upper.x;
upper.x = value;
}
break;
case 1:
lower.y = value;
if( lower.y > upper.y )
{
lower.y = upper.y;
upper.y = value;
}
break;
case 2:
lower.z = value;
if( lower.z > upper.z )
{
lower.z = upper.z;
upper.z = value;
}
break;
default:
throw new IndexOutOfBoundsException( "index must be between 0-2 inclusive" );
}
}
public void setUpper( int index , double value )
{
switch( index )
{
case 0:
upper.x = value;
if( upper.x < lower.x )
{
upper.x = lower.x;
lower.x = value;
}
break;
case 1:
upper.y = value;
if( upper.y < lower.y )
{
upper.y = lower.y;
lower.y = value;
}
break;
case 2:
upper.z = value;
if( upper.z < lower.z )
{
upper.z = lower.z;
lower.z = value;
}
break;
default:
throw new IndexOutOfBoundsException( "index must be between 0-2 inclusive" );
}
}
public void set( Point3d c1 , Point3d c2 )
{
lower.x = Math.min( c1.x , c2.x );
lower.y = Math.min( c1.y , c2.y );
lower.z = Math.min( c1.z , c2.z );
upper.x = Math.max( c1.x , c2.x );
upper.y = Math.max( c1.y , c2.y );
upper.z = Math.max( c1.z , c2.z );
}
public void set( BBox r )
{
lower.set( r.lower );
upper.set( r.upper );
}
public void setCenterRadius( Point3d center , double radius )
{
lower.set( center.x - radius , center.y - radius , center.z - radius );
upper.set( center.x + radius , center.y + radius , center.z + radius );
}
public void enlargeFixed( double enlargement )
{
lower.x -= enlargement;
lower.y -= enlargement;
lower.z -= enlargement;
upper.x += enlargement;
upper.y += enlargement;
upper.z += enlargement;
}
public void enlargePrecent( double percentage )
{
double enlargement = ( upper.x - lower.x ) * ( percentage - 1.0 ) * 0.5;
lower.x -= enlargement;
upper.x += enlargement;
enlargement = ( upper.y - lower.y ) * ( percentage - 1.0 ) * 0.5;
lower.y -= enlargement;
upper.y += enlargement;
enlargement = ( upper.z - lower.z ) * ( percentage - 1.0 ) * 0.5;
lower.z -= enlargement;
upper.z += enlargement;
}
public double min2( double a , double b )
{
return a < b ? a : Double.isNaN( b ) ? a : b;
}
public double max2( double a , double b )
{
return a > b ? a : Double.isNaN( b ) ? a : b;
}
public void union( BBox b2 )
{
union( this , b2 );
}
public void union( BBox b1 , BBox b2 )
{
lower.x = min2( b2.lower.x , b1.lower.x );
lower.y = min2( b2.lower.y , b1.lower.y );
lower.z = min2( b2.lower.z , b1.lower.z );
upper.x = max2( b2.upper.x , b1.upper.x );
upper.y = max2( b2.upper.y , b1.upper.y );
upper.z = max2( b2.upper.z , b1.upper.z );
}
public void intersect( BBox b2 )
{
intersect( this , b2 );
}
public void intersect( BBox b1 , BBox b2 )
{
if( b1.intersects( b2 ) )
{
setVoid( );
}
else
{
lower.x = Math.max( b2.lower.x , b1.lower.x );
lower.y = Math.max( b2.lower.y , b1.lower.y );
lower.z = Math.max( b2.lower.z , b1.lower.z );
upper.x = Math.min( b2.upper.x , b1.upper.x );
upper.y = Math.min( b2.upper.y , b1.upper.y );
upper.z = Math.min( b2.upper.z , b1.upper.z );
}
}
public double getLow( int index )
{
switch( index )
{
case 0:
return lower.x;
case 1:
return lower.y;
case 2:
return lower.z;
default:
throw new IndexOutOfBoundsException( "index must be between 0-2 inclusive" );
}
}
public double getHigh( int index )
{
switch( index )
{
case 0:
return upper.x;
case 1:
return upper.y;
case 2:
return upper.z;
default:
throw new IndexOutOfBoundsException( "index must be between 0-2 inclusive" );
}
}
public Point3d getLower( Point3d buffer )
{
buffer.set( lower );
return buffer;
}
public Point3d getUpper( Point3d buffer )
{
buffer.set( upper );
return buffer;
}
public String toString( )
{
return "BoundingBox[" + lower + " - " + upper + "]";
}
}