1345 lines
29 KiB
C
1345 lines
29 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
|
||
|
|
----
|
||
|
|
|
||
|
|
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
|
||
|
|
//[TOC] [\tableofcontents]
|
||
|
|
|
||
|
|
{\Large \bf Anhang B: Rectangle-Template }
|
||
|
|
|
||
|
|
[1] Header File of the Rectangle Algebra
|
||
|
|
|
||
|
|
October, 2003 Victor Teixeira de Almeida
|
||
|
|
|
||
|
|
October, 2004 Schoenhammer Herbert, (virtual) method BoundingBox() added
|
||
|
|
|
||
|
|
[TOC]
|
||
|
|
|
||
|
|
1 Overview
|
||
|
|
|
||
|
|
This header file essentially contains the definition of the struct ~Rectangle~.
|
||
|
|
This class corresponds to the memory representation for the type constructor
|
||
|
|
~rect~, ~rect3~ and ~rect4~ which are 2-dimensional, 3-dimensional,
|
||
|
|
4-dimensional or 8-dimensional rectangles alligned with the axes of each
|
||
|
|
dimension. A rectangle in such a way can be represented by four, six or eight
|
||
|
|
numbers (two for each dimension).
|
||
|
|
|
||
|
|
|
||
|
|
2 Defines and includes
|
||
|
|
|
||
|
|
*/
|
||
|
|
#ifndef __RECTANGLE_ALGEBRA_H__
|
||
|
|
#define __RECTANGLE_ALGEBRA_H__
|
||
|
|
|
||
|
|
|
||
|
|
#include <cmath>
|
||
|
|
#include <limits.h>
|
||
|
|
#include <iostream>
|
||
|
|
#include "stdarg.h"
|
||
|
|
#include "Attribute.h"
|
||
|
|
#include "Algebras/Geoid/Geoid.h"
|
||
|
|
#include "ListUtils.h"
|
||
|
|
|
||
|
|
#include <stdio.h>
|
||
|
|
|
||
|
|
#ifdef SECONDO_WIN32
|
||
|
|
#define Rectangle SecondoRectangle
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAX
|
||
|
|
#define MAX( a, b ) ((a) > (b) ? (a) : (b))
|
||
|
|
#endif
|
||
|
|
#ifndef MIN
|
||
|
|
#define MIN( a, b ) ((a) < (b) ? (a) : (b))
|
||
|
|
#endif
|
||
|
|
|
||
|
|
template <unsigned dim>
|
||
|
|
class Rectangle;
|
||
|
|
|
||
|
|
template <unsigned dim>
|
||
|
|
class StandardSpatialAttribute : public Attribute
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
StandardSpatialAttribute() : Attribute() {}
|
||
|
|
StandardSpatialAttribute(bool defined):Attribute(defined) {}
|
||
|
|
|
||
|
|
virtual const Rectangle<dim> BoundingBox(const Geoid* geoid = 0) const = 0;
|
||
|
|
virtual double Distance(const Rectangle<dim>& rect,
|
||
|
|
const Geoid* geoid=0) const = 0;
|
||
|
|
|
||
|
|
virtual bool Intersects(const Rectangle<dim>& rect,
|
||
|
|
const Geoid* geoid=0 ) const = 0;
|
||
|
|
|
||
|
|
virtual bool IsEmpty() const = 0;
|
||
|
|
|
||
|
|
static unsigned GetDim(){
|
||
|
|
return dim;
|
||
|
|
}
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
3 Class ~Rectangle~
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
class Rectangle: public StandardSpatialAttribute<dim>
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
|
||
|
|
/*
|
||
|
|
Do not use the standard constructor:
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline Rectangle():StandardSpatialAttribute<dim>() {}
|
||
|
|
|
||
|
|
/*
|
||
|
|
The first constructor. First one can set if the rectangle is defined,
|
||
|
|
and if it is, the coordinates can be set.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline Rectangle( const bool defined, const double* minMax );
|
||
|
|
inline explicit Rectangle( const bool defined);
|
||
|
|
|
||
|
|
/*
|
||
|
|
The second constructor. First one can set if the rectangle is defined,
|
||
|
|
and if it is, the coordinates can be set.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline Rectangle( const bool defined,
|
||
|
|
const double *min, const double *max );
|
||
|
|
|
||
|
|
/*
|
||
|
|
The copy constructor.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline Rectangle( const Rectangle<dim>& r );
|
||
|
|
|
||
|
|
/*
|
||
|
|
Checks if the rectangle is defined.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline void Set(const bool defined, const double *min, const double *max);
|
||
|
|
|
||
|
|
/*
|
||
|
|
Checks if the rectangle is defined (For conformity with other spatial types)
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline bool IsEmpty() const override { return !(this->IsDefined()); };
|
||
|
|
|
||
|
|
/*
|
||
|
|
Redefinition of operator ~=~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline Rectangle<dim>& operator = ( const Rectangle<dim>& r );
|
||
|
|
|
||
|
|
/*
|
||
|
|
Checks if the rectangle contains the rectangle ~r~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline bool Contains( const Rectangle<dim>& r, const Geoid* geoid=0 ) const;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Checks if the rectangle intersects with rectangle ~r~. Both rectangles
|
||
|
|
must be defined.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline bool Intersects( const Rectangle<dim>& r,
|
||
|
|
const Geoid* geoid=0 ) const override;
|
||
|
|
/*
|
||
|
|
Checks if the rectangle intersects with rectangle ~r~. If one of the
|
||
|
|
involved rectangles is not defined, the result will be false;
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline bool IntersectsUD( const Rectangle<dim>& r,
|
||
|
|
const Geoid* geoid=0 ) const;
|
||
|
|
|
||
|
|
/*
|
||
|
|
Redefinition of operator ~==~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline bool operator == ( const Rectangle<dim>& r ) const;
|
||
|
|
|
||
|
|
/*
|
||
|
|
Fuzzy version of the operator ~==~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline bool AlmostEqual( const Rectangle<dim>& r ) const;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Redefinition of operator ~!=~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline bool operator != ( const Rectangle<dim>& r ) const;
|
||
|
|
|
||
|
|
/*
|
||
|
|
Returns the area of a rectangle.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline double Area(const Geoid* geoid=0) const;
|
||
|
|
|
||
|
|
/*
|
||
|
|
Returns the perimeter of a rectangle.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline double Perimeter(const Geoid* geoid=0) 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 Rectangle<dim> Union( const Rectangle<dim>& r,
|
||
|
|
const Geoid* geoid=0 ) 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 Rectangle<dim>&r, const Geoid* geoid=0);
|
||
|
|
|
||
|
|
/*
|
||
|
|
Returns the Euclidean distance (~geoid~ = NULL) resp. spherical distance between
|
||
|
|
two rectangles.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline double Distance(const Rectangle<dim>& r, const Geoid* geoid=0)
|
||
|
|
const override;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Returns the square of the maximum distance between two points within
|
||
|
|
this rectangle and ~r~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
double QMaxMaxDistance(const Rectangle<dim>& r) const;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Returns the square of the minmaxdistance between this and ~r~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
double QMinMaxDistance(const Rectangle<dim>& r) const;
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
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 Rectangle<dim>& Translate( const double t[dim] );
|
||
|
|
|
||
|
|
/*
|
||
|
|
Overridings of some Attribute functions
|
||
|
|
|
||
|
|
*/
|
||
|
|
virtual double getMinX() const override {
|
||
|
|
return min[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
virtual double getMaxX() const override {
|
||
|
|
return max[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
virtual double getMinY() const override {
|
||
|
|
return dim < 2 ? 0 : min[1];
|
||
|
|
}
|
||
|
|
|
||
|
|
virtual double getMaxY() const override {
|
||
|
|
return dim < 2 ? 0 : max[1];
|
||
|
|
}
|
||
|
|
|
||
|
|
virtual double getMinZ() const override {
|
||
|
|
return dim < 3 ? 0 : min[2];
|
||
|
|
}
|
||
|
|
|
||
|
|
virtual double getMaxZ() const override {
|
||
|
|
return dim < 3 ? 0 : max[2];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Intervallength for a certain dimension.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline const double LengthD( int d ) const {
|
||
|
|
|
||
|
|
assert ( d >= 0 && (unsigned)d < dim);
|
||
|
|
|
||
|
|
return this->IsDefined()?max[d] - min[d]:-1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Middle of an interval of a certain dimension.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline const double MidD( int d ) const {
|
||
|
|
|
||
|
|
assert ( d >= 0 && (unsigned)d < dim);
|
||
|
|
|
||
|
|
return (max[d] + min[d]) / 2.0;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
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 Rectangle<dim> Intersection( const Rectangle<dim>& b,
|
||
|
|
const Geoid* geoid=0 ) const;
|
||
|
|
|
||
|
|
/*
|
||
|
|
Returns the bounding box of the rectangle; this bounding Box is a clone
|
||
|
|
of the rectangle.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline const Rectangle<dim> BoundingBox(const Geoid* geoid = 0)
|
||
|
|
const override;
|
||
|
|
|
||
|
|
inline static const std::string BasicType() {
|
||
|
|
if(dim==2){
|
||
|
|
return "rect";
|
||
|
|
} else {
|
||
|
|
std::ostringstream ss;
|
||
|
|
ss << "rect" << dim;
|
||
|
|
return ss.str();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
static const bool checkType(const ListExpr type){
|
||
|
|
return listutils::isSymbol(type, BasicType());
|
||
|
|
}
|
||
|
|
|
||
|
|
inline size_t Sizeof() const override { return sizeof( *this ); }
|
||
|
|
|
||
|
|
inline size_t HashValue() const override{
|
||
|
|
size_t h = 0;
|
||
|
|
for( unsigned i = 0; i < dim; i++ )
|
||
|
|
h += size_t(4 * min[i] + max[i]);
|
||
|
|
return h;
|
||
|
|
}
|
||
|
|
|
||
|
|
inline void CopyFrom( const Attribute* right ) override
|
||
|
|
{ *this = *(const Rectangle<dim>*)right; }
|
||
|
|
|
||
|
|
inline int Compare( const Attribute *arg ) const override{
|
||
|
|
unsigned thispos, rpos;
|
||
|
|
unsigned thismin[dim], rmin[dim];
|
||
|
|
const Rectangle<dim>* r = (const Rectangle<dim>*)arg;
|
||
|
|
if(!(this->IsDefined())
|
||
|
|
&& !r->IsDefined())
|
||
|
|
return 0;
|
||
|
|
if(!(this->IsDefined()))
|
||
|
|
return -1;
|
||
|
|
if(!r->IsDefined())
|
||
|
|
return 1;
|
||
|
|
//order on rectangles is z-order (bit interleaving)
|
||
|
|
// treat positive/negative quadrants
|
||
|
|
thispos = 0;
|
||
|
|
rpos = 0;
|
||
|
|
for (unsigned j = 0; j < dim; j++){
|
||
|
|
thispos <<= 1;
|
||
|
|
thispos |= (min[j] >= 0);
|
||
|
|
rpos <<= 1;
|
||
|
|
rpos |= (r->min[j] >= 0);
|
||
|
|
}
|
||
|
|
if (thispos < rpos){
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
if (thispos > rpos){
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// now treat z-order based on positive integer coordinates
|
||
|
|
for (unsigned j = 0; j < dim; j++){
|
||
|
|
thismin[j] = (unsigned) fabs(min[j]);
|
||
|
|
rmin[j] = (unsigned) fabs(r->min[j]);
|
||
|
|
}
|
||
|
|
|
||
|
|
int bits = sizeof(unsigned)*8-1;
|
||
|
|
for (int j = bits; j >= 0; j--){
|
||
|
|
thispos = 0;
|
||
|
|
rpos = 0;
|
||
|
|
for (unsigned k = 0; k < dim; k++){
|
||
|
|
thispos <<= 1;
|
||
|
|
thispos |= ((thismin[k] >> j) & 1);
|
||
|
|
rpos <<= 1;
|
||
|
|
rpos |= ((rmin[k] >> j) & 1);
|
||
|
|
}
|
||
|
|
if (thispos < rpos){
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
if (thispos > rpos){
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// if no conclusion on z-order (based on integer coordinates) can be
|
||
|
|
// reached, we fall back to the standard comparison
|
||
|
|
for( unsigned i = 0; i < dim; i++ ){
|
||
|
|
if( this->min[i] < r->min[i] ){
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
if( this->min[i] > r->min[i] ){
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
for( unsigned i = 0; i < dim; i++ ){
|
||
|
|
if( this->max[i] < r->max[i] ){
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
if( this->max[i] > r->max[i] ){
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
~Extend~
|
||
|
|
|
||
|
|
Enlarges this rectangle with a border of size ~b~. The function
|
||
|
|
changes the ~this~ object and returns it.
|
||
|
|
|
||
|
|
*/
|
||
|
|
inline const Rectangle<dim>& Extend(const double b);
|
||
|
|
|
||
|
|
inline bool Adjacent( const Attribute *arg ) const override
|
||
|
|
{ return false; }
|
||
|
|
|
||
|
|
inline Rectangle* Clone() const override
|
||
|
|
{ return new Rectangle<dim>( *this ); }
|
||
|
|
|
||
|
|
inline std::ostream& Print( std::ostream &os ) const override {
|
||
|
|
if( this->IsDefined() ){
|
||
|
|
os << "Rectangle: ( ";
|
||
|
|
for(unsigned int i=0; i < dim; i++)
|
||
|
|
os<<min[i]<<" "<<max[i]<<" ";
|
||
|
|
os<<")"<<std::endl;
|
||
|
|
return os;
|
||
|
|
} else {
|
||
|
|
return os << Symbol::UNDEFINED();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
inline double Size() const{
|
||
|
|
if(!this->IsDefined()){
|
||
|
|
return -1.0;
|
||
|
|
}
|
||
|
|
double accu = +0.0;
|
||
|
|
try{
|
||
|
|
accu = (max[0] - min[0]);
|
||
|
|
for(unsigned int i=1; i<dim; i++){
|
||
|
|
accu *= (max[i] - min[i]);
|
||
|
|
};
|
||
|
|
accu = std::abs(accu);
|
||
|
|
}
|
||
|
|
catch(...){ // catch any exception!
|
||
|
|
accu = -1.0;
|
||
|
|
}
|
||
|
|
return accu;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
Projection operator: Returns a 2D-Rectangle created by a projection of this
|
||
|
|
Rectangle to arbirary dimensions.
|
||
|
|
|
||
|
|
*/
|
||
|
|
Rectangle<2u> Project2D(int dX, int dY) const {
|
||
|
|
assert(dX >= 0);
|
||
|
|
assert((unsigned)dX < dim);
|
||
|
|
assert(dY >= 0);
|
||
|
|
assert((unsigned)dY < dim);
|
||
|
|
double minMax[] = {MinD(dX),MaxD(dX),MinD(dY),MaxD(dY)};
|
||
|
|
return
|
||
|
|
Rectangle<2u>(this->IsDefined(),minMax);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
Projection to the first newdim components of this rectangle.
|
||
|
|
Note: newdim must be
|
||
|
|
smaller or equal to the currect dimension for this rectangle.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template<int newdim>
|
||
|
|
Rectangle<newdim> project(){
|
||
|
|
assert(newdim<=dim);
|
||
|
|
Rectangle<newdim> res(this->IsDefined(), min, max);
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
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 ~Rectangle~
|
||
|
|
|
||
|
|
The first constructor. First one can set if the rectangle is defined,
|
||
|
|
and if it is, the coordinates can be set.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
inline Rectangle<dim>::Rectangle( bool defined, const double* minMax ):
|
||
|
|
StandardSpatialAttribute<dim>(defined)
|
||
|
|
{
|
||
|
|
for( unsigned i = 0; i < dim; i++ )
|
||
|
|
{
|
||
|
|
double d1 = defined?minMax[2*i]:0;
|
||
|
|
double d2 = defined?minMax[2*i+1]:0;
|
||
|
|
min[i] = d1;
|
||
|
|
max[i] = d2;
|
||
|
|
}
|
||
|
|
|
||
|
|
if( !Proper() )
|
||
|
|
{
|
||
|
|
static MessageCenter* msg = MessageCenter::GetInstance();
|
||
|
|
NList msgList( NList("simple"),
|
||
|
|
NList("Rectangle built with invalid dimensions!") );
|
||
|
|
msg->Send(nl,msgList.listExpr());
|
||
|
|
this->del.isDefined = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
template <unsigned dim>
|
||
|
|
inline Rectangle<dim>::Rectangle( bool defined ):
|
||
|
|
StandardSpatialAttribute<dim>(defined)
|
||
|
|
{
|
||
|
|
for( unsigned i = 0; i < dim; i++ )
|
||
|
|
{
|
||
|
|
min[i] = 0;
|
||
|
|
max[i] = 0;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
The second constructor. First one can set if the rectangle is defined,
|
||
|
|
and if it is, the coordinates can be set.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
inline Rectangle<dim>::Rectangle( const bool defined,
|
||
|
|
const double *min,
|
||
|
|
const double *max ):
|
||
|
|
StandardSpatialAttribute<dim>(defined)
|
||
|
|
{
|
||
|
|
Set(defined,min,max);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
The copy constructor.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
inline Rectangle<dim>::Rectangle( const Rectangle<dim>& r ):
|
||
|
|
StandardSpatialAttribute<dim>(r.IsDefined())
|
||
|
|
{
|
||
|
|
for( unsigned i = 0; i < dim; i++ )
|
||
|
|
{
|
||
|
|
min[i] = r.min[i];
|
||
|
|
max[i] = r.max[i];
|
||
|
|
}
|
||
|
|
assert( Proper() );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
Sets the values of this rectangle.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
inline void Rectangle<dim>::Set(const bool defined,
|
||
|
|
const double *min,
|
||
|
|
const double *max){
|
||
|
|
this->del.isDefined = defined;
|
||
|
|
for( unsigned i = 0; i < dim; i++ )
|
||
|
|
{
|
||
|
|
this->min[i] = defined?min[i]:0;
|
||
|
|
this->max[i] = defined?max[i]:0;
|
||
|
|
}
|
||
|
|
if( !Proper() )
|
||
|
|
{
|
||
|
|
static MessageCenter* msg = MessageCenter::GetInstance();
|
||
|
|
NList msgList( NList("simple"),
|
||
|
|
NList("Rectangle built with invalid dimensions!") );
|
||
|
|
msg->Send(nl,msgList.listExpr());
|
||
|
|
this->SetDefined(false);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Redefinition of operator ~=~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
inline Rectangle<dim>& Rectangle<dim>::operator=( const Rectangle<dim>& r )
|
||
|
|
{
|
||
|
|
this->del.isDefined = r.IsDefined();
|
||
|
|
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 <unsigned dim>
|
||
|
|
inline bool Rectangle<dim>::Contains( const Rectangle<dim>& r,
|
||
|
|
const Geoid* geoid/*=0*/ ) const
|
||
|
|
{
|
||
|
|
assert( (this->del.isDefined) && r.IsDefined()
|
||
|
|
&& (!geoid || geoid->IsDefined()) );
|
||
|
|
|
||
|
|
for( unsigned i = 0; i < dim; i++ ){
|
||
|
|
|
||
|
|
/*if( min[i] > r.min[i] || max[i] < r.max[i] ){ //original one
|
||
|
|
return false;
|
||
|
|
}*/
|
||
|
|
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 <unsigned dim>
|
||
|
|
inline bool Rectangle<dim>::Intersects( const Rectangle<dim>& r,
|
||
|
|
const Geoid* geoid/*=0*/ ) const
|
||
|
|
{
|
||
|
|
assert( this->del.isDefined && r.IsDefined()
|
||
|
|
&& (!geoid || geoid->IsDefined()));
|
||
|
|
|
||
|
|
for( unsigned i = 0; i < dim; i++ )
|
||
|
|
if( max[i] < r.min[i] || r.max[i] < min[i] )
|
||
|
|
return false;
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
template <unsigned dim>
|
||
|
|
inline bool Rectangle<dim>::IntersectsUD( const Rectangle<dim>& r,
|
||
|
|
const Geoid* geoid/*=0*/ ) const
|
||
|
|
{
|
||
|
|
if(!this->del.isDefined || !r.IsDefined()
|
||
|
|
|| (geoid && !geoid->IsDefined())){
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
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 <unsigned dim>
|
||
|
|
inline bool Rectangle<dim>::operator == ( const Rectangle<dim>& r ) const
|
||
|
|
{
|
||
|
|
assert( this->IsDefined());
|
||
|
|
assert( r.IsDefined() );
|
||
|
|
|
||
|
|
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 <unsigned dim>
|
||
|
|
inline bool Rectangle<dim>::AlmostEqual( const Rectangle<dim>& r ) const
|
||
|
|
{
|
||
|
|
if(!(this->del.isDefined) && !r.IsDefined()){
|
||
|
|
return true;
|
||
|
|
} else if(!(this->del.isDefined) || !r.IsDefined()){
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
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 <unsigned dim>
|
||
|
|
inline bool Rectangle<dim>::operator != ( const Rectangle<dim>& r ) const
|
||
|
|
{
|
||
|
|
return !(*this == r);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
Returns the area of a rectangle.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
inline double Rectangle<dim>::Area(const Geoid* geoid /*=0*/) const
|
||
|
|
{
|
||
|
|
if( !(this->del.isDefined) || (geoid && !geoid->IsDefined()))
|
||
|
|
return 0.0;
|
||
|
|
if(geoid){
|
||
|
|
std::cerr << ": Spherical geometry not implemented!" << std::endl;
|
||
|
|
assert(false);
|
||
|
|
}
|
||
|
|
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 <unsigned dim>
|
||
|
|
inline double Rectangle<dim>::Perimeter (const Geoid* geoid/*=0*/) const
|
||
|
|
{
|
||
|
|
if( !(this->del.isDefined) || (geoid && !geoid->IsDefined()) )
|
||
|
|
return 0.0;
|
||
|
|
if(geoid){
|
||
|
|
std::cerr << ": Spherical geometry not implemented!" << std::endl;
|
||
|
|
assert(false);
|
||
|
|
}
|
||
|
|
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 <unsigned dim>
|
||
|
|
inline const double Rectangle<dim>::MinD( int d ) const
|
||
|
|
{
|
||
|
|
assert( d >= 0 && (unsigned)d < dim );
|
||
|
|
return min[d];
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
Returns the max coord value for the given dimension ~d~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
inline const double Rectangle<dim>::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 <unsigned dim>
|
||
|
|
inline Rectangle<dim> Rectangle<dim>::Union( const Rectangle<dim>& r,
|
||
|
|
const Geoid* geoid /*=0*/ ) const
|
||
|
|
{
|
||
|
|
if( !this->del.isDefined || !r.IsDefined() || (geoid && !geoid->IsDefined()) )
|
||
|
|
return Rectangle<dim>( false );
|
||
|
|
if(geoid){
|
||
|
|
std::cerr << ": Spherical geometry not implemented!" << std::endl;
|
||
|
|
assert(false);
|
||
|
|
}
|
||
|
|
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 Rectangle<dim>( true, auxmin, auxmax );
|
||
|
|
}
|
||
|
|
|
||
|
|
template<unsigned dim>
|
||
|
|
inline void Rectangle<dim>::Extend(const Rectangle<dim>& r,
|
||
|
|
const Geoid* geoid /*=0*/ ){
|
||
|
|
|
||
|
|
assert(geoid==0); // not implemented yet
|
||
|
|
if(!this->del.isDefined){
|
||
|
|
if(!r.IsDefined()){
|
||
|
|
return;
|
||
|
|
} else {
|
||
|
|
*this = r;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if(!r.IsDefined()){
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
// both rectangle are defined
|
||
|
|
for(unsigned i=0;i<dim;i++){
|
||
|
|
min[i] = MIN(min[i],r.min[i]);
|
||
|
|
max[i] = MAX(max[i],r.max[i]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Translates the rectangle given the translate vector ~t~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
inline Rectangle<dim>& Rectangle<dim>::Translate( const double t[dim] )
|
||
|
|
{
|
||
|
|
if( (this->del.isDefined) )
|
||
|
|
{
|
||
|
|
for( unsigned i = 0; i < dim; i++ )
|
||
|
|
{
|
||
|
|
min[i] += t[i];
|
||
|
|
max[i] += t[i];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return *this;
|
||
|
|
}
|
||
|
|
|
||
|
|
template <unsigned dim>
|
||
|
|
inline const Rectangle<dim>& Rectangle<dim>::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 <unsigned dim>
|
||
|
|
inline const Rectangle<dim> Rectangle<dim>::BoundingBox(const Geoid* geoid)const
|
||
|
|
{
|
||
|
|
if(geoid){
|
||
|
|
std::cerr << __PRETTY_FUNCTION__ << ": Spherical geometry not implemented."
|
||
|
|
<< std::endl;
|
||
|
|
assert( !geoid ); // TODO: implement spherical geometry case
|
||
|
|
}
|
||
|
|
if( (this->del.isDefined) )
|
||
|
|
return Rectangle<dim>( *this );
|
||
|
|
else
|
||
|
|
return Rectangle<dim>( false );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
Returns the intersection between this and the rectangle ~r~.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
inline Rectangle<dim>
|
||
|
|
Rectangle<dim>::Intersection( const Rectangle<dim>& r,
|
||
|
|
const Geoid* geoid /*=0*/ ) const
|
||
|
|
{
|
||
|
|
if( !this->del.isDefined || !r.IsDefined() || (geoid && (!geoid->IsDefined()))
|
||
|
|
|| !Intersects( r,geoid ) ){
|
||
|
|
return Rectangle<dim>( false );
|
||
|
|
}
|
||
|
|
|
||
|
|
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 Rectangle<dim>( true, auxmin, auxmax );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
Returns ~true~ if this is a "proper" rectangle, i.e. it does not
|
||
|
|
represent an empty set.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
inline bool Rectangle<dim>::Proper() const
|
||
|
|
{
|
||
|
|
if( (this->del.isDefined) )
|
||
|
|
{
|
||
|
|
for( unsigned i = 0; i < dim; i++ )
|
||
|
|
if( min[i] > max[i] ) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
Distance: returns the Euclidean distance between two rectangles
|
||
|
|
|
||
|
|
*/
|
||
|
|
template<unsigned dim>
|
||
|
|
double geoDistance(const Rectangle<dim>& r1, const Rectangle<dim>& r2,
|
||
|
|
const Geoid* geoid){
|
||
|
|
assert(false);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
double geoDistance(const Rectangle<2>& r1, const Rectangle<2>& r2,
|
||
|
|
const Geoid* geoid);
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
template <unsigned dim>
|
||
|
|
inline double Rectangle<dim>::Distance(const Rectangle<dim>& r,
|
||
|
|
const Geoid* geoid /*=0*/) const
|
||
|
|
{
|
||
|
|
assert(this->del.isDefined);
|
||
|
|
assert(r.del.isDefined );
|
||
|
|
assert( !geoid || geoid->IsDefined() );
|
||
|
|
if(geoid){
|
||
|
|
return geoDistance(*this, r, geoid);
|
||
|
|
}
|
||
|
|
|
||
|
|
double sum = 0;
|
||
|
|
for( unsigned i = 0; i < dim; i++ )
|
||
|
|
{
|
||
|
|
if(r.min[i] >= max[i])
|
||
|
|
sum += std::pow( (max[i] - r.min[i]), 2 );
|
||
|
|
else if(r.max[i] <= min[i])
|
||
|
|
sum += std::pow( (min[i] - r.max[i]), 2 );
|
||
|
|
else if( (min[i] <= r.min[i] && r.min[i] <= max[i]) ||
|
||
|
|
(r.min[i] <= min[i] && min[i] <= r.max[i]) )
|
||
|
|
sum += 0;
|
||
|
|
else
|
||
|
|
{
|
||
|
|
cout << "Rectangle<dim>::Distance(): Missing case!" << std::endl
|
||
|
|
<< " min[" << i << "] = " << min[i]
|
||
|
|
<< " max[" << i << "] = " << max[i] << std::endl
|
||
|
|
<< " r.min[" << i << "] = " << r.min[i]
|
||
|
|
<< " r.max[" << i << "] = " << r.max[i] << std::endl;
|
||
|
|
assert( 0 );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return sqrt(sum);
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
QMaxMaxDistance
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
double Rectangle<dim>::QMaxMaxDistance(const Rectangle<dim>& r) const{
|
||
|
|
double sum = 0.0;
|
||
|
|
double aux[4];
|
||
|
|
for(unsigned i=0;i<dim;i++){
|
||
|
|
aux[0] = fabs(MinD(i) - r.MinD(i));
|
||
|
|
aux[1] = fabs(MinD(i) - r.MaxD(i));
|
||
|
|
aux[2] = fabs(MaxD(i) - r.MinD(i));
|
||
|
|
aux[3] = fabs(MaxD(i) - r.MaxD(i));
|
||
|
|
// determine the maximum of the values
|
||
|
|
double a = aux[0];
|
||
|
|
for(int j=1;j<4;j++){
|
||
|
|
if(aux[j]>a){
|
||
|
|
a = aux[j];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
sum += a*a;
|
||
|
|
}
|
||
|
|
return sum;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
QMinMaxDistance
|
||
|
|
|
||
|
|
*/
|
||
|
|
template<unsigned dim>
|
||
|
|
double Rectangle<dim>::QMinMaxDistance(const Rectangle<dim>& r) const{
|
||
|
|
double sum = QMaxMaxDistance(r);
|
||
|
|
double S[dim];
|
||
|
|
for (unsigned k=0;k<dim; k++){
|
||
|
|
S[k] = sum;
|
||
|
|
}
|
||
|
|
double aux[4];
|
||
|
|
for(unsigned k=0;k<dim;k++){
|
||
|
|
aux[0] = fabs(MinD(k) - r.MinD(k));
|
||
|
|
aux[1] = fabs(MinD(k) - r.MaxD(k));
|
||
|
|
aux[2] = fabs(MaxD(k) - r.MinD(k));
|
||
|
|
aux[3] = fabs(MaxD(k) - r.MaxD(k));
|
||
|
|
// subtract maximum value
|
||
|
|
double a = aux[0];
|
||
|
|
for(int j=1;j<4;j++){
|
||
|
|
if(aux[j]>a){
|
||
|
|
a = aux[j];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
S[k] -= a*a;
|
||
|
|
// add minimum value
|
||
|
|
a = aux[0];
|
||
|
|
for(int j=1;j<4;j++){
|
||
|
|
if(aux[j]<a){
|
||
|
|
a = aux[j];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
S[k] += a*a;
|
||
|
|
}
|
||
|
|
// find maximum value
|
||
|
|
double res = S[0];
|
||
|
|
for(unsigned k=1;k<dim;k++){
|
||
|
|
if(S[k] < res){
|
||
|
|
res = S[k];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
|
||
|
|
template<unsigned dim>
|
||
|
|
void Rectangle<dim>::scale(const double sf){
|
||
|
|
if(!this->IsDefined()){
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if(sf==0){
|
||
|
|
this->SetDefined(false);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
for(unsigned int i=0;i<dim;i++){
|
||
|
|
min[i] *= sf;
|
||
|
|
max[i] *= sf;
|
||
|
|
if(sf<0){
|
||
|
|
std::swap(min[i],max[i]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
5 Template functions for the type constructors
|
||
|
|
|
||
|
|
5.1 ~Out~-function
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
ListExpr OutRectangle( ListExpr typeInfo, Word value )
|
||
|
|
{
|
||
|
|
Rectangle<dim> *r = (Rectangle<dim>*)value.addr;
|
||
|
|
if( r->IsDefined() )
|
||
|
|
{
|
||
|
|
ListExpr result = nl->OneElemList( nl->RealAtom( r->MinD(0) ) ),
|
||
|
|
last = result;
|
||
|
|
last = nl->Append( last, nl->RealAtom( r->MaxD(0) ) );
|
||
|
|
|
||
|
|
for( unsigned i = 1; i < dim; i++ )
|
||
|
|
{
|
||
|
|
last = nl->Append( last, nl->RealAtom( r->MinD(i) ) );
|
||
|
|
last = nl->Append( last, nl->RealAtom( r->MaxD(i) ) );
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
return (nl->SymbolAtom(Symbol::UNDEFINED()));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.2 ~In~-function
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
Word InRectangle( const ListExpr typeInfo, const ListExpr instance,
|
||
|
|
const int errorPos, ListExpr& errorInfo, bool& correct )
|
||
|
|
{
|
||
|
|
ListExpr l = instance;
|
||
|
|
|
||
|
|
|
||
|
|
if( nl->ListLength( instance ) == 2 * dim )
|
||
|
|
{
|
||
|
|
correct = true;
|
||
|
|
double min[dim], max[dim];
|
||
|
|
|
||
|
|
for( unsigned i = 0; i < dim; i++ )
|
||
|
|
{
|
||
|
|
if( nl->IsAtom( nl->First( l ) ) &&
|
||
|
|
nl->AtomType( nl->First( l ) ) == RealType )
|
||
|
|
{
|
||
|
|
min[i] = nl->RealValue( nl->First( l ) );
|
||
|
|
l = nl->Rest( l );
|
||
|
|
}
|
||
|
|
else if( nl->IsAtom(nl->First(l)) &&
|
||
|
|
nl->AtomType(nl->First(l)) == IntType)
|
||
|
|
{
|
||
|
|
min[i] = nl->IntValue(nl->First(l));
|
||
|
|
l = nl->Rest(l);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
correct = false;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if( nl->IsAtom( nl->First( l ) ) &&
|
||
|
|
nl->AtomType( nl->First( l ) ) == RealType )
|
||
|
|
{
|
||
|
|
max[i] = nl->RealValue( nl->First( l ) );
|
||
|
|
l = nl->Rest( l );
|
||
|
|
}
|
||
|
|
else if(nl->IsAtom(nl->First(l)) &&
|
||
|
|
nl->AtomType(nl->First(l)) == IntType )
|
||
|
|
{
|
||
|
|
max[i] = nl->IntValue(nl->First(l));
|
||
|
|
l = nl->Rest(l);
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
correct = false;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if( correct )
|
||
|
|
{
|
||
|
|
Rectangle<dim> *r = new Rectangle<dim>( true, min, max );
|
||
|
|
if( !r->IsDefined() )
|
||
|
|
{
|
||
|
|
correct = false;
|
||
|
|
delete r;
|
||
|
|
return SetWord(Address(0));
|
||
|
|
}
|
||
|
|
return SetWord( r );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if ( listutils::isSymbolUndefined(instance))
|
||
|
|
{
|
||
|
|
correct = true;
|
||
|
|
return SetWord( new Rectangle<3>( false,0,0 ) );
|
||
|
|
}
|
||
|
|
correct = false;
|
||
|
|
return SetWord( Address( 0 ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.1 ~Create~-function
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
Word CreateRectangle( const ListExpr typeInfo )
|
||
|
|
{
|
||
|
|
return SetWord( new Rectangle<dim>( false ) );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.2 ~Delete~-function
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
void DeleteRectangle( const ListExpr typeInfo, Word& w )
|
||
|
|
{
|
||
|
|
delete (Rectangle<dim> *)w.addr;
|
||
|
|
w.addr = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.3 ~Close~-function
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
void CloseRectangle( const ListExpr typeInfo, Word& w )
|
||
|
|
{
|
||
|
|
delete (Rectangle<dim> *)w.addr;
|
||
|
|
w.addr = 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.4 ~Clone~-function
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
Word CloneRectangle( const ListExpr typeInfo, const Word& w )
|
||
|
|
{
|
||
|
|
Rectangle<dim> *r = new Rectangle<dim>( *((Rectangle<dim> *)w.addr) );
|
||
|
|
return SetWord( r );
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
5.5 ~Cast~-function
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
void* CastRectangle(void* addr)
|
||
|
|
{
|
||
|
|
return new (addr) Rectangle<dim>;
|
||
|
|
}
|
||
|
|
|
||
|
|
/*
|
||
|
|
3.11 ~SizeOf~-function
|
||
|
|
|
||
|
|
*/
|
||
|
|
template <unsigned dim>
|
||
|
|
int SizeOfRectangle()
|
||
|
|
{
|
||
|
|
return sizeof(Rectangle<dim>);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
Word
|
||
|
|
InRectangle( const ListExpr typeInfo, const ListExpr instance,
|
||
|
|
const int errorPos, ListExpr& errorInfo, bool& correct );
|
||
|
|
|
||
|
|
/*
|
||
|
|
4 Class ~RectangleSet~
|
||
|
|
|
||
|
|
This class simply contains a set of rectangles. It is used by the
|
||
|
|
MON-Tree to search in an R-Tree using a set of rectangles instead
|
||
|
|
of only one.
|
||
|
|
|
||
|
|
2.3 Struct ~RectangleSet~
|
||
|
|
|
||
|
|
This structure contains a set of rectangles used in the
|
||
|
|
MON-Tree search.
|
||
|
|
|
||
|
|
*/
|
||
|
|
template<unsigned dim>
|
||
|
|
class RectangleSet
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
RectangleSet()
|
||
|
|
{}
|
||
|
|
|
||
|
|
inline RectangleSet<dim>& operator = ( const RectangleSet<dim>& r )
|
||
|
|
{
|
||
|
|
set.clear();
|
||
|
|
set = r.set;
|
||
|
|
return *this;
|
||
|
|
}
|
||
|
|
|
||
|
|
virtual ~RectangleSet(){}
|
||
|
|
|
||
|
|
inline virtual bool Intersects( const Rectangle<dim>& r ) const
|
||
|
|
{
|
||
|
|
if( set.empty() )
|
||
|
|
return false;
|
||
|
|
|
||
|
|
for( size_t i = 0; i < set.size(); i++ )
|
||
|
|
if( set[i].Intersects( r ) )
|
||
|
|
return true;
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
size_t Size() const
|
||
|
|
{ return set.size(); }
|
||
|
|
|
||
|
|
void Add( const Rectangle<dim>& r )
|
||
|
|
{
|
||
|
|
set.push_back( r );
|
||
|
|
}
|
||
|
|
|
||
|
|
void Clear()
|
||
|
|
{ set.clear(); }
|
||
|
|
|
||
|
|
protected:
|
||
|
|
std::vector< Rectangle<dim> > set;
|
||
|
|
};
|
||
|
|
|
||
|
|
typedef Rectangle<1> Rect1;
|
||
|
|
typedef Rectangle<2> Rect;
|
||
|
|
typedef Rectangle<3> Rect3;
|
||
|
|
typedef Rectangle<4> Rect4;
|
||
|
|
typedef Rectangle<8> Rect8;
|
||
|
|
|
||
|
|
#endif
|
||
|
|
|