Files
secondo/Algebras/MRegionOps2/SourceUnit2.cpp
2026-01-23 17:03:45 +08:00

568 lines
15 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2008, 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
----
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
//[TOC] [\tableofcontents]
//[ue] [\"u]
//[ae] [\"a]
//[oe] [\"o]
//[x] [$\times $]
//[->] [$\rightarrow $]
//[pow] [\verb+^+]
[1] Codefile of SourceUnit class
April - November 2008, M. H[oe]ger for bachelor thesis.
[2] Implementation with exakt dataype
Oktober 2014 - Maerz 2015, S. Schroeer for master thesis.
[TOC]
1 Introduction
2 Defines and Includes
*/
#include "SourceUnit2.h"
#include "PFace.h"
#include "SourceUnitPair2.h"
#include <stdlib.h>
using namespace std;
using namespace datetime;
namespace temporalalgebra {
namespace mregionops2 {
/***********************************
5 Class SourceUnit2
***********************************/
SourceUnit2::SourceUnit2(const bool _isUnitA,
MRegion2* const _mRegion,
const int _pos,
precTimeInterval _interval,
SourceUnitPair2* const _parent) :
isUnitA(_isUnitA),
pos(_pos),
mRegion(_mRegion),
interval(_interval),
parent(_parent)
{
myDebugId=0;
}
/***********************************
5.1 SourceUnit2::CreatePFaces()
***********************************/
void SourceUnit2::CreatePFaces() {
cout << "SourceUnit2::CreatePFaces 1" << endl;
URegionEmb2 uRegion;
MSegmentData2 segment, restrSegment;
MSegmentData2 dms;
PreciseMSegmentData pdms;
const DbArray<MSegmentData2>* segmentData = mRegion->GetMSegmentData2();
const DbArray<PreciseMSegmentData>* preciseSegmentData
= mRegion->GetPreciseMSegmentData();
const DbArray<int>* preciseCoordinates = mRegion->GetPreciseCoordinates();
URegionEmb2 ur;
// from MovingRegion3 include, it's another version as inside MovingRegion2
// in MovingRegion2 the sFac is 1
// reason: if scalefactor is different - OPEN what's to do?
// mpz_t sFactor;
// mpz_init(sFactor);
// uint sfactor;
// scalefactor for ganzzahligen Anteil
int sFac = mRegion->GetScaleFactor();
// old Segement URegion
Point2D old_is, old_ie, old_fs, old_fe;
// new Segment derURegion
Point2D new_is, new_ie, new_fs, new_fe;
// mRegion is a pointer to MRegion2
// pos = aPos or bPos
mRegion->Get(pos, uRegion);
// old Intervall
precTimeInterval told(uRegion.timeInterval, uRegion.pInterval,
mRegion->GetPreciseInstants());
// new Intervall
precTimeInterval tnew = interval;
// all segments from uregion
for (int i = 0; i < uRegion.GetSegmentsNum(); i++)
{
cout << "SourceUnit2::Segmente der Uregion i - Segment "
<< i << " " << uRegion.GetSegmentsNum() << endl;
uRegion.GetSegment(segmentData, i, dms);
uRegion.GetPreciseSegment(preciseSegmentData, i, pdms);
unsigned int cycleNo = dms.GetCycleNo();
unsigned int faceNo = dms.GetFaceNo();
SetCycleStatus(faceNo, cycleNo, NOTYETKNOWN);
// one mregion in use
// store pfaces in datastructure
// preciseSegmentData Nachkommaanteil
// MSegmentData2 Vorkommaanteile
// exakt points for old points
mpq_class isx = dms.GetInitialStartX()
+ pdms.GetInitialStartX(preciseCoordinates);
mpq_class isy = dms.GetInitialStartY()
+ pdms.GetInitialStartY(preciseCoordinates);
mpq_class iex = dms.GetInitialEndX()
+ pdms.GetInitialEndX(preciseCoordinates);
mpq_class iey = dms.GetInitialEndY()
+ pdms.GetInitialEndY(preciseCoordinates);
mpq_class fsx = dms.GetFinalStartX()
+ pdms.GetFinalStartX(preciseCoordinates);
mpq_class fsy = dms.GetFinalStartY()
+ pdms.GetFinalStartY(preciseCoordinates);
mpq_class fex = dms.GetFinalEndX()
+ pdms.GetFinalEndX(preciseCoordinates);
mpq_class fey = dms.GetFinalEndY()
+ pdms.GetFinalEndY(preciseCoordinates);
isx = isx * sFac;
isy = isy * sFac;
iex = iex * sFac;
iey = iey * sFac;
fsx = fsx * sFac;
fsy = fsy * sFac;
fex = fex * sFac;
fey = fey * sFac;
//
// old Segement URegion
// old_is, old_ie, old_fs, old_fe;
//
old_is = Point2D(isx, isy);
old_ie = Point2D(iex, iey);
old_fs = Point2D(fsx, fsy);
old_fe = Point2D(fex, fey);
if (told.start == tnew.start)
{
new_is = old_is;
new_ie = old_ie;
}
else if (told.end == tnew.start)
{
new_is = old_fs;
new_ie = old_fe;
}
else
{
mpq_class ratio = (tnew.start - told.start) / (told.end - told.start);
new_is = Point2D(old_is, old_fs, ratio);
new_ie = Point2D(old_ie, old_fe, ratio);
}
if (told.start == tnew.end)
{
new_fs = old_is;
new_fe = old_ie;
}
else if (told.end == tnew.end)
{
new_fs = old_fs;
new_fe = old_fe;
}
else
{
mpq_class ratio = (tnew.end - told.start) / (told.end - told.start);
new_fs = Point2D(old_is, old_fs, ratio);
new_fe = Point2D(old_ie, old_fe, ratio);
}
PFace* pFace = new PFace(this, new_is, new_ie,
new_fs, new_fe, dms.GetInsideAbove(),
cycleNo, faceNo);
pFace->SetDebugId(myDebugId++);
pFaces.push_back(pFace);
}
}
void SourceUnit2::AddTimestamp(mpq_class tim) {
parent->AddTimestamp(tim);
}
unsigned int SourceUnit2::GetTimeIntervalCount() {
return parent->GetTimeIntervalCount();
}
mpq_class SourceUnit2::GetTimeIntervalStart(unsigned int i) {
return parent->GetTimeIntervalStart(i);
}
mpq_class SourceUnit2::GetTimeIntervalEnd(unsigned int i) {
return parent->GetTimeIntervalEnd(i);
}
void SourceUnit2::SetCycleStatus(unsigned int pfaceNo,
unsigned int cycleNo,
CycleStatus stat)
{
// if entry with key exist actualize status
// else insert neu CyleInfo
std::pair<unsigned int, unsigned int> key(pfaceNo, cycleNo);
std::map<std::pair<unsigned int, unsigned int>, CycleInfo*>::iterator it;
it = cycleInfo.find(key);
if (it == cycleInfo.end()) {
cout << "insert new" << endl;
CycleInfo* newentry = new CycleInfo();
newentry->status = stat;
cycleInfo.insert(std::pair<std::pair<unsigned int,
unsigned int>,
CycleInfo*>(key, newentry ));
}
else
{
cout << "actualize status" << endl;
it->second->status = stat;
}
}
void SourceUnit2::FinalizeIntSegs()
{
std::vector<PFace*>::iterator iter;
for (iter = pFaces.begin(); iter != pFaces.end(); iter++)
{
(*iter)->FinalizeIntSegs();
}
}
SourceUnit2::~SourceUnit2() {
vector<PFace*>::iterator iter;
for (iter = pFaces.begin(); iter != pFaces.end(); iter++) {
delete *iter;
}
}
const SetOp SourceUnit2::GetOperation() const {
return parent->GetOperation();
}
void SourceUnit2::CollectRelevantPFaces(vector<PFace*>* storage)
{
string mystring; //just for stopping the console, debugging
cout << "SourceUnit2::CollectRelevantPFaces started for operation: ";
switch(GetOperation())
{
case INTERSECTION: cout << "INTERSECTION/Schnittmenge\n"; break;
case UNION: cout << "UNION/Vereinigung\n"; break;
case MINUS: cout << "MINUS\n"; break;
case INSIDE: cout << "INSIDE\n"; break;
case INTERSECT: cout << "INTERSECT\n"; break;
}
vector<PFace*>::iterator iter;
for (iter = pFaces.begin(); iter != pFaces.end(); iter++)
{
//(*iter)->Print();
switch(GetOperation())
{
case INTERSECTION:
cout << "INTERSECTION/Schnittmenge\n";
if((*iter)->HasIntersegs() == true)
{
cout << "PFace has intersegs --> is relevant\n";
storage->push_back(*iter);
}
else
{
if(IsPFaceInsidePartner(*iter)==true)
{
storage->push_back(*iter);
}
//else
}
break;
case UNION:
if((*iter)->HasIntersegs() == false && IsPFaceInsidePartner(*iter)==false)
{
storage->push_back(*iter);
}
else if ((*iter)->HasIntersegs() == true)
{
cout << "PFace has intersegs --> is relevant\n";
storage->push_back(*iter);
}
else
break;
case MINUS:
if(IsUnitA()==true && (*iter)->HasIntersegs() == false)
{
storage->push_back(*iter);
}
if(IsUnitB()==true)
{
if ((*iter)->HasIntersegs() == true)
{
storage->push_back(*iter);
}
else
{
if(IsPFaceInsidePartner(*iter)==true)
{
storage->push_back(*iter);
}
else
{
}
}
}
}
}
for (iter = pFaces.begin(); iter != pFaces.end(); iter++)
{
//is pface in map?
std::pair<unsigned int, unsigned int> key((*iter)->Get_faceNo(),
(*iter)->Get_cycleNo());
std::map<std::pair<unsigned int, unsigned int>, CycleInfo*>::iterator it;
it = cycleInfo.find(key);
if (it != cycleInfo.end())
{
}
else
{
}
}
// show content:
std::map<std::pair<unsigned int, unsigned int>, CycleInfo*>::iterator it;
for (it = cycleInfo.begin(); it != cycleInfo.end(); ++it)
{
}
cout << "SourceUnit2::CollectRelevantPFaces finished" << endl;
}
bool SourceUnit2::IsPFaceInsidePartner(PFace* pface)
{
//cout << "IsPFaceInsidePartner()\n";
bool result = false;
if(IsUnitA())
cout << "i'm A -> ";
else
cout << "i'm B -> ";
SourceUnit2* partner = GetPartner();
if(partner->IsUnitA())
cout << "and my partner is A\n";
else
cout << "and my partner is B\n";
//startpoint instead MidPoint, because intersection exist
const Point3D p = pface->GetA_XYT();
const Point p2D(true, p.GetX().get_d(), p.GetY().get_d());
if(IsUnitA()==true && partner->IsUnitB()==true)
;
else if(IsUnitB()==true && partner->IsUnitA()==true)
;
else
cout << "You should never see this message!\n";
cout << "Partner Unit has " << partner->GetPFaceCount() << " pFaces\n";
vector<PFace*> pFacesOfPartner = partner->GetPFaces();
int polygonCorners = partner->GetPFaceCount();
int cornerIndex = 0;
float polyX[polygonCorners];
float polyY[polygonCorners];
vector<PFace*>::iterator iter;
for (iter = partner->pFaces.begin(); iter != partner->pFaces.end(); iter++)
{
Point3D startPoint = (*iter)->GetA_XYT();
polyX[cornerIndex] = (float)startPoint.GetX().get_d();
polyY[cornerIndex] = (float)startPoint.GetY().get_d();
cornerIndex++;
}
result =pointInPolygon(polyX,polyY,(float)p.GetX().get_d(),
(float)p.GetY().get_d(), polygonCorners);
if (result == true)
cout << "point is INSIDE of partner unit\n";
else
cout << "point is OUTSIDE of partner unit\n";
return result;
}
//http://alienryderflex.com/polygon/
bool SourceUnit2::pointInPolygon(float polyX[],float polyY[],float x,
float y, int polyCorners)
{
int i, j=polyCorners-1 ;
bool oddNodes=false ;
for (i=0; i<polyCorners; i++) {
if ((polyY[i]< y && polyY[j]>=y
|| polyY[j]< y && polyY[i]>=y)
&& (polyX[i]<=x || polyX[j]<=x)) {
oddNodes^=(polyX[i]+(y-polyY[i])/(polyY[j]-polyY[i])*(polyX[j]-polyX[i])<x); }
j=i; }
return oddNodes; }
bool SourceUnit2::HasIntersecs()
{
bool result =false;
vector<PFace*>::iterator iter;
for (iter = pFaces.begin(); iter != pFaces.end(); iter++)
{
if((*iter)->HasIntersegs() == true)
{
result=true;
break;
}
}
return result;
}
bool SourceUnit2::IsInsidePartner()
{
bool result =true;
vector<PFace*>::iterator iter;
for (iter = pFaces.begin(); iter != pFaces.end(); iter++)
{
if(IsPFaceInsidePartner(*iter)==false)
{
result=false;
break;
}
}
return result;
}
/***********************************
5.1 SourceUnit2::PrintPFaces()
***********************************/
void SourceUnit2::PrintPFaces()
{
cout << "inside PrintPFaces " << endl;
for (vector<PFace*>::iterator iter = pFaces.begin();
iter != pFaces.end(); iter++) {
(*iter)->Print();
}
}
SourceUnit2* SourceUnit2::GetPartner()
{
return partner;
}
int SourceUnit2::GetPFaceCount()
{
return pFaces.size();
}
vector<PFace*> SourceUnit2::GetPFaces()
{
return pFaces;
}
void SourceUnit2::AddToMRegion(MRegion2* const target) {
if (IsEmpty())
return;
DbArray<MSegmentData>* targetArray = (DbArray<MSegmentData>*)target->GetFLOB(1);
const int segmentsStartPos = targetArray->Size();
precTimeInterval tmp = GetTimeInterval();
Instant starttime(instanttype);
Instant endtime(instanttype);
starttime.ReadFrom(tmp.start.get_d());
endtime.ReadFrom(tmp.end.get_d());
const Interval<Instant> interval(starttime, endtime, true, false);
URegionEmb targetUnit(interval, segmentsStartPos);
MSegmentData segment;
URegionEmb2 ur;
mRegion->Get(0, ur);
for (int i = 0; i < ur.GetSegmentsNum(); i++)
{
cout << "AddToMRegion() index:" << i << endl;
// uRegion->GetSegment(array, i, segment);
// targetUnit.PutSegment(targetArray, i, segment, true);
}
target->Add(ur);
}
}
}