2966 lines
71 KiB
C++
2966 lines
71 KiB
C++
/*
|
|
----
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2009, University in Hagen, 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
|
|
----
|
|
|
|
//paragraph [1] Title: [{\Large \bf \begin{center}] [\end{center}}]
|
|
//paragraph [10] Footnote: [{\footnote{] [}}]
|
|
//[TOC] [\tableofcontents]
|
|
//[->] [$\rightarrow$]
|
|
|
|
[TOC]
|
|
|
|
0 Overview
|
|
|
|
1 Includes and defines
|
|
|
|
*/
|
|
#ifndef PRECISE2DALGEBRA_CPP_
|
|
#define PRECISE2DALGEBRA_CPP_
|
|
|
|
#include "Precise2DAlgebra.h"
|
|
#include "StringUtils.h"
|
|
|
|
//includes for the Gnu Multiple Precision (GMP) library
|
|
#include <stdio.h>
|
|
#include <gmp.h>
|
|
#include <gmpxx.h>
|
|
|
|
#include "Algebra.h"
|
|
#include "Tools/Flob/DbArray.h"
|
|
#include "Tools/Flob/Flob.h"
|
|
#include "NestedList.h"
|
|
#include "ListUtils.h"
|
|
#include "QueryProcessor.h"
|
|
#include "StandardTypes.h"
|
|
#include "Algebras/Spatial/AttrType.h"
|
|
#include "Algebras/FText/FTextAlgebra.h"
|
|
#include "Algebras/Spatial/SpatialAlgebra.h"
|
|
#include "Coarsening.h"
|
|
#include "AVL_Tree.h"
|
|
#include "TestAVLTree.h"
|
|
|
|
|
|
extern NestedList* nl;
|
|
extern QueryProcessor* qp;
|
|
|
|
using namespace std;
|
|
|
|
namespace p2d {
|
|
|
|
/*
|
|
1 ~textTypeToGmpType()~
|
|
|
|
Reads from inList and stores its representation as mpq\_class in outValue.
|
|
|
|
This function was first implemented by Stefanie Renner in the
|
|
MovingObjects2Algebra and is now adapted for negative values.
|
|
Additionally there are now some more limitations for valid numbers.
|
|
|
|
*/
|
|
bool textTypeToGmpType(const ListExpr& inList, mpq_class& preciseValue,
|
|
bool negValueAllowed) {
|
|
|
|
TextScan theScan = nl->CreateTextScan(inList);
|
|
stringstream theStream;
|
|
int noSlash = 0;
|
|
|
|
char lastChar = '*'; //just a random initialization...
|
|
for (unsigned int i = 0; i < nl->TextLength(inList); i++) {
|
|
string str = "";
|
|
nl->GetText(theScan, 1, str);
|
|
|
|
if ((int) str[0] == 47){
|
|
noSlash++;
|
|
}
|
|
|
|
//Checking for valid character
|
|
if (!(i == 0 && (int) str[0] == 240)) {
|
|
if ((int) str[0] < 45 || (int) str[0] == 46 || (int) str[0] > 57
|
|
|| (i == 0 && (int) str[0] == 48 && nl->TextLength(inList) > 1)
|
|
|| (i == 0 && (int) str[0] == 47)
|
|
|| (lastChar == '/' && (int) str[0] == 48)
|
|
|| (noSlash>1)
|
|
|| (((int) str[0] == 45) && (!negValueAllowed))
|
|
|| ((int) str[0] == 45 && negValueAllowed && (!((lastChar == '/')
|
|
||(i==0))))
|
|
|| ((lastChar == '-') && ((int) str[0] == 47))) {
|
|
stringstream message;
|
|
message << "Precise coordinate not valid: " << nl->ToString(inList) << endl
|
|
<< "Only characters 1, 2, 3, 4, 5, "
|
|
"6, 7, 8, 9, 0 and / allowed." << endl << "0 mustn't be leading "
|
|
"character when "
|
|
"more than one character "
|
|
"in total are given" << endl << ", and 0 is "
|
|
"not allowed directly after /";
|
|
//throw invalid_argument(message.str());
|
|
cerr << message.str()<<endl;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
theStream.put(str[0]);
|
|
lastChar = str[0];
|
|
}
|
|
|
|
theStream >> preciseValue;
|
|
|
|
preciseValue.canonicalize();
|
|
//Checking the value - must be between 0 and 1
|
|
if (preciseValue >= 1 || (preciseValue < 0 && (!negValueAllowed))) {
|
|
stringstream message;
|
|
message << "Precise coordinate not valid: " << nl->ToString(inList) << endl
|
|
<< "Resulting value "
|
|
"is not between 0 and 1, "
|
|
"where 0 is allowed, but 1 is not.";
|
|
//throw invalid_argument(message.str());
|
|
cerr << message.str() << endl;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
1 ~gmpTypeToTextType()~
|
|
|
|
Reads from ~value~ and stores its representation as TextType in ~resultList~.
|
|
|
|
*/
|
|
void gmpTypeToTextType(const mpq_class& value, ListExpr& resultList) {
|
|
string str = value.get_str();
|
|
resultList = nl->TextAtom(str);
|
|
}
|
|
|
|
/*
|
|
1 ~internalValueToOutputValue~
|
|
|
|
A negative value is internally stored with a grid value and a precise value
|
|
like the positive values. But the internal representation has to be changed
|
|
from the real value for correct computations with positive and negative values:
|
|
P.e. if we have a real value -4.3, the internal representation will be
|
|
-5 for the grid value and 7/10 for the precise value. Before the real value
|
|
is printed, he has to be computed from the internal value.
|
|
|
|
*/
|
|
void internalValueToOutputValue(int& gValue, mpq_class& pValue){
|
|
|
|
if ((gValue < 0) && ((cmp(pValue, 0 ) != 0))){
|
|
pValue = 1 - pValue ;
|
|
gValue++;
|
|
|
|
if (gValue==0){
|
|
pValue = pValue * (-1);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
1 ~outputValueToInternalValue~
|
|
|
|
The real value ~gValue~ + ~pValue~ is already split into two parts.
|
|
If the real value is smaller 0, the internal value must be adjusted.
|
|
If the real value is p. e. -1 1/3, the internal value is gValue=-2 and
|
|
pValue=2/3.
|
|
|
|
*/
|
|
void outputValueToInternalValue(int& gValue, mpq_class& pValue){
|
|
|
|
if ((gValue < 0) && (cmp(pValue, 0) != 0)){
|
|
pValue = 1 - pValue ;
|
|
gValue--;
|
|
|
|
if (gValue==0){
|
|
pValue = pValue * (-1);
|
|
}
|
|
}
|
|
if ((gValue == 0) && (cmp(pValue, 0) < 0)){
|
|
gValue--;
|
|
pValue = pValue + 1;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
1 List Representation of pointp
|
|
|
|
The list representation of a pointp is
|
|
|
|
---- (x y (preciseX preciseY))
|
|
where x and y are the values of the grid-point and
|
|
preciseX is the difference between x and the x-coordinate
|
|
of the real point (preciseY analog). x and y are integers,
|
|
preciseX and preciseY are of type text
|
|
|
|
or
|
|
undefined
|
|
----
|
|
|
|
2.1 ~OutPoint2~-function
|
|
|
|
*/
|
|
ListExpr Point2::OutPoint2(ListExpr typeInfo, Word value) {
|
|
Point2* point = (Point2*) (value.addr);
|
|
|
|
if (point->IsDefined()) {
|
|
int gX = point->getGridX();
|
|
int gY = point->getGridY();
|
|
mpq_class pX = point->getPreciseX();
|
|
mpq_class pY = point->getPreciseY();
|
|
internalValueToOutputValue(gX, pX);
|
|
internalValueToOutputValue(gY, pY);
|
|
ListExpr preciseX, preciseY;
|
|
gmpTypeToTextType(pX, preciseX);
|
|
gmpTypeToTextType(pY, preciseY);
|
|
return nl->ThreeElemList(nl->IntAtom(gX),
|
|
nl->IntAtom(gY), nl->TwoElemList(preciseX, preciseY));
|
|
} else {
|
|
return nl->SymbolAtom(Symbol::UNDEFINED());
|
|
}
|
|
}
|
|
|
|
/*
|
|
2.1 ~InPoint2~-function
|
|
|
|
*/
|
|
Word Point2::InPoint2(const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct) {
|
|
correct = true;
|
|
string message = "";
|
|
if (nl->ListLength(instance)==2){
|
|
ListExpr first = nl->First(instance);
|
|
ListExpr second = nl->Second(instance);
|
|
if (nl->IsAtom(first) && nl->IsAtom(second)){
|
|
mpq_class preciseX, preciseY;
|
|
int x, y;
|
|
bool firstIsCorrect = true;
|
|
bool secondIsCorrect = true;
|
|
firstIsCorrect = createCoordinate(first, x, preciseX);
|
|
secondIsCorrect = createCoordinate(second, y, preciseY);
|
|
if (firstIsCorrect && secondIsCorrect){
|
|
Point2* p = new Point2(true, x, y, preciseX, preciseY);
|
|
return SetWord(p);
|
|
}
|
|
}
|
|
}
|
|
if (nl->ListLength(instance) == 3) {
|
|
ListExpr first = nl->First(instance);
|
|
ListExpr second = nl->Second(instance);
|
|
ListExpr third = nl->Third(instance);
|
|
|
|
if (nl->IsAtom(first) && nl->AtomType(first) == IntType && nl->IsAtom(second)
|
|
&& nl->AtomType(second) == IntType) {
|
|
if (nl->ListLength(third) == 2) {
|
|
ListExpr fourth = nl->First(third);
|
|
ListExpr fifth = nl->Second(third);
|
|
if (nl->IsAtom(fourth) && nl->AtomType(fourth) == TextType
|
|
&& nl->IsAtom(fifth) && nl->AtomType(fifth) == TextType) {
|
|
int gX, gY;
|
|
mpq_class pX, pY;
|
|
gX = nl->IntValue(first);
|
|
gY = nl->IntValue(second);
|
|
if (
|
|
textTypeToGmpType(fourth, pX, gX==0) &&
|
|
textTypeToGmpType(fifth, pY, gY==0)){
|
|
outputValueToInternalValue(gX, pX);
|
|
outputValueToInternalValue(gY, pY);
|
|
Point2* p = new Point2(true, gX, gY, pX, pY);
|
|
return SetWord(p);
|
|
} else {
|
|
cerr << "The false value: "<<endl;
|
|
cerr << nl->ToString(instance)<<endl;
|
|
cerr << "is not suitable for the gmp-Type."<< endl;
|
|
correct = false;
|
|
return SetWord(Address(0));
|
|
}
|
|
} else {
|
|
message = "The third and fourth argument "
|
|
"have to be of type TextType";
|
|
}
|
|
} else {
|
|
message = "There has to be only "
|
|
"2 arguments in the list "
|
|
"with the precise data";
|
|
}
|
|
} else {
|
|
message = "The first and the second "
|
|
"argument have to be of type int.";
|
|
}
|
|
} else {
|
|
if (nl->ListLength(instance)<2){
|
|
message = stringutils::int2str(nl->ListLength(instance)) + "are not enough "
|
|
"arguments.";
|
|
} else {
|
|
message = "There are too many arguments.";
|
|
}
|
|
if (listutils::isSymbolUndefined(instance)) {
|
|
return SetWord(new Point2(false));
|
|
}
|
|
}
|
|
cerr << "The false value: "<<endl;
|
|
cerr << nl->ToString(instance)<<endl;
|
|
cerr << message << endl;
|
|
correct = false;
|
|
return SetWord(Address(0));
|
|
}
|
|
|
|
/*
|
|
2 List Representation of linep
|
|
|
|
The list representation of a linep is
|
|
|
|
---- $(segm_1 segm_2 ... segm_n)$, where
|
|
|
|
$segm_i$ = ((xl yl (preciseXl preciseYl))(xr yr (preciseXr preciseYr)))
|
|
for all i $\in \{1,...,n\}$.
|
|
x and y are the values of the grid-point and
|
|
preciseX is the difference between x and the x-coordinate
|
|
of the real point (preciseY analog). x and y are integers,
|
|
preciseX and preciseY are of type text
|
|
|
|
or
|
|
undefined
|
|
----
|
|
|
|
2.2 ~OutLine2~-function
|
|
|
|
*/
|
|
ListExpr Line2::OutLine2(ListExpr typeInfo, Word value) {
|
|
Line2* line = (Line2*) (value.addr);
|
|
|
|
if (!line->IsDefined()) {
|
|
return nl->SymbolAtom(Symbol::UNDEFINED());
|
|
}
|
|
ListExpr segment, result=nl->TheEmptyList(), last=nl->TheEmptyList();
|
|
|
|
result = nl->TheEmptyList();
|
|
|
|
int gLeftX, gLeftY, gRightX, gRightY;
|
|
mpq_class pLeftX, pLeftY, pRightX, pRightY;
|
|
ListExpr preciseLeftX, preciseLeftY, preciseRightX, preciseRightY;
|
|
|
|
bool firstSegment = true;
|
|
const int sz = line->Size();
|
|
|
|
for (int i = 0; i < sz; i++) {
|
|
if (line->IsLeftDomPoint(i)) {
|
|
// read data of segment no ~i~
|
|
gLeftX = line->getLeftGridX(i);
|
|
gLeftY = line->getLeftGridY(i);
|
|
gRightX = line->getRightGridX(i);
|
|
gRightY = line->getRightGridY(i);
|
|
pLeftX = line->getPreciseLeftX(i);
|
|
pLeftY = line->getPreciseLeftY(i);
|
|
pRightX = line->getPreciseRightX(i);
|
|
pRightY = line->getPreciseRightY(i);
|
|
internalValueToOutputValue(gLeftX, pLeftX);
|
|
internalValueToOutputValue(gLeftY, pLeftY);
|
|
internalValueToOutputValue(gRightX, pRightX);
|
|
internalValueToOutputValue(gRightY, pRightY);
|
|
gmpTypeToTextType(pLeftX, preciseLeftX);
|
|
gmpTypeToTextType(pLeftY, preciseLeftY);
|
|
gmpTypeToTextType(pRightX, preciseRightX);
|
|
gmpTypeToTextType(pRightY, preciseRightY);
|
|
// create ListExpr
|
|
segment = nl->TwoElemList(
|
|
nl->ThreeElemList(nl->IntAtom(gLeftX), nl->IntAtom(gLeftY),
|
|
nl->TwoElemList(preciseLeftX, preciseLeftY)),
|
|
nl->ThreeElemList(nl->IntAtom(gRightX), nl->IntAtom(gRightY),
|
|
nl->TwoElemList(preciseRightX, preciseRightY)));
|
|
// add ~segment~ to ~result~
|
|
if (firstSegment) {
|
|
last = nl->OneElemList(segment);
|
|
result = last;
|
|
firstSegment = false;
|
|
} else {
|
|
last = nl->Append(last, segment);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
2.2 ~InLine2~-function
|
|
|
|
*/
|
|
Word Line2::InLine2(const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct) {
|
|
correct = true;
|
|
|
|
if (listutils::isSymbolUndefined(instance)) {
|
|
return SetWord(new Line2(false));
|
|
}
|
|
Line2* line = new Line2(true);
|
|
line->StartBulkLoad();
|
|
ListExpr rest = instance;
|
|
ListExpr segment, leftPoint, rightPoint;
|
|
int edgeno = 0;
|
|
Point2* lp = new Point2(false);
|
|
Point2* rp = new Point2(false);
|
|
while (!nl->IsEmpty(rest)) {
|
|
correct = true;
|
|
segment = nl->First(rest);
|
|
rest = nl->Rest(rest);
|
|
if (nl->ListLength(segment) == 4) {
|
|
ListExpr first = nl->First(segment);
|
|
ListExpr second = nl->Second(segment);
|
|
ListExpr third = nl->Third(segment);
|
|
ListExpr fourth = nl->Fourth(segment);
|
|
if (nl->IsAtom(first) && nl->IsAtom(second)
|
|
&& nl->IsAtom(third) && nl->IsAtom(fourth)){
|
|
mpq_class preciseLX, preciseLY, preciseRX, preciseRY;
|
|
int lx, ly, rx, ry;
|
|
bool firstIsCorrect = true;
|
|
bool secondIsCorrect = true;
|
|
bool thirdIsCorrect = true;
|
|
bool fourthIsCorrect = true;
|
|
firstIsCorrect = createCoordinate(first, lx, preciseLX);
|
|
secondIsCorrect = createCoordinate(second, ly, preciseLY);
|
|
thirdIsCorrect = createCoordinate(third, rx, preciseRX);
|
|
fourthIsCorrect = createCoordinate(fourth, ry, preciseRY);
|
|
if (firstIsCorrect && secondIsCorrect && thirdIsCorrect && fourthIsCorrect){
|
|
Point2* lp = new Point2(true, lx, ly, preciseLX, preciseLY);
|
|
Point2* rp = new Point2(true, rx, ry, preciseRX, preciseRY);
|
|
|
|
if (*lp == *rp) {
|
|
correct = false;
|
|
cerr << nl->ToString(segment) << " contains an error." << endl
|
|
<< "One segment consists of "
|
|
"2 different points. " << endl;
|
|
line->DeleteIfAllowed();
|
|
delete lp;
|
|
delete rp;
|
|
return SetWord(Address(0));
|
|
} else {
|
|
if (*lp < *rp) {
|
|
line->addSegment(true, lp, rp, edgeno);
|
|
line->addSegment(false, lp, rp, edgeno);
|
|
} else {
|
|
line->addSegment(true, rp, lp, edgeno);
|
|
line->addSegment(false, rp, lp, edgeno);
|
|
}
|
|
edgeno++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (nl->ListLength(segment) == 2) {
|
|
leftPoint = nl->First(segment);
|
|
Word lpWord = Point2::InPoint2(typeInfo, leftPoint, errorPos, errorInfo,
|
|
correct);
|
|
lp = (Point2*) (lpWord.addr);
|
|
if (correct) {
|
|
rightPoint = nl->Second(segment);
|
|
Word rpWord = Point2::InPoint2(typeInfo, rightPoint, errorPos, errorInfo,
|
|
correct);
|
|
rp = (Point2*) (rpWord.addr);
|
|
}
|
|
if (correct) {
|
|
if (*lp == *rp) {
|
|
|
|
correct = false;
|
|
cerr << nl->ToString(segment) << " contains an error." << endl
|
|
<< "One segment consists of "
|
|
"2 different points. " << endl;
|
|
line->DeleteIfAllowed();
|
|
delete lp;
|
|
delete rp;
|
|
return SetWord(Address(0));
|
|
} else {
|
|
if (*lp < *rp) {
|
|
line->addSegment(true, lp, rp, edgeno);
|
|
line->addSegment(false, lp, rp, edgeno);
|
|
} else {
|
|
line->addSegment(true, rp, lp, edgeno);
|
|
line->addSegment(false, rp, lp, edgeno);
|
|
}
|
|
edgeno++;
|
|
}
|
|
} else {
|
|
cerr << nl->ToString(segment) << " contains an error." << endl;
|
|
line->DeleteIfAllowed();
|
|
delete lp;
|
|
delete rp;
|
|
return SetWord(Address(0));
|
|
}
|
|
}
|
|
if (!((nl->ListLength(segment) == 2) || (nl->ListLength(segment) == 4))){
|
|
cerr << nl->ToString(segment) << " has a false list length. "
|
|
<< "One segment consists of 2 points or 4 numbers." << endl;
|
|
line->DeleteIfAllowed();
|
|
return SetWord(Address(0));
|
|
}
|
|
|
|
}
|
|
line->EndBulkLoad(true, true, true);
|
|
delete lp;
|
|
delete rp;
|
|
return SetWord(line);
|
|
}
|
|
|
|
/*
|
|
2 List Representation of points2
|
|
|
|
The list representation of a points2-object is
|
|
|
|
---- ($point_1$ $point_2$ ... $point_n$), where
|
|
|
|
$point_i$ = (x y (preciseX preciseY))
|
|
for all i $\in$ $\{1,...,n\}$.
|
|
x and y are the values of the grid-point and
|
|
preciseX is the difference between x and the x-coordinate
|
|
of the real point (preciseY analogous). x and y are integers,
|
|
preciseX and preciseY are of type text
|
|
|
|
or
|
|
undefined
|
|
----
|
|
|
|
2.3 ~OutPoints2~-function
|
|
|
|
*/
|
|
ListExpr Points2::OutPoints2(ListExpr typeInfo, Word value) {
|
|
Points2* points = (Points2*) (value.addr);
|
|
|
|
if (!points->IsDefined()) {
|
|
return nl->SymbolAtom(Symbol::UNDEFINED());
|
|
}
|
|
|
|
ListExpr point, result=nl->TheEmptyList(), last=nl->TheEmptyList();
|
|
result = nl->TheEmptyList();
|
|
int gX, gY;
|
|
mpq_class pX, pY;
|
|
ListExpr preciseX, preciseY;
|
|
bool firstPoint = true;
|
|
const int sz = points->Size();
|
|
for (int i = 0; i < sz; i++) {
|
|
// Daten von point i lesen
|
|
gX = points->getGridX(i);
|
|
gY = points->getGridY(i);
|
|
pX = points->getPreciseX(i);
|
|
pY = points->getPreciseY(i);
|
|
|
|
internalValueToOutputValue(gX, pX);
|
|
internalValueToOutputValue(gY, pY);
|
|
//preciseX = nl->TextAtom();
|
|
//nl->AppendText(preciseX, points->getPreciseXAsString(i));
|
|
//preciseY = nl->TextAtom();
|
|
//nl->AppendText(preciseY, points->getPreciseYAsString(i));
|
|
gmpTypeToTextType(pX, preciseX);
|
|
gmpTypeToTextType(pY, preciseY);
|
|
// ListExpr point erstellen
|
|
point = nl->ThreeElemList(nl->IntAtom(gX), nl->IntAtom(gY),
|
|
nl->TwoElemList(preciseX, preciseY));
|
|
// point an result anhaengen
|
|
if (firstPoint) {
|
|
last = nl->OneElemList(point);
|
|
result = last;
|
|
firstPoint = false;
|
|
} else {
|
|
last = nl->Append(last, point);
|
|
}
|
|
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
2.3 ~InPoints2~-function
|
|
|
|
*/
|
|
Word Points2::InPoints2(const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct) {
|
|
correct = true;
|
|
|
|
if (listutils::isSymbolUndefined(instance)) {
|
|
return SetWord(new Points2(false));
|
|
}
|
|
Points2* points = new Points2(true);
|
|
points->StartBulkLoad();
|
|
ListExpr rest = instance;
|
|
ListExpr point;
|
|
Point2* p = new Point2(false);
|
|
while (!nl->IsEmpty(rest)) {
|
|
correct = true;
|
|
point = nl->First(rest);
|
|
rest = nl->Rest(rest);
|
|
Word pointWord = Point2::InPoint2(typeInfo, point, errorPos, errorInfo,
|
|
correct);
|
|
p = (Point2*) (pointWord.addr);
|
|
|
|
if (correct) {
|
|
points->addPoint(p);
|
|
} else {
|
|
points->DeleteIfAllowed();
|
|
delete p;
|
|
return SetWord(Address(0));
|
|
}
|
|
}
|
|
points->EndBulkLoad(true, true, true);
|
|
delete p;
|
|
return SetWord(points);
|
|
}
|
|
|
|
/*
|
|
1 ~$<<$~
|
|
|
|
*/
|
|
|
|
/*
|
|
1.1 for Point2
|
|
|
|
*/
|
|
ostream& operator<<(ostream& o, const Point2& p) {
|
|
if (p.IsDefined())
|
|
o << "(" << p.getGridX() << ", " << p.getGridY() << " (" << p.getPreciseX()
|
|
<< ", " << p.getPreciseY() << "))";
|
|
else
|
|
o << Symbol::UNDEFINED();
|
|
return o;
|
|
}
|
|
|
|
/*
|
|
1.1 for Points2
|
|
|
|
*/
|
|
ostream& operator<<(ostream& o, const Points2& p) {
|
|
if (p.IsDefined()) {
|
|
o << "(";
|
|
int index = 0;
|
|
while (index < p.Size()) {
|
|
o << "(" << p.getGridX(index) << ", " << p.getGridY(index) << " ("
|
|
<< p.getPreciseX(index) << ", " << p.getPreciseY(index) << ")) ";
|
|
}
|
|
o << ")";
|
|
} else
|
|
o << Symbol::UNDEFINED();
|
|
return o;
|
|
}
|
|
|
|
/*
|
|
1.1 for Line2
|
|
|
|
*/
|
|
ostream& operator<<(ostream& o, const Line2& l) {
|
|
if (l.IsDefined()) {
|
|
o << "(";
|
|
int index = 0;
|
|
while (index < l.Size()) {
|
|
o << "((" << l.getLeftGridX(index) << ", " << l.getLeftGridY(index) << " ("
|
|
<< l.getPreciseLeftX(index) << ", " << l.getPreciseLeftY(index) << ")) ("
|
|
<< l.getRightGridX(index) << ", " << l.getRightGridY(index) << " ("
|
|
<< l.getPreciseRightX(index) << ", " << l.getPreciseRightY(index) << ")))";
|
|
}
|
|
o << ")";
|
|
} else
|
|
o << Symbol::UNDEFINED();
|
|
return o;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
1 Value-mapping-functions
|
|
|
|
*/
|
|
|
|
/*
|
|
1.1 ~union\_LLL~
|
|
|
|
~linep~ x ~linep~ [->] ~linep~
|
|
|
|
~result~ contains all segments of both ~linep~-objects. If there are
|
|
overlapping segments, ~result~ will contain only one of them.
|
|
|
|
If one of the ~linep~-objects is not defined, ~result~ will be undefined too.
|
|
|
|
*/
|
|
int union_LLL(Word* args, Word& result, int message, Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
Line2* res = static_cast<Line2*>(result.addr);
|
|
l1->unionOP(*l2, *res);
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
1.1 ~intersection\_LLL~
|
|
|
|
~linep~ x ~linep~ [->] ~linep~
|
|
|
|
~result~ contains all overlapping segments of both ~linep~-objects.
|
|
If one of the ~linep~-objects is not defined, ~result~ will be undefined too.
|
|
|
|
*/
|
|
int intersection_LLL(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
Line2* res = static_cast<Line2*>(result.addr);
|
|
l1->intersection(*l2, *res);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~minus\_LLL~
|
|
|
|
~linep~ x ~linep~ [->] ~linep~
|
|
|
|
~result~ contains all segments of the first argument, unless
|
|
they are part of the second argument
|
|
If one of the ~linep~-objects is not defined, ~result~ will be undefined too.
|
|
|
|
*/
|
|
int minus_LLL(Word* args, Word& result, int message, Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
Line2* res = static_cast<Line2*>(result.addr);
|
|
l1->minus(*l2, *res);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~intersects\_LLB~
|
|
|
|
~linep~ x ~linep~ [->] ~bool~
|
|
|
|
~result~ is true, if 2 segments of both arguments intersect, false otherwise.
|
|
|
|
*/
|
|
int intersects_LLB(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
bool defined = (l1->IsDefined() && l2->IsDefined());
|
|
bool res = l1->intersects(*l2);
|
|
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1 ~crossings\_LLP~
|
|
|
|
~linep~ x ~linep~ [->] ~points2~
|
|
|
|
~result~ contains all intersection points of the first and the second argument.
|
|
Overlapping parts are not considered.
|
|
|
|
*/
|
|
int crossings_LLP(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
Points2* res = static_cast<Points2*>(result.addr);
|
|
l1->crossings(*l2, *res);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~unionWithScaling\_LLL~
|
|
|
|
~linep~ x ~linep~ [->] ~linep~
|
|
|
|
~result~ contains all segments of both ~linep~-objects. If there are
|
|
overlapping segments, ~result~ will contain only one of them.
|
|
|
|
If one of the ~linep~-objects is not defined, ~result~ will be undefined too.
|
|
|
|
*/
|
|
int unionWithScaling_LLL(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
Line2* res = static_cast<Line2*>(result.addr);
|
|
l1->unionWithScaling(*l2, *res);
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
/*
|
|
1.1 ~intersectionWithScaling\_LLL~
|
|
|
|
~linep~ x ~linep~ [->] ~linep~
|
|
|
|
~result~ contains all overlapping segments of both ~linep~-objects.
|
|
If one of the ~linep~-objects is not defined, ~result~ will be undefined too.
|
|
|
|
*/
|
|
int intersectionWithScaling_LLL(Word* args, Word& result, int message,
|
|
Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
Line2* res = static_cast<Line2*>(result.addr);
|
|
l1->intersectionWithScaling(*l2, *res);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~minusWithScaling\_LLL~
|
|
|
|
~linep~ x ~linep~ [->] ~linep~
|
|
|
|
~result~ contains all segments of the first argument, unless
|
|
they are part of the second argument
|
|
If one of the ~linep~-objects is not defined, ~result~ will be undefined too.
|
|
|
|
*/
|
|
int minusWithScaling_LLL(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
Line2* res = static_cast<Line2*>(result.addr);
|
|
l1->minusWithScaling(*l2, *res);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~intersectsWithScaling\_LLB~
|
|
|
|
~linep~ x ~linep~ [->] ~bool~
|
|
|
|
~result~ is true, if 2 segments of both arguments intersect, false otherwise.
|
|
|
|
*/
|
|
int intersectsWithScaling_LLB(Word* args, Word& result, int message,
|
|
Word& local,
|
|
Supplier s) {
|
|
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
bool defined = (l1->IsDefined() && l2->IsDefined());
|
|
bool res = l1->intersectsWithScaling(*l2);
|
|
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1 ~crossingsWithScaling\_LLP~
|
|
|
|
~linep~ x ~linep~ [->] ~points2~
|
|
|
|
~result~ contains all intersection points of the first and the second argument.
|
|
Overlapping parts are not considered.
|
|
|
|
*/
|
|
int crossingsWithScaling_LLP(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
Points2* res = static_cast<Points2*>(result.addr);
|
|
l1->crossingsWithScaling(*l2, *res);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~union\_RRR~
|
|
|
|
~regionp~ x ~regionp~ [->] ~regionp~
|
|
|
|
~result~ contains the union-set of the first and the second argument.
|
|
|
|
|
|
If one of the ~regionp~-objects is not defined, ~result~ will be undefined too.
|
|
|
|
*/
|
|
int union_RRR(Word* args, Word& result, int message, Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
Region2* res = static_cast<Region2*>(result.addr);
|
|
//r1->Union(*r2, *res);
|
|
p2d::SetOp(*r1, *r2, *res, union_op);
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~intersection\_RRR~
|
|
|
|
~regionp~ x ~regionp~ [->] ~regionp~
|
|
|
|
~result~ contains the intersection-set of both ~regionp~-objects.
|
|
If one of the ~regionp~-objects is not defined, ~result~
|
|
will be undefined too.
|
|
|
|
*/
|
|
int intersection_RRR(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
Region2* res = static_cast<Region2*>(result.addr);
|
|
//r1->Intersection(*r2, *res);
|
|
p2d::SetOp(*r1, *r2, *res, intersection_op);
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~minus\_RRR~
|
|
|
|
~regionp~ x ~regionp~ [->] ~regionp~
|
|
|
|
~result~ contains the face of the first argument, reduced to the face
|
|
of the secondo argument
|
|
If one of the ~linep~-objects is not defined, ~result~ will be
|
|
undefined too.
|
|
|
|
*/
|
|
int minus_RRR(Word* args, Word& result, int message, Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
Region2* res = static_cast<Region2*>(result.addr);
|
|
//r1->Minus(*r2, *res);
|
|
p2d::SetOp(*r1, *r2, *res, difference_op);
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~intersects\_RRB~
|
|
|
|
~regionp~ x ~regionp~ [->] ~bool~
|
|
|
|
~result~ is true, if the 2 given regionp-objects intersect, false otherwise.
|
|
|
|
*/
|
|
int intersects_RRB(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
bool res = p2d::intersects(*r1, *r2, 0);
|
|
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1 ~overlaps\_RRB~
|
|
|
|
~regionp~ x ~regionp~ [->] ~bool~
|
|
|
|
~result~ is true, if the 2 given regionp-objects overlap, false otherwise.
|
|
|
|
*/
|
|
int overlaps2_RRB(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
bool res = overlaps(*r1, *r2, 0);
|
|
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1 ~inside\_RRB~
|
|
|
|
~regionp~ x ~regionp~ [->] ~bool~
|
|
|
|
~result~ is true, if the first one of the given regionp-objects is
|
|
completely inside the second regionp-object, false otherwise.
|
|
|
|
*/
|
|
int inside_RRB(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
bool res = inside(*r1, *r2, 0);
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1 ~unionWithScaling\_RRR~
|
|
|
|
~regionp~ x ~regionp~ [->] ~regionp~
|
|
|
|
~result~ contains the union-set of the first and the second argument.
|
|
|
|
|
|
If one of the ~regionp~-objects is not defined, ~result~ will be undefined too.
|
|
|
|
*/
|
|
int unionWithScaling_RRR(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
Region2* res = static_cast<Region2*>(result.addr);
|
|
//r1->Union(*r2, *res);
|
|
p2d::SetOpWithScaling(*r1, *r2, *res, union_op);
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~intersectionWithScaling\_RRR~
|
|
|
|
~regionp~ x ~regionp~ [->] ~regionp~
|
|
|
|
~result~ contains the intersection-set of both ~regionp~-objects.
|
|
If one of the ~regionp~-objects is not defined, ~result~
|
|
will be undefined too.
|
|
|
|
*/
|
|
int intersectionWithScaling_RRR(Word* args, Word& result, int message,
|
|
Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
Region2* res = static_cast<Region2*>(result.addr);
|
|
//r1->Intersection(*r2, *res);
|
|
p2d::SetOpWithScaling(*r1, *r2, *res, intersection_op);
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~minusWithScaling\_RRR~
|
|
|
|
~regionp~ x ~regionp~ [->] ~regionp~
|
|
|
|
~result~ contains the face of the first argument, reduced to the face
|
|
of the secondo argument
|
|
If one of the ~linep~-objects is not defined, ~result~ will be
|
|
undefined too.
|
|
|
|
*/
|
|
int minusWithScaling_RRR(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
Region2* res = static_cast<Region2*>(result.addr);
|
|
//r1->Minus(*r2, *res);
|
|
p2d::SetOpWithScaling(*r1, *r2, *res, difference_op);
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~intersectsWithScaling\_RRB~
|
|
|
|
~regionp~ x ~regionp~ [->] ~bool~
|
|
|
|
~result~ is true, if the 2 given regionp-objects intersect, false otherwise.
|
|
|
|
*/
|
|
int intersectsWithScaling_RRB(Word* args, Word& result, int message,
|
|
Word& local,
|
|
Supplier s) {
|
|
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
bool res = intersectsWithScaling(*r1, *r2, 0);
|
|
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1 ~overlapsWithScaling\_RRB~
|
|
|
|
~regionp~ x ~regionp~ [->] ~bool~
|
|
|
|
~result~ is true, if the 2 given regionp-objects overlap, false otherwise.
|
|
|
|
*/
|
|
int overlapsWithScaling_RRB(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
bool res = overlapsWithScaling(*r1, *r2, 0);
|
|
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1 ~insideWithScaling\_RRB~
|
|
|
|
~regionp~ x ~regionp~ [->] ~bool~
|
|
|
|
~result~ is true, if the first one of the given regionp-objects is
|
|
completely inside the second regionp-object, false otherwise.
|
|
|
|
*/
|
|
int insideWithScaling_RRB(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
bool res = insideWithScaling(*r1, *r2, 0);
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
1.1 ~lineToLine2~
|
|
|
|
~line~ [->] ~linep~
|
|
|
|
This function converts a ~line~-object into a ~linep~-object.
|
|
|
|
*/
|
|
int lineToLine2(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line* l1 = static_cast<Line*>(args[0].addr);
|
|
Line2* res = static_cast<Line2*>(result.addr);
|
|
convertLineToLine2(*l1, *res);
|
|
assert(res->IsDefined()&&res->BoundingBox().IsDefined());
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 ~coarseRegion2~
|
|
|
|
~regionp~ [->] ~region~
|
|
|
|
This function coarses a ~regionp~-object to a ~region~object.
|
|
|
|
*/
|
|
int coarse(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Region2* r = static_cast<Region2*>(args[0].addr);
|
|
Region* res = static_cast<Region*>(result.addr);
|
|
p2d::coarseRegion2(*r, *res);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int coarse2(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Region2* r = static_cast<Region2*>(args[0].addr);
|
|
Region* res = static_cast<Region*>(result.addr);
|
|
p2d::coarseRegion2b(*r, *res);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1 Test-operators
|
|
|
|
The next operator are test-operators. They do the same as the analogous
|
|
operators above. But the operator, who should return a lin2-, points2- or
|
|
regionp-object, return if the object is defined. The other operator, who
|
|
returns only a value of type bool, don't change. Additionally all following
|
|
operators give some information, like how often decisions could be made
|
|
without using the precise values.
|
|
|
|
*/
|
|
|
|
/*
|
|
1.1.1 ~testUnion\_LLB~
|
|
|
|
*/
|
|
int testUnion_LLB(Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
const Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
const Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Line2* res = new Line2(0);
|
|
|
|
p2d_test::TestStruct t;
|
|
p2d_test::SetOp(*l1, *l2, *res, p2d_test::union_op, t, 0);
|
|
|
|
t.noSegmentsIn = (l1->Size()/2) + (l2->Size()/2);
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (l1->IsDefined() && l2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testIntersection\_LLB~
|
|
|
|
*/
|
|
int testIntersection_LLB(Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
const Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
const Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Line2* res = new Line2(0);
|
|
|
|
p2d_test::TestStruct t;
|
|
p2d_test::SetOp(*l1, *l2, *res, p2d_test::intersection_op, t, 0);
|
|
|
|
t.noSegmentsIn = (l1->Size()/2) + (l2->Size()/2);
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (l1->IsDefined() && l2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testMinus\_LLB~
|
|
|
|
*/
|
|
int testMinus_LLB(Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Line2* res = new Line2(0);
|
|
|
|
p2d_test::TestStruct t;
|
|
p2d_test::SetOp(*l1, *l2, *res, p2d_test::difference_op, t, 0);
|
|
|
|
t.noSegmentsIn = (l1->Size()/2) + (l2->Size()/2);
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (l1->IsDefined() && l2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
1.1.1 ~testIntersects\_LLB~
|
|
|
|
*/
|
|
int testIntersects_LLB(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
bool defined = (l1->IsDefined() && l2->IsDefined());
|
|
|
|
p2d_test::TestStruct t;
|
|
bool res = p2d_test::intersects(*l1, *l2, t);
|
|
|
|
t.noSegmentsIn = (l1->Size()/2) + (l2->Size()/2);
|
|
t.print();
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testUnionWithScaling\_LLB~
|
|
|
|
*/
|
|
int testUnionWithScaling_LLB(Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
const Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
const Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Line2* res = new Line2(0);
|
|
|
|
p2d_test::TestStruct t;
|
|
p2d_test::SetOpWithScaling(*l1, *l2, *res, p2d_test::union_op, t, 0);
|
|
|
|
t.noSegmentsIn = (l1->Size()/2) + (l2->Size()/2);
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (l1->IsDefined() && l2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testIntersectionWithScaling\_LLB~
|
|
|
|
*/
|
|
int testIntersectionWithScaling_LLB(Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
const Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
const Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Line2* res = new Line2(0);
|
|
|
|
p2d_test::TestStruct t;
|
|
p2d_test::SetOpWithScaling(*l1, *l2, *res, p2d_test::intersection_op, t, 0);
|
|
|
|
t.noSegmentsIn = (l1->Size()/2) + (l2->Size()/2);
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (l1->IsDefined() && l2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testMinusWithScaling\_LLB~
|
|
|
|
*/
|
|
int testMinusWithScaling_LLB(Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Line2* res = new Line2(0);
|
|
|
|
p2d_test::TestStruct t;
|
|
p2d_test::SetOpWithScaling(*l1, *l2, *res, p2d_test::difference_op, t, 0);
|
|
|
|
t.noSegmentsIn = (l1->Size()/2) + (l2->Size()/2);
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (l1->IsDefined() && l2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
1.1.1 ~testIntersectsWithScaling\_LLB~
|
|
|
|
*/
|
|
int testIntersectsWithScaling_LLB(Word* args, Word& result, int message,
|
|
Word& local,
|
|
Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Line2* l1 = static_cast<Line2*>(args[0].addr);
|
|
Line2* l2 = static_cast<Line2*>(args[1].addr);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
bool defined = (l1->IsDefined() && l2->IsDefined());
|
|
|
|
p2d_test::TestStruct t;
|
|
bool res = p2d_test::intersectsWithScaling(*l1, *l2, t);
|
|
|
|
t.noSegmentsIn = (l1->Size()/2) + (l2->Size()/2);
|
|
t.print();
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testUnion\_RRB~
|
|
|
|
*/
|
|
int testUnion_RRB(Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Region2* res = new Region2(0);
|
|
p2d_test::TestStruct t;
|
|
p2d_test::SetOp(*r1, *r2, *res, p2d_test::union_op, t);
|
|
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testIntersection\_RRB~
|
|
|
|
*/
|
|
int testIntersection_RRB(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Region2* res = new Region2(0);
|
|
p2d_test::TestStruct t;
|
|
//r1->Union(*r2, *res);
|
|
p2d_test::SetOp(*r1, *r2, *res, p2d_test::intersection_op, t);
|
|
|
|
t.noSegmentsIn = (r1->Size()/2) + (r2->Size()/2);
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testMinus\_RRB~
|
|
|
|
*/
|
|
int testMinus_RRB(Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Region2* res = new Region2(0);
|
|
p2d_test::TestStruct t;
|
|
//r1->Union(*r2, *res);
|
|
p2d_test::SetOp(*r1, *r2, *res, p2d_test::difference_op, t);
|
|
|
|
t.noSegmentsIn = (r1->Size()/2) + (r2->Size()/2);
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testUnionWithScaling\_RRB~
|
|
|
|
*/
|
|
int testUnionWithScaling_RRB(Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Region2* res = new Region2(0);
|
|
p2d_test::TestStruct t;
|
|
p2d_test::SetOpWithScaling(*r1, *r2, *res, p2d_test::union_op, t);
|
|
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testIntersectionWithScaling\_RRB~
|
|
|
|
*/
|
|
int testIntersectionWithScaling_RRB(Word* args, Word& result, int message,
|
|
Word& local,
|
|
Supplier s) {
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Region2* res = new Region2(0);
|
|
p2d_test::TestStruct t;
|
|
//r1->Union(*r2, *res);
|
|
p2d_test::SetOpWithScaling(*r1, *r2, *res, p2d_test::intersection_op, t);
|
|
|
|
t.noSegmentsIn = (r1->Size()/2) + (r2->Size()/2);
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testMinusWithScaling\_RRB~
|
|
|
|
*/
|
|
int testMinusWithScaling_RRB(Word* args, Word& result, int message,
|
|
Word& local, Supplier s) {
|
|
result = qp->ResultStorage(s);
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
Region2* res = new Region2(0);
|
|
p2d_test::TestStruct t;
|
|
//r1->Union(*r2, *res);
|
|
p2d_test::SetOpWithScaling(*r1, *r2, *res, p2d_test::difference_op, t);
|
|
|
|
t.noSegmentsIn = (r1->Size()/2) + (r2->Size()/2);
|
|
t.noSegmentsOut = res->Size()/2;
|
|
t.print();
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
b->Set(defined, res->IsDefined());
|
|
|
|
delete res;
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testIntersectsWithScaling\_RRB~
|
|
|
|
~regionp~ x ~regionp~ [->] ~bool~
|
|
|
|
~result~ is true, if the 2 given regionp-objects intersect, false otherwise.
|
|
|
|
*/
|
|
int testIntersectsWithScaling_RRB(Word* args, Word& result, int message,
|
|
Word& local,
|
|
Supplier s) {
|
|
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
p2d_test::TestStruct t;
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
bool res = p2d_test::intersectsWithScaling(*r1, *r2, t);
|
|
|
|
t.noSegmentsIn = (r1->Size()/2) + (r2->Size()/2);
|
|
t.print();
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~testIntersects\_RRB~
|
|
|
|
~regionp~ x ~regionp~ [->] ~bool~
|
|
|
|
~result~ is true, if the 2 given regionp-objects intersect, false otherwise.
|
|
|
|
*/
|
|
int testIntersects_RRB(Word* args, Word& result, int message, Word& local,
|
|
Supplier s) {
|
|
|
|
Region2* r1 = static_cast<Region2*>(args[0].addr);
|
|
Region2* r2 = static_cast<Region2*>(args[1].addr);
|
|
|
|
result = qp->ResultStorage(s);
|
|
CcBool* b = static_cast<CcBool*>(result.addr);
|
|
|
|
p2d_test::TestStruct t;
|
|
|
|
bool defined = (r1->IsDefined() && r2->IsDefined());
|
|
bool res = p2d_test::intersects(*r1, *r2, t);
|
|
|
|
t.noSegmentsIn = (r1->Size()/2) + (r2->Size()/2);
|
|
t.print();
|
|
b->Set(defined, res);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~bbox~ for Point2
|
|
|
|
*/
|
|
int point2BBox(Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
result = qp->ResultStorage( s );
|
|
Rectangle<2>* box = static_cast<Rectangle<2>* >(result.addr);
|
|
const Point2* point = static_cast<const Point2*>(args[0].addr);
|
|
|
|
if(!point->IsDefined() ){
|
|
box->SetDefined(false);
|
|
} else {
|
|
(*box) = point->BoundingBox(0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~bbox~ for Points2
|
|
|
|
*/
|
|
int points2BBox(Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
|
|
result = qp->ResultStorage( s );
|
|
Rectangle<2>* box = static_cast<Rectangle<2>* >(result.addr);
|
|
const Points2* points = static_cast<const Points2*>(args[0].addr);
|
|
|
|
if(!points->IsDefined() ){
|
|
box->SetDefined(false);
|
|
} else {
|
|
(*box) = points->BoundingBox(0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
1.1.1 ~bbox~ for Line2
|
|
|
|
*/
|
|
int line2BBox(Word* args, Word& result, int message,
|
|
Word& local, Supplier s ){
|
|
|
|
result = qp->ResultStorage( s );
|
|
Rectangle<2>* box = static_cast<Rectangle<2>* >(result.addr);
|
|
const Line2* line = static_cast<const Line2*>(args[0].addr);
|
|
|
|
if(!line->IsDefined() ){
|
|
box->SetDefined(false);
|
|
} else {
|
|
(*box) = line->BoundingBox(0);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
4 Type-mapping-function
|
|
|
|
*/
|
|
|
|
/*
|
|
4.1 ~LLL\_TypeMap~
|
|
|
|
Signature is
|
|
~linep~ x ~linep~ [->] ~linep~
|
|
|
|
*/
|
|
ListExpr LLL_TypeMap(ListExpr args) {
|
|
string err = "linep x linep expected.";
|
|
if (nl->ListLength(args) != 2) {
|
|
return listutils::typeError(err + ": wrong number of arguments");
|
|
}
|
|
ListExpr arg1 = nl->First(args);
|
|
ListExpr arg2 = nl->Second(args);
|
|
if (!listutils::isSymbol(arg1)) {
|
|
return listutils::typeError(err + ": first arg not a spatial type");
|
|
}
|
|
if (!listutils::isSymbol(arg2)) {
|
|
return listutils::typeError(err + ": second arg not a spatial type");
|
|
}
|
|
string a1 = nl->SymbolValue(arg1);
|
|
string a2 = nl->SymbolValue(arg2);
|
|
|
|
if (a1 == Line2::BasicType() && a2 == Line2::BasicType()) {
|
|
return nl->SymbolAtom(Line2::BasicType());
|
|
}
|
|
|
|
return listutils::typeError(err);
|
|
}
|
|
|
|
|
|
/*
|
|
4.2 ~LLB\_TypeMap~
|
|
|
|
Signature is ~linep~ x ~linep~ [->] bool
|
|
|
|
*/
|
|
ListExpr LLB_TypeMap(ListExpr args) {
|
|
string err = "linep x linep expected.";
|
|
if (nl->ListLength(args) != 2) {
|
|
return listutils::typeError(err + ": wrong number of arguments");
|
|
}
|
|
ListExpr arg1 = nl->First(args);
|
|
ListExpr arg2 = nl->Second(args);
|
|
if (!listutils::isSymbol(arg1)) {
|
|
return listutils::typeError(err + ": first arg not a spatial type");
|
|
}
|
|
if (!listutils::isSymbol(arg2)) {
|
|
return listutils::typeError(err + ": second arg not a spatial type");
|
|
}
|
|
string a1 = nl->SymbolValue(arg1);
|
|
string a2 = nl->SymbolValue(arg2);
|
|
|
|
if (a1 == Line2::BasicType() && a2 == Line2::BasicType()) {
|
|
return NList(CcBool::BasicType()).listExpr();
|
|
}
|
|
return listutils::typeError(err);
|
|
}
|
|
|
|
/*
|
|
4.3 ~LLP\_TypeMap~
|
|
|
|
Signature is linep x linep [->] points2
|
|
|
|
*/
|
|
ListExpr LLP_TypeMap(ListExpr args) {
|
|
string err = "linep x linep expected.";
|
|
if (nl->ListLength(args) != 2) {
|
|
return listutils::typeError(err + ": wrong number of arguments");
|
|
}
|
|
ListExpr arg1 = nl->First(args);
|
|
ListExpr arg2 = nl->Second(args);
|
|
if (!listutils::isSymbol(arg1)) {
|
|
return listutils::typeError(err + ": first arg not a spatial type");
|
|
}
|
|
if (!listutils::isSymbol(arg2)) {
|
|
return listutils::typeError(err + ": second arg not a spatial type");
|
|
}
|
|
string a1 = nl->SymbolValue(arg1);
|
|
string a2 = nl->SymbolValue(arg2);
|
|
|
|
if (a1 == Line2::BasicType() && a2 == Line2::BasicType()) {
|
|
return nl->SymbolAtom(Points2::BasicType());
|
|
}
|
|
return listutils::typeError(err);
|
|
}
|
|
|
|
/*
|
|
4.4 ~LL2\_TypeMap~
|
|
|
|
Signature is linep x linep [->] linep
|
|
|
|
*/
|
|
ListExpr LL2_TypeMap(ListExpr args) {
|
|
string err = "line expected.";
|
|
if (nl->ListLength(args) != 1) {
|
|
return listutils::typeError(err + ": wrong number of arguments");
|
|
}
|
|
ListExpr arg1 = nl->First(args);
|
|
if (!listutils::isSymbol(arg1)) {
|
|
return listutils::typeError(err + ": first arg not a spatial type");
|
|
}
|
|
|
|
string a1 = nl->SymbolValue(arg1);
|
|
|
|
if (a1 == Line::BasicType()) {
|
|
return nl->SymbolAtom(Line2::BasicType());
|
|
}
|
|
|
|
return listutils::typeError(err);
|
|
}
|
|
|
|
/*
|
|
4.5 ~RRR\_TypeMap~
|
|
|
|
Signature is
|
|
~regionp~ x ~regionp~ [->] ~regionp~
|
|
|
|
*/
|
|
ListExpr RRR_TypeMap(ListExpr args) {
|
|
string err = "regionp x regionp expected. ";
|
|
if (nl->ListLength(args) != 2) {
|
|
return listutils::typeError(err + ": wrong number of arguments");
|
|
}
|
|
ListExpr arg1 = nl->First(args);
|
|
ListExpr arg2 = nl->Second(args);
|
|
if (!listutils::isSymbol(arg1)) {
|
|
return listutils::typeError(err + ": first arg not a spatial type");
|
|
}
|
|
if (!listutils::isSymbol(arg2)) {
|
|
return listutils::typeError(err + ": second arg not a spatial type");
|
|
}
|
|
string a1 = nl->SymbolValue(arg1);
|
|
string a2 = nl->SymbolValue(arg2);
|
|
|
|
if (a1 == Region2::BasicType() && a2 == Region2::BasicType()) {
|
|
return nl->SymbolAtom(Region2::BasicType());
|
|
}
|
|
return listutils::typeError(err);
|
|
}
|
|
|
|
/*
|
|
4.6 ~RRB\_TypeMap~
|
|
|
|
Signature is ~regionp~ x ~regionp~ [->] bool
|
|
|
|
*/
|
|
ListExpr RRB_TypeMap(ListExpr args) {
|
|
string err = "regionp x regionp expected.";
|
|
if (nl->ListLength(args) != 2) {
|
|
return listutils::typeError(err + ": wrong number of arguments");
|
|
}
|
|
ListExpr arg1 = nl->First(args);
|
|
ListExpr arg2 = nl->Second(args);
|
|
if (!listutils::isSymbol(arg1)) {
|
|
return listutils::typeError(err + ": first arg not a spatial type");
|
|
}
|
|
if (!listutils::isSymbol(arg2)) {
|
|
return listutils::typeError(err + ": second arg not a spatial type");
|
|
}
|
|
string a1 = nl->SymbolValue(arg1);
|
|
string a2 = nl->SymbolValue(arg2);
|
|
|
|
if (a1 == Region2::BasicType() && a2 == Region2::BasicType()) {
|
|
return NList(CcBool::BasicType()).listExpr();
|
|
}
|
|
return listutils::typeError(err);
|
|
}
|
|
|
|
/*
|
|
4.7 ~R2R\_TypeMap~
|
|
|
|
Signature is ~regionp~ [->] region
|
|
|
|
*/
|
|
ListExpr R2R_TypeMap(ListExpr args) {
|
|
string err = "line expected.";
|
|
if (nl->ListLength(args) != 1) {
|
|
return listutils::typeError(err + ": wrong number of arguments");
|
|
}
|
|
ListExpr arg1 = nl->First(args);
|
|
if (!listutils::isSymbol(arg1)) {
|
|
return listutils::typeError(err + ": first arg not a spatial type");
|
|
}
|
|
|
|
string a1 = nl->SymbolValue(arg1);
|
|
|
|
if (a1 == Region2::BasicType()) {
|
|
return nl->SymbolAtom(Region::BasicType());
|
|
}
|
|
|
|
return listutils::typeError(err);
|
|
}
|
|
|
|
/*
|
|
4.8 Spatial2Rect\_TypeMap
|
|
|
|
For operators with signature
|
|
Point2 [->] rect,
|
|
Points2 [->] rect and
|
|
Line2 [->] rect.
|
|
|
|
*/
|
|
ListExpr
|
|
Spatial2Rect_TypeMap( ListExpr args )
|
|
{
|
|
|
|
if ( nl->ListLength( args )!=1 ){
|
|
return listutils::typeError("Only one argument expected.");
|
|
}
|
|
if(nl->AtomType(nl->First(args))!=SymbolType){
|
|
return listutils::typeError("First argument is not in "
|
|
"{pointp,pointsp ird linep}");
|
|
}
|
|
string type = nl->SymbolValue(nl->First( args ));
|
|
if ( type != Point2::BasicType() &&
|
|
type != Points2::BasicType() &&
|
|
type != Line2::BasicType() ){
|
|
return listutils::typeError("Only one argument arg expected , "
|
|
"with arg in {pointp, pointsp or linep.");
|
|
}
|
|
|
|
return (nl->SymbolAtom( Rectangle<2>::BasicType() ));
|
|
}
|
|
|
|
/*
|
|
5 operator information
|
|
|
|
*/
|
|
|
|
/*
|
|
5.1 ~union\_LLLInfo~
|
|
|
|
The operator information for union of 2 linep-objects
|
|
|
|
*/
|
|
struct union_LLLInfo: OperatorInfo {
|
|
|
|
union_LLLInfo() :
|
|
OperatorInfo() {
|
|
name = "union";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> "
|
|
+ Line2::BasicType();
|
|
syntax = "query arg1 union arg2";
|
|
meaning = "union of two linep objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.2 ~intersection\_LLLInfo~
|
|
|
|
The operator information for intersection of 2 linep-objects
|
|
|
|
*/
|
|
struct intersection_LLLInfo: OperatorInfo {
|
|
|
|
intersection_LLLInfo() :
|
|
OperatorInfo() {
|
|
name = "intersection";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> "
|
|
+ Line2::BasicType();
|
|
syntax = "query intersection (arg1, arg2)";
|
|
meaning = "intersection of two linep objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.3 ~minus\_LLLInfo~
|
|
|
|
The operator information for the difference of 2 linep-objects
|
|
|
|
*/
|
|
struct minus_LLLInfo: OperatorInfo {
|
|
|
|
minus_LLLInfo() :
|
|
OperatorInfo() {
|
|
name = "minus";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> "
|
|
+ Line2::BasicType();
|
|
syntax = "query arg1 minus arg2";
|
|
meaning = "difference of two linep objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.4 ~intersects\_LLBInfo~
|
|
|
|
The operator information for the test if 2 linep-objects intersect
|
|
|
|
*/
|
|
struct intersects_LLBInfo: OperatorInfo {
|
|
|
|
intersects_LLBInfo() :
|
|
OperatorInfo() {
|
|
name = "intersects";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> bool";
|
|
syntax = "query arg1 intersects arg2";
|
|
meaning = "returns true, if both linep "
|
|
"objects intersect, false otherwise.";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.5 ~crossings\_LLPInfo~
|
|
|
|
*/
|
|
struct crossings_LLPInfo: OperatorInfo {
|
|
|
|
crossings_LLPInfo() :
|
|
OperatorInfo() {
|
|
name = "crossings";
|
|
signature = Line2::BasicType() + " x "
|
|
+ Line2::BasicType() + " -> "+ Points2::BasicType();
|
|
syntax = "query crossings(arg1, arg2)";
|
|
meaning = "intersection-points of two linep-objects ";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.1 ~unionWithScaling\_LLLInfo~
|
|
|
|
The operator information for union of 2 linep-objects
|
|
|
|
*/
|
|
struct unionWithScaling_LLLInfo: OperatorInfo {
|
|
|
|
unionWithScaling_LLLInfo() :
|
|
OperatorInfo() {
|
|
name = "unionWithScaling";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> "
|
|
+ Line2::BasicType();
|
|
syntax = "query arg1 unionWithScaling arg2";
|
|
meaning = "union of two linep objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.2 ~intersectionWithScaling\_LLLInfo~
|
|
|
|
The operator information for intersection of 2 linep-objects
|
|
|
|
*/
|
|
struct intersectionWithScaling_LLLInfo: OperatorInfo {
|
|
|
|
intersectionWithScaling_LLLInfo() :
|
|
OperatorInfo() {
|
|
name = "intersectionWithScaling";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> "
|
|
+ Line2::BasicType();
|
|
syntax = "query intersectionWithScaling (arg1, arg2)";
|
|
meaning = "intersection of two linep objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.3 ~minusWithScaling\_LLLInfo~
|
|
|
|
The operator information for the difference of 2 linep-objects
|
|
|
|
*/
|
|
struct minusWithScaling_LLLInfo: OperatorInfo {
|
|
|
|
minusWithScaling_LLLInfo() :
|
|
OperatorInfo() {
|
|
name = "minusWithScaling";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> "
|
|
+ Line2::BasicType();
|
|
syntax = "query arg1 minusWithScaling arg2";
|
|
meaning = "difference of two linep objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.4 ~intersectsWithScaling\_LLBInfo~
|
|
|
|
The operator information for the test if 2 linep-objects intersect
|
|
|
|
*/
|
|
struct intersectsWithScaling_LLBInfo: OperatorInfo {
|
|
|
|
intersectsWithScaling_LLBInfo() :
|
|
OperatorInfo() {
|
|
name = "intersectsWithScaling";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> bool";
|
|
syntax = "query arg1 intersectsWithScaling arg2";
|
|
meaning = "returns true, if both linep "
|
|
"objects intersect, false otherwise.";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.5 ~crossingsWithScaling\_LLPInfo~
|
|
|
|
*/
|
|
struct crossingsWithScaling_LLPInfo: OperatorInfo {
|
|
|
|
crossingsWithScaling_LLPInfo() :
|
|
OperatorInfo() {
|
|
name = "crossingsWithScaling";
|
|
signature = Line2::BasicType() + " x "
|
|
+ Line2::BasicType() + " -> "+ Points2::BasicType();
|
|
syntax = "query crossingsWithScaling(arg1, arg2)";
|
|
meaning = "intersection-points of two linep-objects ";
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
5.6 ~union\_RRRInfo~
|
|
|
|
The operator information for union of 2 regionp-objects
|
|
|
|
*/
|
|
struct union_RRRInfo: OperatorInfo {
|
|
|
|
union_RRRInfo() :
|
|
OperatorInfo() {
|
|
name = "union";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> "
|
|
+ Region2::BasicType();
|
|
syntax = "query arg1 union arg2";
|
|
meaning = "union of two regionp objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.7 ~intersection\_RRRInfo~
|
|
|
|
The operator information for intersection of 2 regionp-objects
|
|
|
|
*/
|
|
struct intersection_RRRInfo: OperatorInfo {
|
|
|
|
intersection_RRRInfo() :
|
|
OperatorInfo() {
|
|
name = "intersection";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> "
|
|
+ Region2::BasicType();
|
|
syntax = "query intersection (arg1, arg2)";
|
|
meaning = "intersection of two regionp objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.8 ~minus\_RRRInfo~
|
|
|
|
The operator information for the difference of 2 regionp-objects
|
|
|
|
*/
|
|
struct minus_RRRInfo: OperatorInfo {
|
|
|
|
minus_RRRInfo() :
|
|
OperatorInfo() {
|
|
name = "minus";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> "
|
|
+ Region2::BasicType();
|
|
syntax = "query arg1 minus arg2";
|
|
meaning = "difference of two regionp objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.6 ~unionWithScaling\_RRRInfo~
|
|
|
|
The operator information for union of 2 regionp-objects
|
|
|
|
*/
|
|
struct unionWithScaling_RRRInfo: OperatorInfo {
|
|
|
|
unionWithScaling_RRRInfo() :
|
|
OperatorInfo() {
|
|
name = "unionWithScaling";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> "
|
|
+ Region2::BasicType();
|
|
syntax = "query arg1 unionWithScaling arg2";
|
|
meaning = "union of two regionp objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.7 ~intersectionWithScaling\_RRRInfo~
|
|
|
|
The operator information for intersection of 2 regionp-objects
|
|
|
|
*/
|
|
struct intersectionWithScaling_RRRInfo: OperatorInfo {
|
|
|
|
intersectionWithScaling_RRRInfo() :
|
|
OperatorInfo() {
|
|
name = "intersectionWithScaling";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> "
|
|
+ Region2::BasicType();
|
|
syntax = "query intersectionWithScaling (arg1, arg2)";
|
|
meaning = "intersection of two regionp objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.8 ~minusWithScaling\_RRRInfo~
|
|
|
|
The operator information for the difference of 2 regionp-objects
|
|
|
|
*/
|
|
struct minusWithScaling_RRRInfo: OperatorInfo {
|
|
|
|
minusWithScaling_RRRInfo() :
|
|
OperatorInfo() {
|
|
name = "minusWithScaling";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> "
|
|
+ Region2::BasicType();
|
|
syntax = "query arg1 minusWithScaling arg2";
|
|
meaning = "difference of two regionp objects";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.9 ~lineToLine2Info~
|
|
|
|
The operator information for union of 2 linep-objects
|
|
|
|
*/
|
|
struct lineToLine2Info: OperatorInfo {
|
|
|
|
lineToLine2Info() :
|
|
OperatorInfo() {
|
|
name = "lineToLinep";
|
|
signature = Line::BasicType() + " -> " + Line2::BasicType();
|
|
syntax = "query lineToLinep(arg)";
|
|
meaning = "converts a line-object into a linep-object";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.10 ~intersects\_RRBInfo~
|
|
|
|
The operator information for the test if 2 regionp-objects intersect
|
|
|
|
*/
|
|
struct intersects2_RRBInfo: OperatorInfo {
|
|
|
|
intersects2_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "intersects2";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> bool";
|
|
syntax = "query arg1 intersects2 arg2";
|
|
meaning = "returns true, if both regionp "
|
|
"objects intersect, false otherwise.";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.11 ~overlaps\_RRBInfo~
|
|
|
|
The operator information for the test if 2 regionp-objects intersect
|
|
|
|
*/
|
|
struct overlaps2_RRBInfo: OperatorInfo {
|
|
|
|
overlaps2_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "overlaps2";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> bool";
|
|
syntax = "query arg1 overlaps2 arg2";
|
|
meaning = "returns true, if both regionp "
|
|
"objects overlap, false otherwise.";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.12 ~inside\_RRBInfo~
|
|
|
|
The operator information for the test whether a regionp-object is completely
|
|
contained in a second regionp-object.
|
|
|
|
*/
|
|
struct inside2_RRBInfo: OperatorInfo {
|
|
|
|
inside2_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "inside2";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> bool";
|
|
syntax = "query arg1 inside2 arg2";
|
|
meaning = "returns true, if the first regionp- "
|
|
"object is completely contained in the second regionp-object, false "
|
|
"otherwise.";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.10 ~intersectsWithScaling\_RRBInfo~
|
|
|
|
The operator information for the test if 2 regionp-objects intersect
|
|
|
|
*/
|
|
struct intersectsWithScaling_RRBInfo: OperatorInfo {
|
|
|
|
intersectsWithScaling_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "intersectsWithScaling";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> bool";
|
|
syntax = "query arg1 intersectsWithScaling arg2";
|
|
meaning = "returns true, if both regionp "
|
|
"objects intersect, false otherwise.";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.11 ~overlapsWithScaling\_RRBInfo~
|
|
|
|
The operator information for the test if 2 regionp-objects intersect
|
|
|
|
*/
|
|
struct overlapsWithScaling_RRBInfo: OperatorInfo {
|
|
|
|
overlapsWithScaling_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "overlapsWithScaling";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> bool";
|
|
syntax = "query arg1 overlapsWithScaling arg2";
|
|
meaning = "returns true, if both regionp "
|
|
"objects overlap, false otherwise.";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.12 ~insideWithScaling\_RRBInfo~
|
|
|
|
The operator information for the test whether a regionp-object is completely
|
|
contained in a second regionp-object.
|
|
|
|
*/
|
|
struct insideWithScaling_RRBInfo: OperatorInfo {
|
|
|
|
insideWithScaling_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "insideWithScaling";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> bool";
|
|
syntax = "query arg1 insideWithScaling arg2";
|
|
meaning = "returns true, if the first regionp- "
|
|
"object is completely contained in the second regionp-object, false "
|
|
"otherwise.";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.13 ~coarseRegion2Info~
|
|
|
|
The operator a ~regionp~-object to a ~region~-object
|
|
|
|
*/
|
|
struct coarseInfo: OperatorInfo {
|
|
|
|
coarseInfo() :
|
|
OperatorInfo() {
|
|
name = "coarse";
|
|
signature = Region2::BasicType() + " -> " + Region::BasicType();
|
|
syntax = "query coarse (arg)";
|
|
meaning = "coarses a regionp-object to a region-object";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
5.14 ~coarseRegion2Info~
|
|
|
|
The operator a ~regionp~-object to a ~region~-object
|
|
|
|
*/
|
|
struct coarse2Info: OperatorInfo {
|
|
|
|
coarse2Info() :
|
|
OperatorInfo() {
|
|
name = "coarse2";
|
|
signature = Region2::BasicType() + " -> " + Region::BasicType();
|
|
syntax = "query coarse2 (arg)";
|
|
meaning = "coarses a regionp-object to a region-object. The difference"
|
|
"between coarse and coarse2 is that the intermediate results"
|
|
"of coarse2 are of type regionp. coarse2 might last a little bit longer"
|
|
"but it uses only the set operation of regionp.";
|
|
}
|
|
|
|
};
|
|
|
|
|
|
/*
|
|
6 operator information for the test-operators
|
|
|
|
*/
|
|
|
|
/*
|
|
6.1 ~testUnionInfo~ for Line2
|
|
|
|
*/
|
|
struct testUnion_LLBInfo: OperatorInfo {
|
|
|
|
testUnion_LLBInfo() :
|
|
OperatorInfo() {
|
|
name = "testUnion";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> bool";
|
|
syntax = "query arg1 testUnion arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testIntersectionInfo~ for Line2
|
|
|
|
*/
|
|
struct testIntersection_LLBInfo: OperatorInfo {
|
|
|
|
testIntersection_LLBInfo() :
|
|
OperatorInfo() {
|
|
name = "testIntersection";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> bool";
|
|
syntax = "query testIntersection (arg1, arg2)";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testMinusInfo~ for Line2
|
|
|
|
*/
|
|
struct testMinus_LLBInfo: OperatorInfo {
|
|
|
|
testMinus_LLBInfo() :
|
|
OperatorInfo() {
|
|
name = "testMinus";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> bool";
|
|
syntax = "query arg1 testMinus arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testIntersectsInfo~ for Line2
|
|
|
|
*/
|
|
struct testIntersects_LLBInfo: OperatorInfo {
|
|
|
|
testIntersects_LLBInfo() :
|
|
OperatorInfo() {
|
|
name = "testIntersects";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> bool";
|
|
syntax = "query arg1 testIntersects arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testUnionWithScalingInfo~ for Line2
|
|
|
|
*/
|
|
struct testUnionWithScaling_LLBInfo: OperatorInfo {
|
|
|
|
testUnionWithScaling_LLBInfo() :
|
|
OperatorInfo() {
|
|
name = "testUnionWithScaling";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> bool";
|
|
syntax = "query arg1 testUnionWithScaling arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testIntersectionWithScalingInfo~ for Line2
|
|
|
|
*/
|
|
struct testIntersectionWithScaling_LLBInfo: OperatorInfo {
|
|
|
|
testIntersectionWithScaling_LLBInfo() :
|
|
OperatorInfo() {
|
|
name = "testIntersectionWithScaling";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> bool";
|
|
syntax = "query testIntersectionWithScaling (arg1, arg2)";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testMinusWithScalingInfo~ for Line2
|
|
|
|
*/
|
|
struct testMinusWithScaling_LLBInfo: OperatorInfo {
|
|
|
|
testMinusWithScaling_LLBInfo() :
|
|
OperatorInfo() {
|
|
name = "testMinusWithScaling";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> bool";
|
|
syntax = "query arg1 testMinusWithScaling arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testIntersectsWithScalingInfo~ for Line2
|
|
|
|
*/
|
|
struct testIntersectsWithScaling_LLBInfo: OperatorInfo {
|
|
|
|
testIntersectsWithScaling_LLBInfo() :
|
|
OperatorInfo() {
|
|
name = "testIntersectsWithScaling";
|
|
signature = Line2::BasicType() + " x " + Line2::BasicType() + " -> bool";
|
|
syntax = "query arg1 testIntersectsWithScaling arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testUnionInfo~ for Region2
|
|
|
|
*/
|
|
struct testUnion_RRBInfo: OperatorInfo {
|
|
|
|
testUnion_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "testUnion";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType()
|
|
+ " -> bool";
|
|
syntax = "query arg1 testUnion arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testIntersectionInfo~ for Region2
|
|
|
|
*/
|
|
struct testIntersection_RRBInfo: OperatorInfo {
|
|
|
|
testIntersection_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "testIntersection";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType()
|
|
+ " -> bool";
|
|
syntax = "query testIntersection (arg1, arg2)";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testMinusInfo~ for Region2
|
|
|
|
*/
|
|
struct testMinus_RRBInfo: OperatorInfo {
|
|
|
|
testMinus_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "testMinus";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> bool";
|
|
syntax = "query arg1 testMinus arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testUnionWithScalingInfo~ for Region2
|
|
|
|
*/
|
|
struct testUnionWithScaling_RRBInfo: OperatorInfo {
|
|
|
|
testUnionWithScaling_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "testUnionWithScaling";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType()
|
|
+ " -> bool";
|
|
syntax = "query arg1 testUnionWithScaling arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testIntersectionWithScalingInfo~ for Region2
|
|
|
|
*/
|
|
struct testIntersectionWithScaling_RRBInfo: OperatorInfo {
|
|
|
|
testIntersectionWithScaling_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "testIntersectionWithScaling";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType()
|
|
+ " -> bool";
|
|
syntax = "query testIntersectionWithScaling (arg1, arg2)";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testMinusWithScalingInfo~ for Region2
|
|
|
|
*/
|
|
struct testMinusWithScaling_RRBInfo: OperatorInfo {
|
|
|
|
testMinusWithScaling_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "testMinusWithScaling";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> bool";
|
|
syntax = "query arg1 testMinusWithScaling arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testIntersectsInfo~ for Region2
|
|
|
|
*/
|
|
struct testIntersects_RRBInfo: OperatorInfo {
|
|
|
|
testIntersects_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "testIntersects";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> bool";
|
|
syntax = "query arg1 testIntersects arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~testIntersectsWithScalingInfo~ for Region2
|
|
|
|
*/
|
|
struct testIntersectsWithScaling_RRBInfo: OperatorInfo {
|
|
|
|
testIntersectsWithScaling_RRBInfo() :
|
|
OperatorInfo() {
|
|
name = "testIntersectsWithScaling";
|
|
signature = Region2::BasicType() + " x " + Region2::BasicType() + " -> bool";
|
|
syntax = "query arg1 testIntersectsWithScaling arg2";
|
|
meaning = "only for tests";
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
6.1 ~bbox\_Info()~ for Point2, Points2 and Line2.
|
|
|
|
*/
|
|
struct bbox_Info: OperatorInfo {
|
|
|
|
bbox_Info() :
|
|
OperatorInfo() {
|
|
name = "bbox";
|
|
signature = "( " + Point2::BasicType() + "||" + Points2::BasicType() +
|
|
"||" + Line2::BasicType() + " ) -> rect";
|
|
syntax = "query bbox(arg)";
|
|
meaning = "Returns the bounding box of a spatial object";
|
|
}
|
|
};
|
|
|
|
|
|
/*
|
|
7 Creation of the type constructor instance
|
|
|
|
*/
|
|
TypeConstructor point(Point2::BasicType(), Point2::Point2Property,
|
|
Point2::OutPoint2, Point2::InPoint2, 0, 0, Point2::CreatePoint2,
|
|
Point2::DeletePoint2, OpenAttribute<Point2>, SaveAttribute<Point2>,
|
|
Point2::ClosePoint2, Point2::ClonePoint2, Point2::CastPoint2,
|
|
Point2::SizeOfPoint2, Point2::CheckPoint2);
|
|
|
|
TypeConstructor line(Line2::BasicType(), Line2::Line2Property, Line2::OutLine2,
|
|
Line2::InLine2, 0, 0, Line2::CreateLine2, Line2::DeleteLine2,
|
|
OpenAttribute<Line2>, SaveAttribute<Line2>, Line2::CloseLine2,
|
|
Line2::CloneLine2, Line2::CastLine2, Line2::SizeOfLine2, Line2::CheckLine2);
|
|
|
|
TypeConstructor points(Points2::BasicType(), Points2::Points2Property,
|
|
Points2::OutPoints2, Points2::InPoints2, 0, 0, Points2::CreatePoints2,
|
|
Points2::DeletePoints2, OpenAttribute<Points2>, SaveAttribute<Points2>,
|
|
Points2::ClosePoints2, Points2::ClonePoints2, Points2::CastPoints2,
|
|
Points2::SizeOfPoints2, Points2::CheckPoints2);
|
|
|
|
|
|
} // end of namespace p2d
|
|
|
|
/*
|
|
1 Class Precise2DAlgebra
|
|
|
|
*/
|
|
class Precise2DAlgebra: public Algebra {
|
|
public:
|
|
Precise2DAlgebra() :
|
|
Algebra() {
|
|
|
|
/*
|
|
1.1 Add types
|
|
|
|
*/
|
|
AddTypeConstructor(&p2d::point);
|
|
AddTypeConstructor(&p2d::line);
|
|
AddTypeConstructor(&p2d::points);
|
|
|
|
p2d::point.AssociateKind(Kind::DATA());
|
|
p2d::point.AssociateKind(Kind::SPATIAL2D());
|
|
|
|
p2d::line.AssociateKind(Kind::DATA());
|
|
p2d::line.AssociateKind(Kind::SPATIAL2D());
|
|
|
|
p2d::points.AssociateKind(Kind::DATA());
|
|
p2d::points.AssociateKind(Kind::SPATIAL2D());
|
|
|
|
/*
|
|
1.1 Add operators
|
|
|
|
*/
|
|
AddOperator(p2d::union_LLLInfo(), p2d::union_LLL, p2d::LLL_TypeMap);
|
|
|
|
AddOperator(p2d::intersection_LLLInfo(), p2d::intersection_LLL,
|
|
p2d::LLL_TypeMap);
|
|
|
|
AddOperator(p2d::minus_LLLInfo(), p2d::minus_LLL, p2d::LLL_TypeMap);
|
|
|
|
AddOperator(p2d::intersects_LLBInfo(), p2d::intersects_LLB, p2d::LLB_TypeMap);
|
|
|
|
AddOperator(p2d::unionWithScaling_LLLInfo(), p2d::unionWithScaling_LLL,
|
|
p2d::LLL_TypeMap);
|
|
|
|
AddOperator(p2d::intersectionWithScaling_LLLInfo(),
|
|
p2d::intersectionWithScaling_LLL,
|
|
p2d::LLL_TypeMap);
|
|
|
|
AddOperator(p2d::minusWithScaling_LLLInfo(), p2d::minusWithScaling_LLL,
|
|
p2d::LLL_TypeMap);
|
|
|
|
AddOperator(p2d::intersectsWithScaling_LLBInfo(),
|
|
p2d::intersectsWithScaling_LLB, p2d::LLB_TypeMap);
|
|
|
|
AddOperator(p2d::lineToLine2Info(), p2d::lineToLine2, p2d::LL2_TypeMap);
|
|
|
|
AddOperator(p2d::crossings_LLPInfo(), p2d::crossings_LLP, p2d::LLP_TypeMap);
|
|
|
|
AddOperator(p2d::crossingsWithScaling_LLPInfo(),
|
|
p2d::crossingsWithScaling_LLP, p2d::LLP_TypeMap);
|
|
|
|
AddOperator(p2d::union_RRRInfo(), p2d::union_RRR, p2d::RRR_TypeMap);
|
|
|
|
AddOperator(p2d::intersection_RRRInfo(), p2d::intersection_RRR,
|
|
p2d::RRR_TypeMap);
|
|
|
|
AddOperator(p2d::minus_RRRInfo(), p2d::minus_RRR, p2d::RRR_TypeMap);
|
|
|
|
AddOperator(p2d::unionWithScaling_RRRInfo(), p2d::unionWithScaling_RRR,
|
|
p2d::RRR_TypeMap);
|
|
|
|
AddOperator(p2d::intersectionWithScaling_RRRInfo(),
|
|
p2d::intersectionWithScaling_RRR, p2d::RRR_TypeMap);
|
|
|
|
AddOperator(p2d::minusWithScaling_RRRInfo(), p2d::minusWithScaling_RRR,
|
|
p2d::RRR_TypeMap);
|
|
|
|
AddOperator(p2d::intersects2_RRBInfo(), p2d::intersects_RRB,
|
|
p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::overlaps2_RRBInfo(), p2d::overlaps2_RRB, p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::inside2_RRBInfo(), p2d::inside_RRB, p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::intersectsWithScaling_RRBInfo(),
|
|
p2d::intersectsWithScaling_RRB,
|
|
p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::overlapsWithScaling_RRBInfo(),
|
|
p2d::overlapsWithScaling_RRB, p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::insideWithScaling_RRBInfo(),
|
|
p2d::insideWithScaling_RRB, p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::coarseInfo(), p2d::coarse, p2d::R2R_TypeMap);
|
|
|
|
AddOperator(p2d::coarse2Info(), p2d::coarse2, p2d::R2R_TypeMap);
|
|
|
|
AddOperator(p2d::testUnion_LLBInfo(), p2d::testUnion_LLB, p2d::LLB_TypeMap);
|
|
|
|
AddOperator(p2d::testIntersection_LLBInfo(), p2d::testIntersection_LLB,
|
|
p2d::LLB_TypeMap);
|
|
|
|
AddOperator(p2d::testMinus_LLBInfo(), p2d::testMinus_LLB, p2d::LLB_TypeMap);
|
|
|
|
AddOperator(p2d::testUnionWithScaling_LLBInfo(),
|
|
p2d::testUnionWithScaling_LLB, p2d::LLB_TypeMap);
|
|
|
|
AddOperator(p2d::testIntersectionWithScaling_LLBInfo(),
|
|
p2d::testIntersectionWithScaling_LLB, p2d::LLB_TypeMap);
|
|
|
|
AddOperator(p2d::testMinusWithScaling_LLBInfo(),
|
|
p2d::testMinusWithScaling_LLB, p2d::LLB_TypeMap);
|
|
|
|
AddOperator(p2d::testIntersects_LLBInfo(), p2d::testIntersects_LLB,
|
|
p2d::LLB_TypeMap);
|
|
|
|
AddOperator(p2d::testIntersectsWithScaling_LLBInfo(),
|
|
p2d::testIntersects_LLB, p2d::LLB_TypeMap);
|
|
|
|
AddOperator(p2d::testUnion_RRBInfo(), p2d::testUnion_RRB, p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::testIntersection_RRBInfo(), p2d::testIntersection_RRB,
|
|
p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::testMinus_RRBInfo(), p2d::testMinus_RRB, p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::testUnionWithScaling_RRBInfo(),
|
|
p2d::testUnionWithScaling_RRB, p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::testIntersectionWithScaling_RRBInfo(),
|
|
p2d::testIntersectionWithScaling_RRB,
|
|
p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::testMinusWithScaling_RRBInfo(),
|
|
p2d::testMinusWithScaling_RRB, p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::testIntersects_RRBInfo(), p2d::testIntersects_RRB,
|
|
p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::testIntersectsWithScaling_RRBInfo(),
|
|
p2d::testIntersectsWithScaling_RRB, p2d::RRB_TypeMap);
|
|
|
|
AddOperator(p2d::bbox_Info(),
|
|
p2d::point2BBox, p2d::Spatial2Rect_TypeMap);
|
|
|
|
AddOperator(p2d::bbox_Info(),
|
|
p2d::points2BBox, p2d::Spatial2Rect_TypeMap);
|
|
|
|
AddOperator(p2d::bbox_Info(),
|
|
p2d::line2BBox, p2d::Spatial2Rect_TypeMap);
|
|
}
|
|
|
|
~Precise2DAlgebra() {
|
|
}
|
|
|
|
};
|
|
|
|
extern "C" Algebra*
|
|
InitializePrecise2DAlgebra(NestedList* nlRef, QueryProcessor* qpRef) {
|
|
nl = nlRef;
|
|
qp = qpRef;
|
|
return (new Precise2DAlgebra());
|
|
}
|
|
|
|
#endif/* _PRECISE2DALGEBRA_CPP*/
|