566 lines
12 KiB
C++
566 lines
12 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
|
|
----
|
|
|
|
*/
|
|
|
|
#include "PointCloud.h"
|
|
|
|
namespace pointcloud {
|
|
|
|
/*
|
|
PointCloud object and related types added and maintained
|
|
by Gundula Swidersky, Dec 2017.
|
|
*/
|
|
|
|
/*
|
|
Begin Cpoint
|
|
*/
|
|
|
|
/*
|
|
NumOfFlobs
|
|
*/
|
|
int Cpoint::NumOfFLOBs() const {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
GetFlob
|
|
*/
|
|
Flob* Cpoint::GetFLOB ( const int i ) {
|
|
assert(false);
|
|
}
|
|
|
|
/*
|
|
Compare
|
|
*/
|
|
int Cpoint::Compare (const Attribute * arg ) const {
|
|
// first compare defined flags
|
|
if(!IsDefined()) {
|
|
return arg->IsDefined()?-1:0;
|
|
}
|
|
if(!arg->IsDefined()) {
|
|
return 1;
|
|
}
|
|
Cpoint* p = (Cpoint*) arg;
|
|
if (x < p->x) return -1;
|
|
if (x > p->x) return 1;
|
|
if (y < p->y) return -1;
|
|
if (y > p->y) return 1;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
Adjacent
|
|
*/
|
|
bool Cpoint::Adjacent ( const Attribute * arg) const {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
Sizeof Cpoint
|
|
*/
|
|
size_t Cpoint::Sizeof () const {
|
|
return sizeof(*this);
|
|
}
|
|
|
|
/*
|
|
HashValue
|
|
*/
|
|
size_t Cpoint::HashValue () const {
|
|
if(!IsDefined()) {
|
|
return 0;
|
|
}
|
|
return (size_t) (x+y);
|
|
}
|
|
|
|
/*
|
|
CopyFrom
|
|
*/
|
|
void Cpoint::CopyFrom ( const Attribute* arg ) {
|
|
if(!arg->IsDefined()) {
|
|
SetDefined(false);
|
|
return;
|
|
}
|
|
*this = (*(Cpoint*) arg);
|
|
SetDefined(true);
|
|
}
|
|
|
|
/*
|
|
Clone
|
|
*/
|
|
Attribute *Cpoint::Clone () const {
|
|
Cpoint* res = new Cpoint(x,y,z);
|
|
if(!this->IsDefined()) {
|
|
res->SetDefined(false);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/*
|
|
Getter / Setter and help functions
|
|
*/
|
|
double Cpoint::getX() const { return x; }
|
|
double Cpoint::getY() const { return y; }
|
|
double Cpoint::getZ() const { return z; }
|
|
|
|
/*
|
|
Begin Cpoints (DBArray of type Cpoint)
|
|
*/
|
|
|
|
/*
|
|
NumOfFlobs
|
|
*/
|
|
int Cpoints::NumOfFLOBs() const {
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
GetFlob
|
|
*/
|
|
Flob* Cpoints::GetFLOB ( const int i ) {
|
|
if (i == 0) {
|
|
return &cpoints;
|
|
}
|
|
return 0;
|
|
// assert(false);
|
|
}
|
|
|
|
/*
|
|
GetNoCpoints
|
|
*/
|
|
int Cpoints::GetNoCpoints() {
|
|
return (cpoints.Size());
|
|
}
|
|
|
|
/*
|
|
GetCpoint
|
|
*/
|
|
Cpoint Cpoints::GetCpoint(int i) {
|
|
Cpoint cpelem;
|
|
cpoints.Get(i, &cpelem);
|
|
return cpelem;
|
|
}
|
|
|
|
/*
|
|
AppendCpoints
|
|
*/
|
|
void Cpoints::AppendCpoint(const Cpoint &cpnt) {
|
|
cpoints.Append(cpnt);
|
|
}
|
|
|
|
/*
|
|
Destroy
|
|
*/
|
|
void Cpoints::DestroyCpoints() {
|
|
cpoints.Destroy();
|
|
}
|
|
|
|
/*
|
|
Compare
|
|
*/
|
|
int Cpoints::Compare (const Attribute * arg ) const {
|
|
// first compare defined flags
|
|
if(!IsDefined()) {
|
|
return arg->IsDefined()?-1:0;
|
|
}
|
|
if(!arg->IsDefined()) {
|
|
return 1;
|
|
}
|
|
// Cpoints* s = (Cpoints*) arg;
|
|
// TODO
|
|
// if (*this->Size() < s->Size()) return -1;
|
|
// if (*this->Size() > s->Size()) return 1;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
Adjacent
|
|
*/
|
|
bool Cpoints::Adjacent ( const Attribute * arg) const {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
Sizeof
|
|
*/
|
|
size_t Cpoints::Sizeof () const {
|
|
return sizeof(*this);
|
|
}
|
|
|
|
/*
|
|
HashValue
|
|
*/
|
|
size_t Cpoints::HashValue () const {
|
|
if(!IsDefined()) {
|
|
return 0;
|
|
}
|
|
double sumHash = 0.0;
|
|
Cpoint cpelem;
|
|
Cpoint* pcpelem;
|
|
for (int i = 0; i < cpoints.Size(); i++) {
|
|
cpoints.Get(i, cpelem);
|
|
pcpelem = &cpelem;
|
|
sumHash = sumHash +
|
|
(pcpelem)->getX() +
|
|
(pcpelem)->getY() +
|
|
(pcpelem)->getZ();
|
|
}
|
|
return (size_t) sumHash;
|
|
}
|
|
|
|
/*
|
|
CopyFrom
|
|
*/
|
|
void Cpoints::CopyFrom ( const Attribute* arg ) {
|
|
if(!arg->IsDefined()) {
|
|
SetDefined(false);
|
|
return;
|
|
}
|
|
*this = (*(Cpoints*) arg);
|
|
SetDefined(true);
|
|
}
|
|
|
|
/*
|
|
Clone
|
|
*/
|
|
Attribute *Cpoints::Clone () const {
|
|
Cpoints* res = new Cpoints(0);
|
|
res->SetDefined(true);
|
|
Cpoint cpelem;
|
|
if(!this->IsDefined()) {
|
|
res->SetDefined(false);
|
|
}
|
|
for (int i = 0; i < cpoints.Size(); i++) {
|
|
cpoints.Get(i, cpelem);
|
|
res->AppendCpoint(cpelem);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/*
|
|
Begin Cpointnode
|
|
*/
|
|
|
|
/*
|
|
Getter / Setter and help functions
|
|
*/
|
|
double Cpointnode::getX() const { return x; }
|
|
double Cpointnode::getY() const { return y; }
|
|
double Cpointnode::getZ() const { return z; }
|
|
int Cpointnode::getLeftSon() const { return leftson; }
|
|
int Cpointnode::getRightSon() const { return rightson; }
|
|
|
|
void Cpointnode::setLeftSon(int lSon) {
|
|
leftson = (lSon < 0) ? -1 : lSon;
|
|
}
|
|
|
|
void Cpointnode::setRightSon(int rSon) {
|
|
rightson = (rSon < 0) ? -1 : rSon;
|
|
}
|
|
|
|
/*
|
|
NumOfFlobs
|
|
*/
|
|
int Cpointnode::NumOfFLOBs() const {
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
GetFlob
|
|
*/
|
|
Flob* Cpointnode::GetFLOB ( const int i ) {
|
|
assert(false);
|
|
}
|
|
|
|
/*
|
|
Compare
|
|
*/
|
|
int Cpointnode::Compare (const Attribute * arg ) const {
|
|
// first compare defined flags
|
|
if(!IsDefined()) {
|
|
return arg->IsDefined()?-1:0;
|
|
}
|
|
if(!arg->IsDefined()) {
|
|
return 1;
|
|
}
|
|
Cpointnode* p = (Cpointnode*) arg;
|
|
if (x < p->x) return -1;
|
|
if (x > p->x) return 1;
|
|
if (y < p->y) return -1;
|
|
if (y > p->y) return 1;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
Adjacent
|
|
*/
|
|
bool Cpointnode::Adjacent ( const Attribute * arg) const {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
Sizeof
|
|
*/
|
|
size_t Cpointnode::Sizeof () const {
|
|
return sizeof(*this);
|
|
}
|
|
|
|
/*
|
|
HashValue
|
|
*/
|
|
size_t Cpointnode::HashValue () const {
|
|
if(!IsDefined()) {
|
|
return 0;
|
|
}
|
|
return (size_t) (x+y);
|
|
}
|
|
|
|
/*
|
|
CopyFrom
|
|
*/
|
|
void Cpointnode::CopyFrom ( const Attribute* arg ) {
|
|
if(!arg->IsDefined()) {
|
|
SetDefined(false);
|
|
return;
|
|
}
|
|
*this = (*(Cpointnode*) arg);
|
|
SetDefined(true);
|
|
}
|
|
|
|
/*
|
|
Clone
|
|
*/
|
|
Attribute *Cpointnode::Clone () const {
|
|
Cpointnode* res = new Cpointnode(x,y,z,leftson,rightson);
|
|
if(!this->IsDefined()) {
|
|
res->SetDefined(false);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
/*
|
|
Begin PointCloud
|
|
*/
|
|
|
|
/*
|
|
Getter / Setter and help functions
|
|
*/
|
|
double PointCloud::getMinX() const { return minX; }
|
|
double PointCloud::getMaxX() const { return maxX; }
|
|
double PointCloud::getMinY() const { return minY; }
|
|
double PointCloud::getMaxY() const { return maxY; }
|
|
|
|
void PointCloud::setMinX(const double minx) {
|
|
minX = minx;
|
|
}
|
|
|
|
void PointCloud::setMaxX(const double maxx) {
|
|
maxX = maxx;
|
|
}
|
|
|
|
void PointCloud::setMinY(const double miny) {
|
|
minY = miny;
|
|
}
|
|
|
|
void PointCloud::setMaxY(const double maxy) {
|
|
maxY = maxy;
|
|
}
|
|
|
|
/*
|
|
NumOfFlobs
|
|
*/
|
|
int PointCloud::NumOfFLOBs() const {
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
GetFlob
|
|
*/
|
|
Flob* PointCloud::GetFLOB ( const int i ) {
|
|
if (i == 0) {
|
|
return &cpoint2dtree;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
GetNoCpointnodes
|
|
*/
|
|
int PointCloud::GetNoCpointnodes() {
|
|
return (cpoint2dtree.Size());
|
|
}
|
|
|
|
/*
|
|
GetCpointnode
|
|
*/
|
|
Cpointnode PointCloud::GetCpointnode(int i) {
|
|
Cpointnode cpelem;
|
|
cpoint2dtree.Get(i, &cpelem);
|
|
return cpelem;
|
|
}
|
|
|
|
|
|
/*
|
|
AppendCpointnode
|
|
*/
|
|
/*
|
|
void PointCloud::AppendCpointnode(const Cpointnode &cpntnode) {
|
|
cpoint2dtree.Append(cpntnode);
|
|
double z = cpntnode.getZ();
|
|
if(z<minZ) minZ = z;
|
|
if(z>maxZ) maxZ = z;
|
|
}
|
|
*/
|
|
|
|
/*
|
|
DestroyPointCloud
|
|
*/
|
|
void PointCloud::DestroyPointCloud() {
|
|
cpoint2dtree.Destroy();
|
|
}
|
|
|
|
/*
|
|
Compare
|
|
*/
|
|
int PointCloud::Compare (const Attribute * arg ) const {
|
|
// first compare defined flags
|
|
if(!IsDefined()) {
|
|
return arg->IsDefined()?-1:0;
|
|
}
|
|
if(!arg->IsDefined()) {
|
|
return 1;
|
|
}
|
|
// TODO define criteria to be compared e.g. like below
|
|
// PointCloud* s = (PointCloud*) arg;
|
|
// if (point2dtree.Size() < s.Size()) return -1;
|
|
// if (point2dtree.Size() > s.Size()) return 1;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
Adjacent
|
|
*/
|
|
bool PointCloud::Adjacent ( const Attribute * arg) const {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
Sizeof
|
|
*/
|
|
size_t PointCloud::Sizeof () const {
|
|
return sizeof(*this);
|
|
}
|
|
|
|
/*
|
|
HashValue
|
|
*/
|
|
size_t PointCloud::HashValue () const {
|
|
if(!IsDefined()) {
|
|
return 0;
|
|
}
|
|
double sumHash = 0.0;
|
|
Cpointnode cpelem;
|
|
Cpointnode* pcpelem;
|
|
for (int i = 0; i < cpoint2dtree.Size(); i++) {
|
|
cpoint2dtree.Get(i, cpelem);
|
|
pcpelem = &cpelem;
|
|
sumHash = sumHash +
|
|
(pcpelem)->getX() +
|
|
(pcpelem)->getY() +
|
|
(pcpelem)->getZ();
|
|
}
|
|
return (size_t) sumHash;
|
|
}
|
|
|
|
/*
|
|
CopyFrom
|
|
*/
|
|
void PointCloud::CopyFrom ( const Attribute* arg ) {
|
|
if(!arg->IsDefined()) {
|
|
SetDefined(false);
|
|
return;
|
|
}
|
|
*this = (*(PointCloud*) arg);
|
|
SetDefined(true);
|
|
}
|
|
|
|
/*
|
|
Clone
|
|
*/
|
|
Attribute *PointCloud::Clone () const {
|
|
return new PointCloud(*this);
|
|
}
|
|
|
|
|
|
bool PointCloud::insert(const double x, const double y, const double z){
|
|
if(cpoint2dtree.Size()==0){
|
|
cpoint2dtree.Append(Cpointnode(x,y,z,-1,-1)); // first node
|
|
minZ = maxZ = z;
|
|
return true;
|
|
}
|
|
// correct z dimension
|
|
if(z<minZ) minZ = z;
|
|
if(z>maxZ) maxZ = z;
|
|
|
|
// search insertion position
|
|
int idx = 0;
|
|
Cpointnode node;
|
|
bool xdim = true;
|
|
cpoint2dtree.Get(idx,node);
|
|
bool done = false;
|
|
bool left;
|
|
do{
|
|
if(xdim){
|
|
left = x < node.getX();
|
|
} else {
|
|
left = y < node.getY();
|
|
}
|
|
int son = left?node.getLeftSon():node.getRightSon();
|
|
done = son==-1;
|
|
if(!done){
|
|
xdim = !xdim;
|
|
idx = son;
|
|
cpoint2dtree.Get(idx,node);
|
|
}
|
|
} while(!done);
|
|
|
|
int pos = cpoint2dtree.Size();
|
|
if(left){
|
|
node.setLeftSon(pos);
|
|
} else {
|
|
node.setRightSon(pos);
|
|
}
|
|
cpoint2dtree.Put(idx,node); // store corrected son
|
|
cpoint2dtree.Append(Cpointnode(x,y,z,-1,-1));
|
|
return true;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
std::ostream& operator<<(std::ostream& out,
|
|
const pointcloud::PointCloud& pc){
|
|
return pc.print(out);
|
|
}
|
|
|