374 lines
11 KiB
C++
374 lines
11 KiB
C++
/*
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2013, 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
|
|
|
|
*/
|
|
|
|
/*
|
|
SECONDO includes
|
|
|
|
*/
|
|
|
|
#include "../HalfSegment/HalfSegment.h"
|
|
#include "Algebras/Rectangle/RectangleAlgebra.h"
|
|
|
|
/*
|
|
TileAlgebra includes
|
|
|
|
*/
|
|
|
|
#include "fromline.h"
|
|
|
|
/*
|
|
declaration of namespace TileAlgebra
|
|
|
|
*/
|
|
|
|
namespace TileAlgebra
|
|
{
|
|
|
|
/*
|
|
Method SetLineValues sets all cells of given tbool object intersected
|
|
by given HalfSegment to true.
|
|
|
|
author: Dirk Zacher
|
|
parameters: rHalfSegment - reference to a HalfSegment
|
|
rtbool - reference to a tbool object containing all cells
|
|
intersected by rHalfSegment marked with a true value
|
|
return value: true, if the value of a cell of given tbool object set to true,
|
|
otherwise false
|
|
exceptions: -
|
|
|
|
*/
|
|
|
|
bool SetLineValues(const HalfSegment& rHalfSegment,
|
|
tbool& rtbool)
|
|
{
|
|
bool bHasTrueValue = false;
|
|
|
|
if(rtbool.IsDefined())
|
|
{
|
|
HalfSegment halfSegment = rHalfSegment;
|
|
CheckHalfSegment(halfSegment);
|
|
|
|
Point lineStartPoint = halfSegment.GetLeftPoint();
|
|
Point lineEndPoint = halfSegment.GetRightPoint();
|
|
|
|
if(lineStartPoint.IsDefined() &&
|
|
lineEndPoint.IsDefined())
|
|
{
|
|
int xDimensionSize = tProperties<char>::GetXDimensionSize();
|
|
int yDimensionSize = tProperties<char>::GetYDimensionSize();
|
|
|
|
tgrid grid;
|
|
rtbool.getgrid(grid);
|
|
double gridX = grid.GetX();
|
|
double gridY = grid.GetY();
|
|
double gridLength = grid.GetLength();
|
|
|
|
double Minima[2] = { gridX, gridY };
|
|
double Maxima[2] = { gridX + xDimensionSize * gridLength,
|
|
gridY + yDimensionSize * gridLength };
|
|
Rectangle<2> rectangle(true, Minima, Maxima);
|
|
|
|
if(HalfSegmentIntersectsRectangle(halfSegment, rectangle))
|
|
{
|
|
Point leftPoint(true, 0.0, 0.0);
|
|
Point rightPoint(true, 0.0, 0.0);
|
|
|
|
if(GetPointsInRectangle(rHalfSegment, rectangle,
|
|
leftPoint, rightPoint))
|
|
{
|
|
double leftPointX = leftPoint.GetX();
|
|
double leftPointY = leftPoint.GetY();
|
|
double rightPointX = rightPoint.GetX();
|
|
double rightPointY = rightPoint.GetY();
|
|
|
|
if(IsHorizontalHalfSegment(halfSegment))
|
|
{
|
|
for(double x = leftPointX; x <= rightPointX; x += gridLength)
|
|
{
|
|
bHasTrueValue |= rtbool.SetValue(x, leftPointY, true, true);
|
|
}
|
|
}
|
|
|
|
else if(IsVerticalHalfSegment(halfSegment))
|
|
{
|
|
for(double y = leftPointY; y <= rightPointY; y += gridLength)
|
|
{
|
|
bHasTrueValue |= rtbool.SetValue(leftPointX, y, true, true);
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
double deltaX = lineEndPoint.GetX() - lineStartPoint.GetX();
|
|
double deltaY = lineEndPoint.GetY() - lineStartPoint.GetY();
|
|
double m = deltaY / deltaX;
|
|
double n = lineStartPoint.GetY() - m * lineStartPoint.GetX();
|
|
double step = (rightPointX - leftPointX) / xDimensionSize;
|
|
|
|
for(double x = leftPointX; x <= rightPointX; x += step)
|
|
{
|
|
double y = m * x + n;
|
|
bHasTrueValue |= rtbool.SetValue(x, y, true, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return bHasTrueValue;
|
|
}
|
|
|
|
/*
|
|
Method fromlineFunction implements the fromline operator functionality.
|
|
|
|
author: Dirk Zacher
|
|
parameters: pArguments - a pointer to the arguments of fromline operator
|
|
rResult - reference to a Word containing the result
|
|
message - message to distinguish call modes of fromlineFunction
|
|
rLocal - reference to a Word to store local method information
|
|
supplier - an Address to a supplier of information of operator tree
|
|
return value: 0 if fromlineFunction successfully executed,
|
|
YIELD if rResult contains a stream element (execution continued),
|
|
CANCEL if all stream elements of the result already returned,
|
|
FAILURE if an error occured
|
|
exceptions: -
|
|
|
|
*/
|
|
|
|
int fromlineFunction(Word* pArguments,
|
|
Word& rResult,
|
|
int message,
|
|
Word& rLocal,
|
|
Supplier supplier)
|
|
{
|
|
int nRetVal = FAILURE;
|
|
|
|
if(qp != 0 &&
|
|
pArguments != 0)
|
|
{
|
|
Line* pLine = static_cast<Line*>(pArguments[0].addr);
|
|
tgrid* pGrid = static_cast<tgrid*>(pArguments[1].addr);
|
|
|
|
if(pLine != 0 &&
|
|
pGrid != 0 &&
|
|
pLine->IsDefined() &&
|
|
pGrid->IsDefined())
|
|
{
|
|
struct ResultInfo
|
|
{
|
|
double m_dMinimumX;
|
|
double m_dMinimumY;
|
|
double m_dMaximumX;
|
|
double m_dMaximumY;
|
|
double m_dX;
|
|
double m_dY;
|
|
};
|
|
|
|
int xDimensionSize = tProperties<char>::GetXDimensionSize();
|
|
int yDimensionSize = tProperties<char>::GetYDimensionSize();
|
|
double gridX = pGrid->GetX();
|
|
double gridY = pGrid->GetY();
|
|
double gridLength = pGrid->GetLength();
|
|
|
|
switch(message)
|
|
{
|
|
case OPEN:
|
|
{
|
|
// initialize the local storage
|
|
ResultInfo* pResultInfo = new ResultInfo;
|
|
|
|
if(pResultInfo != 0)
|
|
{
|
|
Rectangle<2> boundingBox = pLine->BoundingBox();
|
|
pResultInfo->m_dMinimumX = boundingBox.MinD(0);
|
|
pResultInfo->m_dMinimumY = boundingBox.MinD(1);
|
|
pResultInfo->m_dMaximumX = boundingBox.MaxD(0);
|
|
pResultInfo->m_dMaximumY = boundingBox.MaxD(1);
|
|
|
|
double deltaX = pResultInfo->m_dMinimumX - gridX;
|
|
double tileSizeX = xDimensionSize * gridLength;
|
|
pResultInfo->m_dX = gridX + std::floor(deltaX / tileSizeX) *
|
|
tileSizeX;
|
|
|
|
double deltaY = pResultInfo->m_dMinimumY - gridY;
|
|
double tileSizeY = yDimensionSize * gridLength;
|
|
pResultInfo->m_dY = gridY + std::floor(deltaY / tileSizeY) *
|
|
tileSizeY;
|
|
|
|
rLocal.addr = pResultInfo;
|
|
nRetVal = 0;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case REQUEST:
|
|
{
|
|
if(rLocal.addr != 0)
|
|
{
|
|
ResultInfo* pResultInfo = static_cast<ResultInfo*>(rLocal.addr);
|
|
|
|
if(pResultInfo != 0)
|
|
{
|
|
if(pResultInfo->m_dX <= pResultInfo->m_dMaximumX ||
|
|
pResultInfo->m_dY <= pResultInfo->m_dMaximumY)
|
|
{
|
|
tbool* ptbool = new tbool(true);
|
|
|
|
if(ptbool != 0)
|
|
{
|
|
ptbool->SetValues(false, true);
|
|
bool bHasTrueValue = false;
|
|
|
|
do
|
|
{
|
|
ptbool->SetGrid(pResultInfo->m_dX,
|
|
pResultInfo->m_dY,
|
|
gridLength);
|
|
|
|
for(int i = 0; i < pLine->Size(); i++)
|
|
{
|
|
HalfSegment halfSegment;
|
|
pLine->Get(i, halfSegment);
|
|
bHasTrueValue |= SetLineValues(halfSegment, *ptbool);
|
|
}
|
|
|
|
pResultInfo->m_dX += xDimensionSize * gridLength;
|
|
|
|
if(pResultInfo->m_dX > pResultInfo->m_dMaximumX)
|
|
{
|
|
pResultInfo->m_dY += yDimensionSize * gridLength;
|
|
|
|
if(pResultInfo->m_dY <=
|
|
pResultInfo->m_dMaximumY)
|
|
{
|
|
double deltaX = pResultInfo->m_dMinimumX - gridX;
|
|
double tileSizeX = xDimensionSize * gridLength;
|
|
pResultInfo->m_dX = gridX +
|
|
std::floor(deltaX / tileSizeX) *
|
|
tileSizeX;
|
|
}
|
|
}
|
|
}
|
|
|
|
while(bHasTrueValue == false &&
|
|
pResultInfo->m_dX <= pResultInfo->m_dMaximumX &&
|
|
pResultInfo->m_dY <= pResultInfo->m_dMaximumY);
|
|
|
|
if(bHasTrueValue == true)
|
|
{
|
|
// return the next stream element
|
|
rResult.addr = ptbool;
|
|
nRetVal = YIELD;
|
|
}
|
|
|
|
else
|
|
{
|
|
delete ptbool;
|
|
ptbool = 0;
|
|
|
|
// always set the result to null before return CANCEL
|
|
rResult.addr = 0;
|
|
nRetVal = CANCEL;
|
|
}
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
// always set the result to null before return CANCEL
|
|
rResult.addr = 0;
|
|
nRetVal = CANCEL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CLOSE:
|
|
{
|
|
if(rLocal.addr != 0)
|
|
{
|
|
ResultInfo* pResultInfo = static_cast<ResultInfo*>(rLocal.addr);
|
|
|
|
if(pResultInfo != 0)
|
|
{
|
|
delete pResultInfo;
|
|
rLocal.addr = 0;
|
|
}
|
|
}
|
|
|
|
nRetVal = 0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
assert(false);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return nRetVal;
|
|
}
|
|
|
|
/*
|
|
Method fromlineTypeMappingFunction returns the return value type
|
|
of fromline operator in the form of a ListExpr.
|
|
|
|
author: Dirk Zacher
|
|
parameters: arguments - arguments of fromline operator
|
|
return value: return value type of fromline operator
|
|
exceptions: -
|
|
|
|
*/
|
|
|
|
ListExpr fromlineTypeMappingFunction(ListExpr arguments)
|
|
{
|
|
ListExpr type = NList::typeError("Operator fromline expects "
|
|
"a line and a tgrid.");
|
|
|
|
if(nl != 0)
|
|
{
|
|
NList argumentsList(arguments);
|
|
|
|
if(argumentsList.hasLength(2))
|
|
{
|
|
std::string argument1 = argumentsList.first().str();
|
|
std::string argument2 = argumentsList.second().str();
|
|
|
|
if(argument1 == Line::BasicType() &&
|
|
argument2 == tgrid::BasicType())
|
|
{
|
|
type = nl->TwoElemList(nl->SymbolAtom(Stream<tbool>::BasicType()),
|
|
nl->SymbolAtom(tbool::BasicType()));
|
|
}
|
|
}
|
|
}
|
|
|
|
return type;
|
|
}
|
|
|
|
}
|