811 lines
23 KiB
C++
811 lines
23 KiB
C++
/*
|
|
----
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2017, 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
|
|
----
|
|
|
|
*/
|
|
|
|
#ifndef SECONDO_POINTCLOUD_H
|
|
#define SECONDO_POINTCLOUD_H
|
|
|
|
#include "Tools/Flob/DbArray.h"
|
|
#include "Attribute.h"
|
|
#include "Operator.h"
|
|
#include "Algebras/Rectangle/RectangleAlgebra.h"
|
|
#include "Algebra.h"
|
|
#include "NestedList.h"
|
|
#include "QueryProcessor.h"
|
|
#include "AlgebraManager.h"
|
|
#include "Operator.h"
|
|
#include "StandardTypes.h"
|
|
#include "Algebras/FText/FTextAlgebra.h"
|
|
#include "NList.h"
|
|
#include "Symbols.h"
|
|
#include "ListUtils.h"
|
|
#include "Stream.h"
|
|
|
|
|
|
namespace pointcloud {
|
|
|
|
/*
|
|
PointCloud object and related types added and maintained
|
|
by Gundula Swidersky, Dec 2017.
|
|
*/
|
|
|
|
/*
|
|
Type Cpoint (x, y, z)
|
|
*/
|
|
class Cpoint : public Attribute {
|
|
public:
|
|
// constructor doing nothing
|
|
Cpoint() {}
|
|
// constructor initialzing the object
|
|
Cpoint(const double _x, const double _y, const double _z):
|
|
Attribute(true),
|
|
x(_x), y(_y),z(_z) {}
|
|
// destructor
|
|
~Cpoint() {}
|
|
|
|
/*
|
|
BasicType
|
|
*/
|
|
static const std::string BasicType() { return "cpoint"; }
|
|
|
|
/*
|
|
checkType
|
|
*/
|
|
static const bool checkType(const ListExpr list){
|
|
return listutils::isSymbol(list, BasicType());
|
|
}
|
|
|
|
/*
|
|
Getter / Setter and help functions
|
|
*/
|
|
double getX() const;
|
|
double getY() const;
|
|
double getZ() const;
|
|
|
|
/*
|
|
NumOfFlobs
|
|
*/
|
|
int NumOfFLOBs() const;
|
|
|
|
/*
|
|
GetFlob
|
|
*/
|
|
Flob* GetFLOB ( const int i );
|
|
|
|
/*
|
|
Compare
|
|
*/
|
|
int Compare (const Attribute * arg ) const;
|
|
|
|
/*
|
|
Adjacent
|
|
*/
|
|
bool Adjacent ( const Attribute * arg) const;
|
|
|
|
/*
|
|
SizeOf
|
|
*/
|
|
size_t Sizeof () const;
|
|
|
|
/*
|
|
HashValue
|
|
*/
|
|
size_t HashValue () const;
|
|
|
|
/*
|
|
CopyFrom
|
|
*/
|
|
void CopyFrom ( const Attribute* arg );
|
|
|
|
/*
|
|
Clone
|
|
*/
|
|
Attribute *Clone () const;
|
|
|
|
/*
|
|
Property function
|
|
*/
|
|
ListExpr CpointProperty();
|
|
|
|
/*
|
|
IN function
|
|
*/
|
|
Word InCpoint (const ListExpr typeinfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct );
|
|
|
|
/*
|
|
OUT function
|
|
*/
|
|
ListExpr OutCpoint(ListExpr typeInfo, Word value);
|
|
|
|
/*
|
|
Create
|
|
*/
|
|
Word CreateCpoint(const ListExpr typeInfo);
|
|
|
|
/*
|
|
Delete
|
|
*/
|
|
void DeleteCpoint(const ListExpr typeInfo, Word& w);
|
|
|
|
/*
|
|
Close
|
|
*/
|
|
void CloseCpoint (const ListExpr typeInfo, Word& w );
|
|
|
|
/*
|
|
Clone
|
|
*/
|
|
Word CloneCpoint( const ListExpr typeInfo, const Word& w);
|
|
|
|
/*
|
|
Cast
|
|
*/
|
|
void* CastCpoint(void* addr);
|
|
|
|
/*
|
|
TypeCheck
|
|
*/
|
|
bool CpointTypeCheck(ListExpr type, ListExpr& errorInfo);
|
|
|
|
/*
|
|
SizeOfCpoint
|
|
*/
|
|
int SizeOfCpoint();
|
|
|
|
private:
|
|
double x;
|
|
double y;
|
|
double z;
|
|
};
|
|
|
|
/*
|
|
Type Cpoints (DBArray of type Cpoint)
|
|
*/
|
|
class Cpoints : public Attribute {
|
|
public:
|
|
// constructor doing nothing
|
|
Cpoints() {}
|
|
// constructor initialzing the object
|
|
Cpoints(const int anz, const double *X= 0, const double *Y = 0,
|
|
const double *Z = 0) :
|
|
Attribute(true),
|
|
cpoints ( anz ) {
|
|
SetDefined(true);
|
|
Cpoint* cpnt;
|
|
if(anz > 0) {
|
|
for( int i = 0; i < anz; i++) {
|
|
cpnt = new Cpoint( X[i], Y[i], Z[i] );
|
|
cpoints.Append( *cpnt );
|
|
}
|
|
}
|
|
}
|
|
// destructor
|
|
~Cpoints() {}
|
|
|
|
/*
|
|
BasicType
|
|
*/
|
|
static const std::string BasicType() { return "cpoints"; }
|
|
|
|
/*
|
|
checkType
|
|
*/
|
|
static const bool checkType(const ListExpr list){
|
|
return listutils::isSymbol(list, BasicType());
|
|
}
|
|
|
|
/*
|
|
NumOfFlobs
|
|
*/
|
|
int NumOfFLOBs() const;
|
|
|
|
/*
|
|
GetFlob
|
|
*/
|
|
Flob* GetFLOB ( const int i );
|
|
|
|
/*
|
|
GetNoCpoints
|
|
*/
|
|
int GetNoCpoints();
|
|
|
|
/*
|
|
GetCpoint
|
|
*/
|
|
Cpoint GetCpoint(int i);
|
|
|
|
/*
|
|
AppendCpoint
|
|
*/
|
|
void AppendCpoint(const Cpoint &cpnt);
|
|
|
|
/*
|
|
Destroy
|
|
*/
|
|
void DestroyCpoints();
|
|
|
|
/*
|
|
Compare
|
|
*/
|
|
int Compare (const Attribute * arg ) const;
|
|
|
|
/*
|
|
Adjacent
|
|
*/
|
|
bool Adjacent ( const Attribute * arg) const;
|
|
|
|
/*
|
|
Sizeof Cpoints
|
|
*/
|
|
size_t Sizeof () const;
|
|
|
|
/*
|
|
HashValue
|
|
*/
|
|
size_t HashValue () const;
|
|
|
|
/*
|
|
CopyFrom
|
|
*/
|
|
void CopyFrom ( const Attribute* arg );
|
|
|
|
/*
|
|
Clone
|
|
*/
|
|
Attribute *Clone () const;
|
|
|
|
private:
|
|
DbArray<Cpoint> cpoints;
|
|
};
|
|
|
|
/*
|
|
Type Cpointnode that is a node of an 2D Tree that is the internal
|
|
data structure of the Cpoints stored within a PointCloud object. It
|
|
contains Cpoint coordinates and indexes of left son and right son.
|
|
*/
|
|
class Cpointnode : public Attribute {
|
|
public:
|
|
// constructor doing nothing
|
|
Cpointnode() {}
|
|
// constructor initialzing the object
|
|
Cpointnode(const double _x, const double _y, const double _z,
|
|
const int _leftson, const int _rightson):
|
|
Attribute(true),
|
|
x(_x), y(_y),z(_z),leftson(_leftson),rightson(_rightson) {}
|
|
// destructor
|
|
~Cpointnode() {}
|
|
|
|
/*
|
|
BasicType
|
|
*/
|
|
static const std::string BasicType() { return "cpointnode"; }
|
|
|
|
/*
|
|
checkType
|
|
*/
|
|
static const bool checkType(const ListExpr list){
|
|
return listutils::isSymbol(list, BasicType());
|
|
}
|
|
|
|
/*
|
|
Getter, setter and help functions
|
|
*/
|
|
double getX() const;
|
|
double getY() const;
|
|
double getZ() const;
|
|
int getLeftSon() const;
|
|
int getRightSon() const;
|
|
void setLeftSon(int lSon);
|
|
void setRightSon(int rSon);
|
|
|
|
/*
|
|
NumOfFlobs
|
|
*/
|
|
int NumOfFLOBs() const;
|
|
|
|
/*
|
|
GetFlob
|
|
*/
|
|
Flob* GetFLOB ( const int i );
|
|
|
|
/*
|
|
Compare
|
|
*/
|
|
int Compare (const Attribute * arg ) const;
|
|
|
|
/*
|
|
Adjacent
|
|
*/
|
|
bool Adjacent ( const Attribute * arg) const;
|
|
|
|
/*
|
|
Sizeof Cpointnode
|
|
*/
|
|
size_t Sizeof () const;
|
|
|
|
/*
|
|
HashValue
|
|
*/
|
|
size_t HashValue () const;
|
|
|
|
/*
|
|
CopyFrom
|
|
*/
|
|
void CopyFrom ( const Attribute* arg );
|
|
|
|
/*
|
|
Clone
|
|
*/
|
|
Attribute *Clone () const;
|
|
|
|
std::ostream& print(std::ostream& out) const{
|
|
out << "x = " << x <<", y = " << y << "z = " << z
|
|
<< ", left = " << leftson
|
|
<< ", right = " << rightson;
|
|
return out;
|
|
}
|
|
|
|
private:
|
|
double x;
|
|
double y;
|
|
double z;
|
|
int leftson;
|
|
int rightson;
|
|
};
|
|
|
|
/*
|
|
Type Pointcloud contains a 2D Tree with Cpoints and
|
|
the x and y-coordinates of the area (bbox) in which the
|
|
Cpoints are located.
|
|
*/
|
|
class PointCloud : public StandardSpatialAttribute<2> {
|
|
public:
|
|
// constructor doing nothing
|
|
PointCloud() {}
|
|
// constructor initialzing the object
|
|
PointCloud(const int anzp,
|
|
const double *X= 0, const double *Y= 0, const double *Z= 0,
|
|
const int *Lson= 0, const int *Rson= 0,
|
|
const double Xmin = 0, const double Xmax = 0,
|
|
const double Ymin = 0, const double Ymax = 0):
|
|
StandardSpatialAttribute(true),
|
|
cpoint2dtree ( anzp ) {
|
|
SetDefined(true);
|
|
minZ = anzp>0?Z[0]:std::numeric_limits<double>::max();
|
|
maxZ = anzp>0?Z[0]:std::numeric_limits<double>::min();
|
|
if(anzp > 0) {
|
|
for( int i = 0; i < anzp; i++) {
|
|
cpoint2dtree.Append(
|
|
Cpointnode(X[i], Y[i], Z[i], Lson[i], Rson[i]));
|
|
if(Z[i] < minZ) minZ = Z[i];
|
|
if(Z[i] > maxZ) maxZ = Z[i];
|
|
}
|
|
}
|
|
minX = Xmin;
|
|
maxX = Xmax;
|
|
minY = Ymin;
|
|
maxY = Ymax;
|
|
}
|
|
|
|
// Copy contructor
|
|
PointCloud(const PointCloud& pc):
|
|
StandardSpatialAttribute(pc.IsDefined()),
|
|
cpoint2dtree(0), minX(pc.minX),
|
|
maxX(pc.maxX), minY(pc.minY), maxY(pc.maxY),
|
|
minZ(pc.minZ), maxZ(pc.maxZ){
|
|
cpoint2dtree.copyFrom(pc.cpoint2dtree);
|
|
}
|
|
|
|
PointCloud& operator=(const PointCloud& pc){
|
|
cpoint2dtree.copyFrom(pc.cpoint2dtree);
|
|
minX = pc.minX;
|
|
maxX = pc.maxX;
|
|
minY = pc.minY;
|
|
maxY = pc.maxY;
|
|
minZ = pc.minZ;
|
|
maxZ = pc.maxZ;
|
|
return *this;
|
|
}
|
|
|
|
|
|
// destructor
|
|
~PointCloud() {}
|
|
|
|
/*
|
|
BasicType
|
|
*/
|
|
static const std::string BasicType() { return "pointcloud"; }
|
|
|
|
/*
|
|
checkType
|
|
*/
|
|
static const bool checkType(const ListExpr list){
|
|
return listutils::isSymbol(list, BasicType());
|
|
}
|
|
|
|
/*
|
|
Getter / Setter and help functions
|
|
*/
|
|
double getMinX() const;
|
|
double getMaxX() const;
|
|
double getMinY() const;
|
|
double getMaxY() const;
|
|
double getMinZ() const{
|
|
return minZ;
|
|
}
|
|
double getMaxZ() const{
|
|
return maxZ;
|
|
}
|
|
|
|
void setMinX(const double minx);
|
|
void setMaxX(const double maxx);
|
|
void setMinY(const double miny);
|
|
void setMaxY(const double maxy);
|
|
|
|
/*
|
|
NumOfFlobs
|
|
*/
|
|
int NumOfFLOBs() const;
|
|
|
|
/*
|
|
GetFlob
|
|
*/
|
|
Flob* GetFLOB ( const int i );
|
|
|
|
/*
|
|
GetNoCpointnodes
|
|
*/
|
|
int GetNoCpointnodes();
|
|
|
|
/*
|
|
Get Cpointnode
|
|
*/
|
|
Cpointnode GetCpointnode(int i);
|
|
|
|
/*
|
|
SetCpointnode
|
|
*/
|
|
//void SetCpointnode(int i, Cpointnode* cpnode);
|
|
void changeLeftSon(const int idx, const int newSon){
|
|
Cpointnode node;
|
|
cpoint2dtree.Get(idx,node);
|
|
node.setLeftSon(newSon);
|
|
cpoint2dtree.Put(idx,node);
|
|
}
|
|
|
|
void changeRightSon(const int idx, const int newSon){
|
|
Cpointnode node;
|
|
cpoint2dtree.Get(idx,node);
|
|
node.setRightSon(newSon);
|
|
cpoint2dtree.Put(idx,node);
|
|
}
|
|
|
|
|
|
/*
|
|
AppendCpointnode
|
|
*/
|
|
//void AppendCpointnode(const Cpointnode &cpntnode);
|
|
|
|
/*
|
|
Insertion of an element including adaption of the tree
|
|
*/
|
|
bool insert(const double x, const double y, const double z);
|
|
|
|
|
|
/*
|
|
Destroy
|
|
*/
|
|
void DestroyPointCloud();
|
|
|
|
/*
|
|
Compare
|
|
*/
|
|
int Compare (const Attribute * arg ) const;
|
|
|
|
/*
|
|
Adjacent
|
|
*/
|
|
bool Adjacent ( const Attribute * arg) const;
|
|
|
|
/*
|
|
Sizeof PointCloud
|
|
*/
|
|
size_t Sizeof () const;
|
|
|
|
/*
|
|
HashValue
|
|
*/
|
|
size_t HashValue () const;
|
|
|
|
/*
|
|
CopyFrom
|
|
*/
|
|
void CopyFrom ( const Attribute* arg );
|
|
|
|
/*
|
|
Clone
|
|
*/
|
|
Attribute *Clone () const;
|
|
|
|
/*
|
|
getAllPointsInRange
|
|
*/
|
|
Cpoints* getAllPointsInRange(const double x1, const double y1,
|
|
const double x2, const double y2) {
|
|
// Go through the 2D Tree, search the area with help of
|
|
// intersection of regions built by the points.
|
|
double r2min[2], r2max[2];
|
|
r2min[0] = (x1 < x2)? x1: x2;
|
|
r2max[0] = (x1 < x2)? x2: x1;
|
|
r2min[1] = (y1 < y2)? y1: y2;
|
|
r2max[1] = (y1 < y2)? y2: y1;
|
|
int chkDim = 1;
|
|
int idx = 0;
|
|
Rectangle<2> rect2 = Rectangle<2>(true, r2min, r2max);
|
|
if (!this->Intersects(rect2)) {
|
|
//cout << "No point within requested area" << endl;
|
|
return 0;
|
|
}
|
|
Cpoints* rangePoints = new Cpoints(0);
|
|
// go through the 2D Tree
|
|
search2DTree(this->BoundingBox(), rect2, rangePoints, idx, chkDim);
|
|
return rangePoints;
|
|
}
|
|
|
|
void search2DTree(Rectangle<2> rect1, Rectangle<2> rect2,
|
|
Cpoints* resultPoints, int idx, int chkDim) {
|
|
if (this->GetNoCpointnodes() < 1) {
|
|
// there are no points within this PC
|
|
// cout << "PC does not contain any points." << endl;
|
|
} else {
|
|
Cpointnode tempnode = this->GetCpointnode(idx);
|
|
Cpointnode* cptnode = &tempnode;
|
|
double curX, curY;
|
|
bool searchLeft = false;
|
|
bool searchRight = false;
|
|
double r3min[2], r3max[2];
|
|
double r4min[2], r4max[2];
|
|
curX = cptnode->getX();
|
|
curY = cptnode->getY();
|
|
// check if current point matches
|
|
if ((curX >= ((Rectangle<2>*) &rect2)->Rectangle<2>::MinD(0))
|
|
&&
|
|
(curX <= ((Rectangle<2>*) &rect2)->Rectangle<2>::MaxD(0))
|
|
&&
|
|
(curY >= ((Rectangle<2>*) &rect2)->Rectangle<2>::MinD(1))
|
|
&&
|
|
(curY <= ((Rectangle<2>*) &rect2)->Rectangle<2>::MaxD(1))) {
|
|
resultPoints->AppendCpoint(Cpoint(curX, curY,
|
|
cptnode->getZ()));
|
|
}
|
|
if (chkDim == 1) {
|
|
// check X
|
|
// build new rectangles to check for intersection
|
|
// determine search direction upon result
|
|
// cout << " Check dim X" << endl;
|
|
r3min[0] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MinD(0);
|
|
r3min[1] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MinD(1);
|
|
r3max[0] = curX;
|
|
r3max[1] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MaxD(1);
|
|
r4min[0] = curX;
|
|
r4min[1] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MinD(1);
|
|
r4max[0] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MaxD(0);
|
|
r4max[1] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MaxD(1);
|
|
|
|
} else {
|
|
// check y
|
|
// build new rectangles to check for intersection
|
|
// determine search direction upon result
|
|
// cout << " Check dim Y" << endl;
|
|
r3min[0] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MinD(0);
|
|
r3min[1] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MinD(1);
|
|
r3max[0] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MaxD(0);
|
|
r3max[1] = curY;
|
|
r4min[0] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MinD(0);
|
|
r4min[1] = curY;
|
|
r4max[0] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MaxD(0);
|
|
r4max[1] = ((Rectangle<2>*) &rect1)->Rectangle<2>::MaxD(1);
|
|
}
|
|
|
|
Rectangle<2> rect3 = Rectangle<2>(true, r3min, r3max);
|
|
Rectangle<2> rect4 = Rectangle<2>(true, r4min, r4max);
|
|
|
|
|
|
if (intersects2(rect3, rect2)) {
|
|
searchLeft = true;
|
|
} else {
|
|
searchLeft = false;
|
|
}
|
|
if (intersects2(rect4, rect2)) {
|
|
searchRight = true;
|
|
} else {
|
|
searchRight = false;
|
|
}
|
|
if ((searchLeft) && (cptnode->getLeftSon() != -1)) {
|
|
search2DTree(rect3, rect2, resultPoints,
|
|
cptnode->getLeftSon(), (-1 * chkDim));
|
|
}
|
|
if ((searchRight) && (cptnode->getRightSon() != -1)) {
|
|
search2DTree(rect4, rect2, resultPoints,
|
|
cptnode->getRightSon(), (-1 * chkDim));
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
BoundingBox (SpatialAttribute)
|
|
*/
|
|
const Rectangle<2> BoundingBox(const Geoid* geoid = 0) const {
|
|
double cpmin[2], cpmax[2];
|
|
cpmin[0] = minX;
|
|
cpmin[1] = minY;
|
|
cpmax[0] = maxX;
|
|
cpmax[1] = maxY;
|
|
return Rectangle<2>(true, cpmin, cpmax);
|
|
}
|
|
/*
|
|
getMinMaxZ
|
|
*/
|
|
void getMinMaxZ(double& min, double& max) {
|
|
min = minZ;
|
|
max = maxZ;
|
|
}
|
|
|
|
/*
|
|
BoundingBox3d
|
|
*/
|
|
const Rectangle<3> BoundingBox3d() {
|
|
if(cpoint2dtree.Size()==0){
|
|
return Rectangle<3>(false);
|
|
}
|
|
double min[3], max[3];
|
|
min[0] = minX;
|
|
min[1] = minY;
|
|
max[0] = maxX;
|
|
max[1] = maxY;
|
|
getMinMaxZ(min[2], max[2]);
|
|
return Rectangle<3>(true, min, max);
|
|
}
|
|
|
|
/*
|
|
Distance (SpatialAttribute)
|
|
*/
|
|
double Distance(const Rectangle<2>& rect,
|
|
const Geoid* geoid=0) const {
|
|
// Remark: Usage of Geoid not implemented.
|
|
// This method calculates the shortest distance
|
|
// between the given two Bboxes
|
|
//
|
|
if (this->Intersects(rect)) {
|
|
// interesection means distance = 0.0
|
|
return 0.0;
|
|
}
|
|
// Calculate minimum distance between Bboxes
|
|
// position of bboxes to each other not known yet.
|
|
Rectangle<2> checkRect = rect;
|
|
double distX = 0.0;
|
|
double distY = 0.0;
|
|
double minX2 = ((Rectangle<2>*) &checkRect)->Rectangle<2>::MinD(0);
|
|
double maxX2 = ((Rectangle<2>*) &checkRect)->Rectangle<2>::MaxD(0);
|
|
double minY2 = ((Rectangle<2>*) &checkRect)->Rectangle<2>::MinD(1);
|
|
double maxY2 = ((Rectangle<2>*) &checkRect)->Rectangle<2>::MaxD(1);
|
|
if (maxX2 < minX) {
|
|
distX = minX - maxX2;
|
|
} else {
|
|
if (maxX < minX2) {
|
|
distX = minX2 - maxX;
|
|
}
|
|
}
|
|
if (maxY2 < minY) {
|
|
distY = minY - maxY2;
|
|
} else {
|
|
if (maxY < minY2) {
|
|
distY = minY2 - maxY;
|
|
}
|
|
}
|
|
if (distX < distY) {
|
|
return distX;
|
|
}
|
|
return distY;
|
|
}
|
|
|
|
/*
|
|
Intersects (SpatialAttribute)
|
|
*/
|
|
bool Intersects(const Rectangle<2>& rect,
|
|
const Geoid* geoid=0 ) const {
|
|
double minX2 = ((Rectangle<2>*) &rect)->Rectangle<2>::MinD(0);
|
|
double maxX2 = ((Rectangle<2>*) &rect)->Rectangle<2>::MaxD(0);
|
|
double minY2 = ((Rectangle<2>*) &rect)->Rectangle<2>::MinD(1);
|
|
double maxY2 = ((Rectangle<2>*) &rect)->Rectangle<2>::MaxD(1);
|
|
bool disjointX, disjointY;
|
|
disjointX = ((maxX2 < minX) || (maxX < minX2)) ? true : false;
|
|
disjointY = ((maxY2 < minY) || (maxY < minY2)) ? true : false;
|
|
|
|
return (!disjointX && !disjointY);
|
|
}
|
|
|
|
/*
|
|
IsEmpty (SpatialAttribute)
|
|
*/
|
|
bool IsEmpty() const {
|
|
// check amount of elem in point
|
|
return cpoint2dtree.Size()==0;
|
|
}
|
|
|
|
bool intersects2(const Rectangle<2> rect1, const Rectangle<2> rect2) {
|
|
// Check wether given rectangles intersect
|
|
double minX1 = ((Rectangle<2>*) &rect1)->Rectangle<2>::MinD(0);
|
|
double maxX1 = ((Rectangle<2>*) &rect1)->Rectangle<2>::MaxD(0);
|
|
double minY1 = ((Rectangle<2>*) &rect1)->Rectangle<2>::MinD(1);
|
|
double maxY1 = ((Rectangle<2>*) &rect1)->Rectangle<2>::MaxD(1);
|
|
double minX2 = ((Rectangle<2>*) &rect2)->Rectangle<2>::MinD(0);
|
|
double maxX2 = ((Rectangle<2>*) &rect2)->Rectangle<2>::MaxD(0);
|
|
double minY2 = ((Rectangle<2>*) &rect2)->Rectangle<2>::MinD(1);
|
|
double maxY2 = ((Rectangle<2>*) &rect2)->Rectangle<2>::MaxD(1);
|
|
bool disjointX, disjointY;
|
|
disjointX = ((maxX2 < minX1) || (maxX1 < minX2)) ? true : false;
|
|
disjointY = ((maxY2 < minY1) || (maxY1 < minY2)) ? true : false;
|
|
return (!disjointX && !disjointY);
|
|
}
|
|
|
|
std::ostream& print(std::ostream& out) const{
|
|
if(!IsDefined()){
|
|
out << "undefined" << endl;
|
|
return out;
|
|
}
|
|
out << "minX = " << minX << ", maxX = " << maxX << endl
|
|
<< "minY = " << minY << ", maxY = " << maxY << endl
|
|
<< "minZ = " << minZ << ", maxZ = " << maxZ << endl;
|
|
out << "Nodes of tree:" << endl;
|
|
Cpointnode node;
|
|
for(int i=0;i<cpoint2dtree.Size();i++){
|
|
cpoint2dtree.Get(i,node);
|
|
out << i << " : ";
|
|
node.print(out) << endl;
|
|
}
|
|
return out;
|
|
|
|
|
|
}
|
|
private:
|
|
DbArray<Cpointnode> cpoint2dtree;
|
|
// Bounding box of pointcloud
|
|
double minX;
|
|
double maxX;
|
|
double minY;
|
|
double maxY;
|
|
double minZ;
|
|
double maxZ;
|
|
};
|
|
|
|
}
|
|
|
|
std::ostream& operator<<(std::ostream& out,
|
|
const pointcloud::PointCloud&);
|
|
|
|
|
|
|
|
#endif //SECONDO_POINTCLOUD_H
|