Files
2026-01-23 17:03:45 +08:00

178 lines
5.6 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
Class BoundingBox 2D: the MBR.
Original: Prof. Claudio Esperanca.
Adapted by Geraldo Zimbrao in 01/10/1997.
May, 2007 Leonardo Azevedo, Rafael Brand
*/
#ifndef BBOX_H
#define BBOX_H
//#include "gerpag.h"
#include "coord.h"
struct BBox2D : public rRectangle
{
public:
//--- Constructors ------------------------------------------------
BBox2D() : rRectangle( Coordinate( 0, 0 ), Coordinate( -1, -1 ) )
{}
BBox2D( Coordinate min, Coordinate max ) : rRectangle( min, max )
{}
BBox2D( long p1[ 2 ], long p2[ 2 ] ) :
rRectangle( Coordinate( MIN( p1[ 0 ], p2[ 0 ] ), MIN( p1[ 1 ], p2[ 1 ] ) ),
Coordinate( MAX( p1[ 0 ], p2[ 0 ] ), MAX( p1[ 1 ], p2[ 1 ] ) ) )
{}
BBox2D( long p1x, long p1y, long p2x, long p2y ) :
rRectangle( Coordinate( MIN( p1x, p2x ), MIN( p1y, p2y ) ),
Coordinate( MAX( p1x, p2x ), MAX( p1y, p2y ) ) )
{}
//--- Selectors ---------------------------------------------------
inline int overlaps( const BBox2D& b ) const;
// Returns true if this bounding box overlaps b.
double area () const
// Returns area of this bounding box.
{ return rectangleArea( min, max ); }
double perimeter () const
// Returns perimeter of this bounding box.
{ return 2 * ((max.x - min.x + 1) + (max.y - min.y + 1)); }
static int dimension()
{ return 2; }
// The dimension of this class
long minD( int dim ) const
// Returns the min coord value for the given dimension.
{ return ((long *) &min)[ dim ]; }
long maxD( int dim ) const
// Returns the max coord value for the given dimension.
{ return ((long *) &max)[ dim ]; }
static inline BBox2D alignedMBR( BBox2D mbr, long celSize );
// Returns the bounding box aligned in the grid
static inline BBox2D aligned2MBR( BBox2D mbr, long power, long celSize,
long dx, long dy );
// Returns the bounding box aligned in the grid
inline BBox2D unionWith( const BBox2D& b ) const;
// Returns the bounding box that contains both this and b.
inline BBox2D intersection( const BBox2D& b ) const;
// bounding box of the intersection between this and b.
private:
//--- Seletores ---------------------------------------------------
int proper() const
// Returns True if this is a "proper" bounding box, i.e. it does not
// represent an empty set.
{ return (min.x <= max.x) && (min.y <= max.y); }
};
typedef BBox2D Box;
typedef BBox2D MBR;
inline int operator == ( BBox2D a, BBox2D b );
//--- INLINES ---------------------------------------------------------
inline int BBox2D::overlaps( const BBox2D& b ) const
{
//ASSERT_CONDICAO( proper() && b.proper(), ErroNaoInicializado );
assert(proper() && b.proper());
return existsIntersection( *this, b );
}
inline BBox2D BBox2D::unionWith( const BBox2D& b ) const
{
if( !proper() ) return b;
if( !b.proper() ) return *this;
return BBox2D( Coordinate( MIN( min.x, b.min.x ), MIN( min.y, b.min.y ) ),
Coordinate( MAX( max.x, b.max.x ), MAX( max.y, b.max.y ) ) );
}
inline BBox2D BBox2D::intersection( const BBox2D& b ) const
{
if( !proper() ) return *this;
if( !b.proper() ) return b;
return BBox2D( Coordinate( MAX( min.x, b.min.x ), MAX( min.y, b.min.y ) ),
Coordinate( MIN( max.x, b.max.x ), MIN( max.y, b.max.y ) ) );
}
inline BBox2D BBox2D::alignedMBR( BBox2D mbr, long celSize )
{
Coordinate maxAligned( mbr.max.x < 0 ? mbr.max.x - celSize : mbr.max.x,
mbr.max.y < 0 ? mbr.max.y - celSize : mbr.max.y ),
minAligned( mbr.min.x < 0 ? mbr.min.x - celSize : mbr.min.x,
mbr.min.y < 0 ? mbr.min.y - celSize : mbr.min.y );
double dx = (maxAligned.x+1) / celSize - minAligned.x / celSize + 1,
dy = (maxAligned.y+1) / celSize - minAligned.y / celSize + 1;
long ldx = (long) dx, ldy = (long) dy;
return BBox2D( Coordinate( (minAligned.x / celSize) * celSize,
(minAligned.y / celSize) * celSize ),
Coordinate( ((minAligned.x / celSize) + ldx) * celSize,
((minAligned.y / celSize) + ldy) * celSize ) );
}
inline BBox2D BBox2D::aligned2MBR( BBox2D mbr, long power, long celSize,
long dx, long dy)
{
Coordinate min ( mbr.min.x & (0xFFFFFFFFlu << power),
mbr.min.y & (0xFFFFFFFFlu << power) );
return BBox2D( min, Coordinate ( min.x + dx * celSize, min.y + dy * celSize));
}
//--------------------######
inline int operator == ( BBox2D a, BBox2D b )
{
return (a.min == b.min) && (a.max == b.max);
}
struct BoxReal
{
RealCoordinate min, max;
BoxReal() : min(), max() {}
BoxReal( RealCoordinate min, RealCoordinate max ) : min( min ), max( max ) {}
};
#endif // BBOX_H