/* ---- This file is part of SECONDO. Copyright (C) 2019, Faculty of Mathematics and 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 ---- //[<] [\ensuremath{<}] //[>] [\ensuremath{>}] \setcounter{tocdepth}{3} \tableofcontents 1 The Rectangle2 class This class represents a plain, dim-dimensional, non-Attribute rectangle (i.e. a rectangle that has no concept of defined or undefined and cannot be stored as an attribute in a relation) with most methods provided by the Rectangle class. As the class is not derived from (Spatial)Attribute, we save 8 bytes of memory for each instance. */ #pragma once #include #include #include #include #include #include "AlmostEqual.h" #include "Algebras/Rectangle/RectangleAlgebra.h" namespace pointcloud2 { #ifndef MAX #define MAX( a, b ) ((a) > (b) ? (a) : (b)) #endif #ifndef MIN #define MIN( a, b ) ((a) < (b) ? (a) : (b)) #endif template class Rectangle2 { public: /* The empty constructor. */ inline Rectangle2(); /* The destructor. */ inline ~Rectangle2() = default; /* The first constructor. */ inline explicit Rectangle2( const double* minMax ); /* The second constructor. */ inline explicit Rectangle2( const double *min, const double *max ); /* The copy constructor. */ inline Rectangle2( const Rectangle2& r ); /* Checks if the rectangle is defined. */ inline void Set(const double *min, const double *max); /* Redefinition of operator ~=~. */ inline Rectangle2& operator = ( const Rectangle2& r ); /* Checks if the rectangle contains the rectangle ~r~. */ inline bool Contains( const Rectangle2& r ) const; /* Checks if the rectangle intersects with rectangle ~r~. */ inline bool Intersects( const Rectangle2& r ) const; /* Redefinition of operator ~==~. */ inline bool operator == ( const Rectangle2& r ) const; /* Fuzzy version of the operator ~==~. */ inline bool AlmostEqual( const Rectangle2& r ) const; /* Redefinition of operator ~!=~. */ inline bool operator != ( const Rectangle2& r ) const; /* Returns the area of a rectangle. */ inline double Area() const; /* Returns the perimeter of a rectangle. */ inline double Perimeter() const; /* Returns the min coord value for the given dimension ~dim~. */ inline const double MinD( int d ) const; /* Returns the max coord value for the given dimension ~dim~. */ inline const double MaxD( int d ) const; /* Returns the bounding box that contains both this and the rectangle ~r~. */ inline Rectangle2 Union( const Rectangle2& r) const; /* Returns the area of the bounding box that contains both this and the rectangle ~r~. */ inline double UnionArea( const Rectangle2& r) const; /* Extends this rectangle to contain both, this rectangle and the argument (sets this rectangle to be the union of this and r). */ inline void Extend(const Rectangle2&r ); /* Scales a rectangle uniformely in all dimensions. If sf is zero, the result will be undefined. */ void scale(const double sf); /* Translates the rectangle given the translate vector ~t~. */ inline Rectangle2& Translate( const double t[dim] ); /* Returns the intersection between this and the rectangle ~r~. This next functions are necessary for a ~rectangle~ be an attribute in the Relational Algebra. */ inline Rectangle2 Intersection( const Rectangle2& b ) const; /* Returns the bounding box of the rectangle; this bounding Box is a clone of the rectangle. */ inline const Rectangle2 BoundingBox() const; inline size_t Sizeof() const { return sizeof( *this ); } /* ~Extend~ Enlarges this rectangle with a border of size ~b~. The function changes the ~this~ object and returns it. */ inline const Rectangle2& Extend(const double b); inline Rectangle2* Clone() const { return new Rectangle2( *this ); } inline std::ostream& Print( std::ostream &os ) const { os << "Rectangle: ( "; for(unsigned int i=0; i < dim; i++) os< toRectangleAttr() { return Rectangle(true, min, max); } private: /* Returns ~true~ if this is a "proper" rectangle. */ inline bool Proper() const; /* The lower limits of the intervals in each dimension. */ double min[dim]; /* The upper limits of the intervals in each dimension. */ double max[dim]; }; /* 4 Implementation of the class ~Rectangle2~ The first constructor. */ template inline Rectangle2::Rectangle2( const double* minMax ) { for (unsigned i = 0; i < dim; i++ ) { min[i] = minMax[2*i]; max[i] = minMax[2*i+1]; } assert ( Proper() ); } template inline Rectangle2::Rectangle2() { for (unsigned i = 0; i < dim; i++ ) { min[i] = 0; max[i] = 0; } } /* The second constructor. */ template inline Rectangle2::Rectangle2( const double *min, const double *max ) { Set(min, max); } /* The copy constructor. */ template inline Rectangle2::Rectangle2( const Rectangle2& r ) { for ( unsigned i = 0; i < dim; i++ ) { min[i] = r.min[i]; max[i] = r.max[i]; } // assert( Proper() ); // this must have been checked on r before } /* Sets the values of this rectangle. */ template inline void Rectangle2::Set(const double *min, const double *max) { for( unsigned i = 0; i < dim; i++ ) { this->min[i] = min[i]; this->max[i] = max[i]; } assert ( Proper() ); } /* Redefinition of operator ~=~. */ template inline Rectangle2& Rectangle2::operator=(const Rectangle2& r) { for( unsigned i = 0; i < dim; i++ ) { this->min[i] = r.min[i]; this->max[i] = r.max[i]; } assert( Proper() ); return *this; } /* Checks if the rectangle contains the rectangle ~r~. */ template inline bool Rectangle2::Contains( const Rectangle2& r ) const { for ( unsigned i = 0; i < dim; i++ ) { if( min[i] > r.min[i] || max[i] < r.max[i] ) { if (min[i] > r.min[i] && !::AlmostEqual(min[i], r.min[i])) return false; if (max[i] < r.max[i] && !::AlmostEqual(max[i], r.max[i])) return false; } } return true; } /* Checks if the rectangle intersects with rectangle ~r~. */ template inline bool Rectangle2::Intersects( const Rectangle2& r ) const { for ( unsigned i = 0; i < dim; i++ ) if( max[i] < r.min[i] || r.max[i] < min[i] ) return false; return true; } /* Redefinition of operator ~==~. */ template inline bool Rectangle2::operator == ( const Rectangle2& r ) const { for( unsigned i = 0; i < dim; i++ ) if( min[i] != r.min[i] || max[i] != r.max[i] ) return false; return true; } /* Fuzzy check for equality. */ template inline bool Rectangle2::AlmostEqual( const Rectangle2& r ) const { for (unsigned i = 0; i < dim; i++ ){ if( !::AlmostEqual(min[i], r.min[i]) || !::AlmostEqual(max[i], r.max[i]) ){ return false; } } return true; } /* Redefinition of operator ~!=~. */ template inline bool Rectangle2::operator != ( const Rectangle2& r ) const { return !(*this == r); } /* Returns the area of a rectangle. */ template inline double Rectangle2::Area() const { double area = 1.0; for(unsigned i = 0; i < dim; i++ ) area *= max[i] - min[i]; return area; } /* Returns the perimeter of a rectangle. */ template inline double Rectangle2::Perimeter() const { double perimeter = 0.0; for ( unsigned i = 0; i < dim; i++ ) perimeter += std::pow( 2, (double)dim-1 ) * ( max[i] - min[i] ); return perimeter; } /* Returns the min coord value for the given dimension ~d~. */ template inline const double Rectangle2::MinD( int d ) const { assert( d >= 0 && (unsigned)d < dim ); return min[d]; } /* Returns the max coord value for the given dimension ~d~. */ template inline const double Rectangle2::MaxD( int d ) const { assert( d >= 0 && (unsigned)d < dim ); return max[d]; } /* Returns the bounding box that contains both this and the rectangle ~r~. */ template inline Rectangle2 Rectangle2::Union( const Rectangle2& r) const { double auxmin[dim], auxmax[dim]; for( unsigned i = 0; i < dim; i++ ) { auxmin[i] = MIN( min[i], r.min[i] ); auxmax[i] = MAX( max[i], r.max[i] ); } return Rectangle2( auxmin, auxmax ); } /* Returns the area of the bounding box that contains both this and the rectangle ~r~. */ template inline double Rectangle2::UnionArea( const Rectangle2& r) const { double area = 1.0; for( unsigned i = 0; i < dim; i++ ) { double maxUnion = MAX( max[i], r.max[i] ); double minUnion = MIN( min[i], r.min[i] ); area *= maxUnion - minUnion; } return area; } template inline void Rectangle2::Extend(const Rectangle2& r ) { for(unsigned i=0;i inline Rectangle2& Rectangle2::Translate( const double t[dim] ) { for( unsigned i = 0; i < dim; i++ ) { min[i] += t[i]; max[i] += t[i]; } return *this; } template inline const Rectangle2& Rectangle2::Extend(const double b) { assert(b >= 0.0); for (unsigned int i = 0; i < dim; i++){ min[i] -=b; max[i] +=b; } return *this; } /* Returns the bounding box of the rectangle; this bounding Box is a clone of the rectangle. */ template inline const Rectangle2 Rectangle2::BoundingBox() const { return Rectangle2( *this ); } /* Returns the intersection between this and the rectangle ~r~. */ template inline Rectangle2 Rectangle2::Intersection( const Rectangle2& r ) const { double auxmin[dim], auxmax[dim]; for( unsigned i = 0; i < dim; i++ ) { auxmin[i] = MAX( min[i], r.min[i] ); auxmax[i] = MIN( max[i], r.max[i] ); } return Rectangle2( auxmin, auxmax ); } /* Returns ~true~ if this is a "proper" rectangle, i.e. it does not represent an empty set. */ template inline bool Rectangle2::Proper() const { for( unsigned i = 0; i < dim; i++ ) { if( min[i] > max[i] ) return false; } return true; } template void Rectangle2::scale(const double sf) { for(unsigned int i=0;i