/* //paragraph [1] Title: [{\Large \bf \begin{center}] [\end{center}}] //paragraph [10] Footnote: [{\footnote{] [}}] //[TOC] [\tableofcontents] //[NP] [\newpage] //[ue] [\"u] //[e] [\'e] ---- 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 ---- 01590 Fachpraktikum "Erweiterbare Datenbanksysteme" WS 2014 / 2015 Jens Breit, Joachim Dechow, Daniel Fuchs, Simon Jacobi, G[ue]nther Milosits, Daijun Nagamine, Hans-Joachim Klauke. Betreuer: Dr. Thomas Behr, Fabio Vald[e]s [1] Implementation of a Spatial3D algebra: createCube, createCylinder, createCone,createSphere [TOC] [NP] 1 Includes and Defines */ #include #include // std::min #include "Matrix4x4.h" #include "Spatial3D.h" #include "Spatial3DTransformations.h" #include "Algebras/Relation-C++/RelationAlgebra.h" extern NestedList* nl; extern QueryProcessor* qp; using namespace std; namespace spatial3DCreate { /* 1 Some auxiliary functions for the operators: 1.1 ~addRectangle~ Adds a rectangle to a volume. */ void addRectangle(const Point3d& a,const Point3d& b, const Point3d& c,const Point3d& d,Volume3d& res){ res.add(Triangle(a,b,c)); res.add(Triangle(a,c,d)); } /* 1.2 ~createCube~ Creates a cube. */ void createCube(Point3d* p1,Point3d* p2,Volume3d& res){ res.clear(); double xMin = min(p1->getX(),p2->getX()); double xMax = max(p1->getX(),p2->getX()); double yMin = min(p1->getY(),p2->getY()); double yMax = max(p1->getY(),p2->getY()); double zMin = min(p1->getZ(),p2->getZ()); double zMax = max(p1->getZ(),p2->getZ()); if(xMin == xMax || yMin == yMax || zMin == zMax){ res.SetDefined(false); return; } res.startBulkLoad(); addRectangle(Point3d(xMin,yMax,zMax),Point3d(xMin,yMin, zMax), Point3d(xMax,yMin,zMax),Point3d(xMax,yMax,zMax), res); addRectangle(Point3d(xMin,yMax,zMin),Point3d(xMax,yMax,zMin), Point3d(xMax,yMin,zMin),Point3d(xMin,yMin,zMin), res); addRectangle(Point3d(xMin,yMax,zMax),Point3d(xMin,yMax,zMin), Point3d(xMin,yMin,zMin),Point3d(xMin,yMin,zMax), res); addRectangle(Point3d(xMax,yMax,zMax),Point3d(xMax,yMin,zMax), Point3d(xMax,yMin,zMin),Point3d(xMax,yMax,zMin), res); addRectangle(Point3d(xMin,yMax,zMax),Point3d(xMax,yMax,zMax), Point3d(xMax,yMax,zMin),Point3d(xMin,yMax,zMin), res); addRectangle(Point3d(xMin,yMin,zMax),Point3d(xMin,yMin,zMin), Point3d(xMax,yMin,zMin),Point3d(xMax,yMin,zMax), res); res.endBulkLoad(NO_REPAIR); } /* 1.3 ~createCylinder~ Creates a cylinder. */ void createCylinder(Point3d* p1,double r, double h, int corners,Volume3d& res){ res.clear(); if(corners < 3){ res.SetDefined(false); return; } res.startBulkLoad(); double cx = p1->getX(); double cy = p1->getY(); double cz = p1->getZ(); for(int i = 0; i < corners; i++){ double x1 = cos(i * 2 * M_PI / corners) * r + cx; double y1 = sin(i * 2 * M_PI / corners) * r + cy; double x2 = cos((i+1) * 2 * M_PI / corners) * r + cx; double y2 = sin((i+1) * 2 * M_PI / corners) * r + cy; res.add(Triangle(Point3d(cx,cy,cz), Point3d(x2,y2,cz), Point3d(x1,y1,cz))); res.add(Triangle(Point3d(cx,cy,cz + h), Point3d(x1,y1,cz + h), Point3d(x2,y2,cz + h))); addRectangle(Point3d(x1,y1,cz), Point3d(x2,y2,cz), Point3d(x2,y2,cz + h), Point3d(x1,y1,cz + h), res); } res.endBulkLoad(NO_REPAIR); } /* 1.4 ~createCone~ Creates a cone. */ void createCone(Point3d* p1,double r, double h, int corners,Volume3d& res){ res.clear(); if(corners < 3){ res.SetDefined(false); return; } res.startBulkLoad(); double cx = p1->getX(); double cy = p1->getY(); double cz = p1->getZ(); for(int i = 0; i < corners; i++){ double x1 = cos(i * 2 * M_PI / corners) * r + cx; double y1 = sin(i * 2 * M_PI / corners) * r + cy; double x2 = cos((i+1) * 2 * M_PI / corners) * r + cx; double y2 = sin((i+1) * 2 * M_PI / corners) * r + cy; res.add(Triangle(Point3d(cx,cy,cz), Point3d(x2,y2,cz), Point3d(x1,y1,cz))); res.add(Triangle(Point3d(cx,cy,cz + h), Point3d(x1,y1,cz), Point3d(x2,y2,cz))); } res.endBulkLoad(NO_REPAIR); } /* 1.5 ~createSphere~ Creates a sphere. */ void createSphere(Point3d* p1,double r, int corners,Volume3d& res){ res.clear(); if(corners < 3){ res.SetDefined(false); return; } if(corners % 2 != 0){ corners++; } res.startBulkLoad(); double cx = p1->getX(); double cy = p1->getY(); double cz = p1->getZ() + r; for(int i = 1; i <= corners / 2 - 1; i++){ double y = cos(i * 2 * M_PI / corners) * r + cy; double r2 = sin(i * 2 * M_PI / corners) * r; for(int j = 1; j <= corners; j++){ double z = sin(j * 2 * M_PI / corners) * r2 + cz; double x = cos(j * 2 * M_PI / corners) * r2 + cx; double zPrev = sin((j - 1) * 2 * M_PI / corners) * r2 + cz; double xPrev = cos((j - 1) * 2 * M_PI / corners) * r2 + cx; if(i == 1){ res.add(Triangle(Point3d(cx,cy + r,cz), Point3d(x,y,z), Point3d(xPrev,y,zPrev))); } if(i > 1){ double yPrev = cos((i - 1) * 2 * M_PI / corners) * r + cy; double r2Prev = sin((i - 1) * 2 * M_PI / corners) * r; double zOld = sin(j * 2 * M_PI / corners) * r2Prev + cz; double xOld = cos(j * 2 * M_PI / corners) * r2Prev + cx; double zOldPrev = sin((j - 1) * 2 * M_PI / corners) * r2Prev + cz; double xOldPrev = cos((j - 1) * 2 * M_PI / corners) * r2Prev + cx; addRectangle(Point3d(x,y,z), Point3d(xPrev,y,zPrev), Point3d(xOldPrev,yPrev,zOldPrev), Point3d(xOld,yPrev,zOld), res); } if(i == corners / 2 - 1){ res.add(Triangle(Point3d(cx,cy - r,cz), Point3d(xPrev,y,zPrev), Point3d(x,y,z))); } } } res.endBulkLoad(NO_REPAIR); } /* 10 Operators Definition of operators is similar to definition of type constructors. An operator is defined by creating an instance of class ~Operator~. Again we have to define some functions before we are able to create an ~Operator~ instance. 10.1 Type mapping functions A type mapping function takes a nested list as argument. Its contents are type descriptions of an operator's input parameters. A nested list describing the output type of the operator is returned. 10.1.1 Type mapping function Spatial3DCreateCubeMap. This type mapping function is used for the ~creatCube~ operator. */ ListExpr Spatial3DCreateCubeMap( ListExpr args ) { if ( nl->ListLength( args ) != 2 ) { ErrorReporter::ReportError("wrong number of arguments (2 expected)"); return nl->TypeError(); } ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); if(nl->AtomType(arg1)!=SymbolType){ ErrorReporter::ReportError("point3D x point3d expected"); return nl->TypeError(); } string st = nl->SymbolValue(arg1); if( st!=Point3d::BasicType()){ ErrorReporter::ReportError("point3D x point3d expected"); return nl->TypeError(); } if(nl->AtomType(arg2)!=SymbolType){ ErrorReporter::ReportError("point3D x point3d expected"); return nl->TypeError(); } st = nl->SymbolValue(arg2); if( st!=Point3d::BasicType()){ ErrorReporter::ReportError("point3D x point3d expected"); return nl->TypeError(); } st = Volume3d::BasicType(); return nl->SymbolAtom(st); } /* 10.1.2 Type mapping function Spatial3DCreateCylinderOrConeMap This type mapping function is used for the ~createCylinder~ and ~createCone~ operators. */ ListExpr Spatial3DCreateCylinderOrConeMap( ListExpr args ) { if ( nl->ListLength( args ) != 4 ) { ErrorReporter::ReportError("wrong number of arguments (4 expected)"); return nl->TypeError(); } ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); ListExpr arg3 = nl->Third(args); ListExpr arg4 = nl->Fourth(args); if(nl->AtomType(arg1)!=SymbolType){ ErrorReporter::ReportError("point3D x real x real x int expected"); return nl->TypeError(); } string st = nl->SymbolValue(arg1); if( st!=Point3d::BasicType()){ ErrorReporter::ReportError("point3D x real x real x int expected"); return nl->TypeError(); } if(!nl->IsEqual(arg2,CcReal::BasicType())){ ErrorReporter::ReportError("point3D x real x real x int expected"); return nl->TypeError(); } if(!nl->IsEqual(arg3,CcReal::BasicType())){ ErrorReporter::ReportError("point3D x real x real x int expected"); return nl->TypeError(); } if(!nl->IsEqual(arg4,CcInt::BasicType())){ ErrorReporter::ReportError("point3D x real x real x int expected"); return nl->TypeError(); } st = Volume3d::BasicType(); return nl->SymbolAtom(st); } /* 10.1.3 Type mapping function Spatial3DCreateSphereMap This type mapping function is used for the ~createSphere~ operator. */ ListExpr Spatial3DCreateSphereMap( ListExpr args ) { if ( nl->ListLength( args ) != 3 ) { ErrorReporter::ReportError("wrong number of arguments (3 expected)"); return nl->TypeError(); } ListExpr arg1 = nl->First(args); ListExpr arg2 = nl->Second(args); ListExpr arg3 = nl->Third(args); if(nl->AtomType(arg1)!=SymbolType){ ErrorReporter::ReportError("point3D x real x int expected"); return nl->TypeError(); } string st = nl->SymbolValue(arg1); if( st!=Point3d::BasicType()){ ErrorReporter::ReportError("point3D x real x int expected"); return nl->TypeError(); } if(!nl->IsEqual(arg2,CcReal::BasicType())){ ErrorReporter::ReportError("point3D x real x int expected"); return nl->TypeError(); } if(!nl->IsEqual(arg3,CcInt::BasicType())){ ErrorReporter::ReportError("point3D x real x int expected"); return nl->TypeError(); } st = Volume3d::BasicType(); return nl->SymbolAtom(st); } /* 10.4 Value mapping functions 10.4.1 Value mapping functions of operator ~createCube~ */ int Spatial3DCreateCube( Word* args, Word& result, int message, Word& local, Supplier s ){ result = qp->ResultStorage(s); Volume3d* res = static_cast(result.addr); Point3d* p1 = static_cast(args[0].addr); Point3d* p2 = static_cast(args[1].addr); if(!p1->IsDefined() || !p2->IsDefined()){ res->SetDefined(false); return 0; } createCube(p1,p2,*res); return 0; } int Spatial3DCreateCylinder( Word* args, Word& result, int message, Word& local, Supplier s ){ result = qp->ResultStorage(s); Volume3d* res = static_cast(result.addr); Point3d* p = static_cast(args[0].addr); CcReal* cr = static_cast(args[1].addr); CcReal* ch = static_cast(args[2].addr); CcInt* cc = static_cast(args[3].addr); if(!p->IsDefined() || !cr->IsDefined() || !ch->IsDefined() || !cc->IsDefined() ){ res->SetDefined(false); return 0; } double r = cr->GetRealval(); double h = ch->GetRealval(); int c = cc->GetIntval(); createCylinder(p,r,h,c,*res); return 0; } int Spatial3DCreateCone( Word* args, Word& result, int message, Word& local, Supplier s ){ result = qp->ResultStorage(s); Volume3d* res = static_cast(result.addr); Point3d* p = static_cast(args[0].addr); CcReal* cr = static_cast(args[1].addr); CcReal* ch = static_cast(args[2].addr); CcInt* cc = static_cast(args[3].addr); if(!p->IsDefined() || !cr->IsDefined() || !ch->IsDefined() || !cc->IsDefined() ){ res->SetDefined(false); return 0; } double r = cr->GetRealval(); double h = ch->GetRealval(); int c = cc->GetIntval(); createCone(p,r,h,c,*res); return 0; } int Spatial3DCreateSphere( Word* args, Word& result, int message, Word& local, Supplier s ){ result = qp->ResultStorage(s); Volume3d* res = static_cast(result.addr); Point3d* p = static_cast(args[0].addr); CcReal* cr = static_cast(args[1].addr); CcInt* cc = static_cast(args[2].addr); if(!p->IsDefined() || !cr->IsDefined()|| !cc->IsDefined()){ res->SetDefined(false); return 0; } double r = cr->GetRealval(); int c = cc->GetIntval(); createSphere(p,r,c,*res); return 0; } /* 10.5 Definition of operators Definition of operators is done in a way similar to definition of type constructors: an instance of class ~Operator~ is defined. 10.5.2 Definition of specification strings */ const string Spatial3DSpecCreateCube = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( (point3D x point3D) -> volume3d" " createCube(p1,p2)" " creates a cube with he corner p1 and p2" " query createCube(point1,point2]" ") )"; const string Spatial3DSpecCreateCylinder = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( point3D x real x real x int) -> volume3d" " createCylinder(p,r,h,c)" " creates a cylinder with radius r and hight h" " query createCylinder(point, radius, height, corner)" ") )"; const string Spatial3DSpecCreateCone = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( point3D x real x real x int) -> volume3d" " createCone(p,r,h,c)" " creates a cone with radius r and hight h" " query createCone(point, radius, height, corner)" ") )"; const string Spatial3DSpecCreateSphere = "( ( \"Signature\" \"Syntax\" \"Meaning\" \"Example\" ) " "( point3D x real x int) -> volume3d" " createSphere(p,r,h,c)" " creates a sphere with radius r" " query createCone(point, radius, corner)" ") )"; /* 10.5.3 Definition of the operators */ Operator* getCreateCubePtr(){ return new Operator( "createCube", Spatial3DSpecCreateCube, Spatial3DCreateCube, Operator::SimpleSelect, Spatial3DCreateCubeMap ); } Operator* getCreateCylinderPtr(){ return new Operator( "createCylinder", Spatial3DSpecCreateCylinder, Spatial3DCreateCylinder, Operator::SimpleSelect, Spatial3DCreateCylinderOrConeMap ); } Operator* getCreateConePtr(){ return new Operator( "createCone", Spatial3DSpecCreateCone, Spatial3DCreateCone, Operator::SimpleSelect, Spatial3DCreateCylinderOrConeMap ); } Operator* getCreateSpherePtr(){ return new Operator( "createSphere", Spatial3DSpecCreateSphere, Spatial3DCreateSphere, Operator::SimpleSelect, Spatial3DCreateSphereMap ); } }