/* ---- 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 $] [1] Implementation of the MRegionOps3Algebra April - November 2008, M. H[oe]ger for bachelor thesis. Mai - November 2017, U. Wiesecke for master thesis. [TOC] 1 Introduction 2 Defines and Includes */ #include "SetOps.h" using namespace std; namespace temporalalgebra { namespace mregionops3 { /* 3 Enumeration 4 Class RationalPoint3DExt */ RationalPoint3DExt::RationalPoint3DExt():RationalPoint3D(){ }// Konstruktor RationalPoint3DExt::RationalPoint3DExt(const mpq_class& a, const mpq_class& b, const mpq_class& c, SourceFlag _sourceFlag): RationalPoint3D(a,b,c),sourceFlag(_sourceFlag){ }// Konstruktor void RationalPoint3DExt::setSourceFlag(SourceFlag flag){ this->sourceFlag = flag; }// setSourceFlag SourceFlag RationalPoint3DExt::getSourceFlag()const{ return this->sourceFlag; }// getSourceFlag bool RationalPoint3DExt::operator < (const RationalPoint3DExt& point)const{ if (NumericUtil::lower(this->x, point.x)) return true; if (NumericUtil::greater(this->x,point.x)) return false; if (NumericUtil::lower(this->y, point.y)) return true; if (NumericUtil::greater(this->y,point.y)) return false; if (NumericUtil::lower(this->z, point.z)) return true; if (NumericUtil::greater(this->z,point.z)) return false; return this->sourceFlag < point.sourceFlag; }// Operator < std::ostream& operator <<(std::ostream& os, const RationalPoint3DExt& point){ os << "RationalPoint3DExt(" << point.x.get_d(); os << ", " << point.y.get_d(); os << ", " << point.z.get_d() <<", "; if (point.sourceFlag == UNIT_A) os << "UNIT_A)"; else os << "UNIT_B)"; return os; }// operator << /* 5 Class RationalPoint3DExtSet */ RationalPoint3DExtSet::RationalPoint3DExtSet(){ }// Konstruktor void RationalPoint3DExtSet::insert(const RationalPoint3DExt& point){ this->points.insert(point); }// insert size_t RationalPoint3DExtSet::size() const{ return this->points.size(); }// size bool RationalPoint3DExtSet::getIntersectionSegment( RationalSegment3D& result)const{ // cout << *this << endl; if (this->points.size() != 4) return false; set::iterator it = this->points.begin(); RationalPoint3DExt point1 = *it; it++; RationalPoint3DExt point2 = *it; if (point1.getSourceFlag() == point2.getSourceFlag()) return false; it++; RationalPoint3DExt point3 = *it; if (point2 == point3) { // The length of the intersection segment is zero. return false; }// if result = RationalSegment3D(point2, point3); return true; }// getIntersectionSegment std::ostream& operator <<(std::ostream& os, const RationalPoint3DExtSet& points){ return points.print(os,""); }// operator << std::ostream& RationalPoint3DExtSet::print(std::ostream& os, std::string prefix)const{ set::const_iterator iter; os << "RationalPoint3DExtSet(" << endl; for (iter = points.begin(); iter != points.end(); ++iter) { os << prefix << " " << *iter << endl; }// for os << prefix << ")" << endl; return os; }// print /* 6 Class RationalPlane3D */ RationalPlane3D::RationalPlane3D():normalVector(),pointOnPlane(){ }// Konstruktor RationalPlane3D::RationalPlane3D(const RationalPlane3D& plane){ set(plane); }// konstruktor RationalPlane3D::RationalPlane3D(const PFace& pf){ RationalPoint3D leftStart = pf.getLeftStart().getR(); RationalPoint3D leftEnd = pf.getLeftEnd().getR(); RationalPoint3D rightStart= pf.getRightStart().getR(); RationalPoint3D rightEnd = pf.getRightEnd().getR(); this->pointOnPlane = leftStart; // We compute the normalvector if(rightStart.distance(leftStart) > rightEnd.distance(leftEnd)){ // Cross product of vector ab and ac this->normalVector = (rightStart - leftStart) ^ (leftEnd - leftStart); // check point d on plane if (!NumericUtil::nearlyEqual(distance2ToPlane(rightEnd), 0.0, NumericUtil::eps * NumericUtil::epsRelaxFactor)) { cerr << "Distance" << distance2ToPlane(rightEnd).get_d() << endl; cerr << *this << endl; cerr << pf <normalVector = (leftEnd - rightEnd) ^ (rightStart - rightEnd); }// else this->normalVector.normalize(); // The vector w is either the normalized cross product // of the normal vector and the t-unit-vector, or it's opposite. // This depends on the kind of set-operation, we want to perform. // // wVector = Vector3D(normalVector() ^ Vector3D(0.0, 0.0, -1.0); // wVector.normalize(); // This can be simplified to: this->wVector = RationalVector3D( - normalVector.getY(), normalVector.getX(), 0.0); this->wVector.normalize(); }// Konstruktor void RationalPlane3D::set(const RationalPlane3D& plane){ this->normalVector = plane.normalVector; this->pointOnPlane = plane.pointOnPlane; this->wVector = plane.wVector; }// set void RationalPlane3D::set(const RationalVector3D& normalVector, const RationalPoint3D& pointOnPlane){ this->normalVector = normalVector; this->pointOnPlane = pointOnPlane; this->wVector = RationalVector3D( - normalVector.getY(), normalVector.getX(), 0.0); this->wVector.normalize(); }// set RationalPoint3D RationalPlane3D::getPointOnPlane() const{ return this->pointOnPlane; }// getPointOnPlane RationalVector3D RationalPlane3D::getNormalVector() const{ return this->normalVector; }// getNormalVector mpq_class RationalPlane3D::distance2ToPlane(const RationalPoint3D& point) const{ mpq_class n = - (this->normalVector * (point - this->pointOnPlane)); mpq_class d = this->normalVector * this->normalVector; if (NumericUtil::nearlyEqual(d,0.0)) NUM_FAIL("Normalvector is zerro."); mpq_class b = n / d; RationalPoint3D result = point + b * this->normalVector; return result.distance2(point); }// distance2ToPlane bool RationalPlane3D::isParallelTo(const RationalPlane3D& plane) const{ RationalVector3D cross = this->normalVector ^ plane.normalVector; return NumericUtil::nearlyEqual(cross.length2(),0.0); }// isParallelTo bool RationalPlane3D::isCoplanarTo(const RationalPlane3D& plane) const{ return NumericUtil::nearlyEqual(distance2ToPlane(plane.pointOnPlane), 0.0); }// isCoplanarTo bool RationalPlane3D::intersection(const Segment3D segment, RationalPoint3D& result)const{ RationalPoint3D head = segment.getHead(); RationalPoint3D tail = segment.getTail(); mpq_class d0 = head.distance2(tail); mpq_class d1 = distance2ToPlane(head); mpq_class d2 = distance2ToPlane(tail); if(d0 > 1) { d1 = d1/d0; d2 = d2/d0; }// if // do not evaluate a segment that is parallel to the plane if(NumericUtil::nearlyEqual(d1, 0, NumericUtil::eps * NumericUtil::epsRelaxFactor) && NumericUtil::nearlyEqual(d2, 0, NumericUtil::eps * NumericUtil::epsRelaxFactor))return false; // We compute the intersection point of the plane // - defined by the PFace - and the segment. RationalVector3D u = head - tail; RationalVector3D w = tail - this->pointOnPlane; mpq_class d = this->normalVector * u; mpq_class n = - this->normalVector * w; // Segment is parallel to plane ? if (NumericUtil::nearlyEqual(d, 0.0)) return false; mpq_class s = n / d; // No intersection point, if s < -eps or s > 1 + eps. if (NumericUtil::lower(s, 0.0) || NumericUtil::greater(s, 1.0)) return false; // Compute segment intersection point result = tail + s * u; // cout << result; return true; }// intersection RationalPlane3D& RationalPlane3D::operator =(const RationalPlane3D& plane){ set(plane); return *this; }// Operator = std::ostream& operator <<(std::ostream& os, const RationalPlane3D& plane){ os << "RationalPlane3D("<< plane.normalVector << ", "; os << plane.pointOnPlane <<")"; return os; }// operator << void RationalPlane3D::intersection(const PFace& other, SourceFlag sourceFlag, RationalPoint3DExtSet& intPointSet)const{ Point3D leftStart = other.getLeftStart(); Point3D leftEnd = other.getLeftEnd(); Point3D rightStart = other.getRightStart(); Point3D rightEnd = other.getRightEnd(); RationalPoint3DExt intPoint; vector edgesPFace; // We store all edges of this PFace as 3DSegments in the vector // edgesPFace. edgesPFace.push_back(Segment3D(leftStart, leftEnd)); edgesPFace.push_back(Segment3D(rightStart, rightEnd)); if (leftStart != rightStart) { edgesPFace.push_back(Segment3D(leftStart,rightStart)); }// if if (leftEnd != rightEnd) { edgesPFace.push_back(Segment3D(leftEnd,rightEnd)); }// if // Intersect the plane - defined by the other PFace - // with all edges of this PFace: RationalPoint3DExt temp; for (size_t i = 0, j = 0 ; i < edgesPFace.size();i++) { if (intersection(edgesPFace[i], intPoint)) { intPoint.setSourceFlag(sourceFlag); intPointSet.insert(intPoint); if (j == 0) { temp = intPoint; j++; }// if else if (!(temp == intPoint)){ j++; }// else if }// if }// for }// intersection bool RationalPlane3D::isLeftSideInner(const RationalSegment3D segment, const RationalPlane3D other)const{ RationalVector3D segmentVector(segment.getHead() - segment.getTail()); segmentVector.normalize(); RationalVector3D vector = this->normalVector ^ segmentVector; if (NumericUtil::greater(vector * other.normalVector, 0)){ return false; }// if return true; }// isLeftAreaInner RationalPoint2D RationalPlane3D::transform( const RationalPoint3D& point) const{ // check point d on plane if (!NumericUtil::nearlyEqual(distance2ToPlane(point),0.0, NumericUtil::eps * NumericUtil::epsRelaxFactor)) { cerr << setprecision(14); cerr << "Distance to plane " << distance2ToPlane(point).get_d() << endl; NUM_FAIL("Point isn't located on plane."); }// if mpq_class w = point.getX() * wVector.getX() + point.getY() * wVector.getY(); return RationalPoint2D(w,point.getZ()); }// transform RationalSegment2D RationalPlane3D::transform( const RationalSegment3D& segment) const{ return RationalSegment2D(transform(segment.getTail()), transform(segment.getHead())); }// transform void RationalPlane3D::transform( const vector& segment3D, vector& segment2D) const{ for(size_t i = 0; i < segment3D.size(); i++){ segment2D.push_back(transform(segment3D[i])); }// for }// transform /* 7 Class IntersectionPoint */ IntersectionPoint::IntersectionPoint():x(0),y(0),z(0),w(0){ }// Konstruktor IntersectionPoint::IntersectionPoint(const IntersectionPoint& point){ set(point); }// Konstruktor IntersectionPoint::IntersectionPoint(const RationalPoint3D& point3D, const RationalPoint2D& point2D){ if (!NumericUtil::nearlyEqual(point3D.getZ(), point2D.getY())) { cerr << "RationalPoint3D:=" << point3D << endl; cerr << "RationalPoint2D:=" << point2D << endl; NUM_FAIL("Point3D and Point2D don't discribe the same."); }// if this->x = point3D.getX(); this->y = point3D.getY(); this->z = point3D.getZ(); this->w = point2D.getX(); }// Konstruktor IntersectionPoint::IntersectionPoint(mpq_class x, mpq_class y, mpq_class z, mpq_class w){ this->x = x; this->y = y; this->z = z; this->w = w; }// Konstruktor void IntersectionPoint::set(const IntersectionPoint& point){ this->x = point.x; this->y = point.y; this->z = point.z; this->w = point.w; }// set RationalPoint3D IntersectionPoint::getRationalPoint3D() const{ return RationalPoint3D(x,y,z); }// getPoint3D RationalPoint2D IntersectionPoint::getRationalPoint2D() const{ return RationalPoint2D(w,z); }// getPoint2D mpq_class IntersectionPoint::getX()const{ return x; }// getX mpq_class IntersectionPoint::getY()const{ return y; }// getY mpq_class IntersectionPoint::getZ()const{ return z; }// getZ mpq_class IntersectionPoint::getW()const{ return w; }// getW mpq_class IntersectionPoint::getT()const{ return z; }// getT Rectangle<3> IntersectionPoint::getBoundingBox()const{ double array[3] = {x.get_d(),y.get_d(),z.get_d()}; return Rectangle<3>(true,array,array); }// getBoundingBox std::ostream& operator <<(std::ostream& os, const IntersectionPoint& point){ os << "IntersectionPoint("; os << point.x.get_d() << ", " << point.y.get_d() << ", "; os << point.z.get_d() << ", " << point.w.get_d() << ")"; return os; }// OPerator << IntersectionPoint& IntersectionPoint::operator =( const IntersectionPoint& point){ set(point); return *this; }// Operator = bool IntersectionPoint::operator ==(const IntersectionPoint& point) const{ return NumericUtil::nearlyEqual(this->x, point.x) && NumericUtil::nearlyEqual(this->y, point.y) && NumericUtil::nearlyEqual(this->z, point.z) && NumericUtil::nearlyEqual(this->w, point.w); }// Operator == /* 8 Class IntersectionSegment */ IntersectionSegment::IntersectionSegment(){ this->predicate = UNDEFINED; }// Konstruktor IntersectionSegment::IntersectionSegment( const IntersectionSegment& segment){ set(segment); }// konstruktor IntersectionSegment::IntersectionSegment( const IntersectionPoint& tail, const IntersectionPoint& head, const Predicate& predicate /* = UNDEFINED */){ set(tail,head,predicate); }// konstruktor IntersectionSegment::IntersectionSegment( const RationalSegment3D& segment3D, const RationalSegment2D& segment2D, const Predicate& predicate /* = UNDEFINED */){ IntersectionPoint tail(segment3D.getTail(),segment2D.getTail()); IntersectionPoint head(segment3D.getHead(),segment2D.getHead()); set(tail,head,predicate); }// Konstruktor void IntersectionSegment::set( const IntersectionPoint& tail, const IntersectionPoint& head, const Predicate& predicate){ if ((NumericUtil::lower(tail.getT(), head.getT())) || (NumericUtil::nearlyEqual(tail.getT(), head.getT()) && NumericUtil::lower(tail.getW(), head.getW()))) { this->tail = tail; this->head = head; this->predicate = predicate; }// if else { this->tail = head; this->head = tail; if(predicate == LEFT_IS_INNER) this->predicate = RIGHT_IS_INNER; else if (predicate == RIGHT_IS_INNER) this->predicate = LEFT_IS_INNER; else this->predicate = predicate; }// else }// set void IntersectionSegment::set(const IntersectionSegment& segment){ this->tail = segment.tail; this->head = segment.head; this->predicate = segment.predicate; }// set RationalSegment3D IntersectionSegment::getRationalSegment3D()const{ return Segment3D(tail.getRationalPoint3D().getD(), head.getRationalPoint3D()); }// getSegment3D RationalSegment2D IntersectionSegment::getRationalSegment2D()const{ return Segment2D(tail.getRationalPoint2D().getD(), head.getRationalPoint2D()); }// getSegment2D IntersectionPoint IntersectionSegment::getTail() const{ return tail; }// getTail IntersectionPoint IntersectionSegment::getHead() const{ return head; }// getHead Predicate IntersectionSegment::getPredicate()const{ return predicate; }// getSegment3D bool IntersectionSegment::isOrthogonalToTAxis()const{ return NumericUtil::nearlyEqual(tail.getT(),head.getT()); }// isOrthogonalToTAxis bool IntersectionSegment::isOutOfRange(mpq_class t)const{ if (NumericUtil::lower(this->head.getT(),t)) return true; return NumericUtil::nearlyEqual(this->head.getT(),t); }// isOutOfRange bool IntersectionSegment::isLeftOf(const IntersectionSegment& intSeg)const{ mpq_class tail1T = this->getTail().getT(); mpq_class head2T = intSeg.getHead().getT(); mpq_class tail2T = intSeg.getTail().getT(); // Precondition: // this->getTail().getT() is inside the interval // [intSeg.getTail().getT(), intSeg.getHead().getT()] // and this and intSeg don't intersect in their interior. if (NumericUtil::nearlyEqual(tail2T, head2T)){ mpq_class head1W = this->getHead().getW(); mpq_class tail1W = this->getTail().getW(); mpq_class tail2W = intSeg.getTail().getW(); if (NumericUtil::nearlyEqual(tail1T, tail2T)){ if( NumericUtil::lower(tail2W, tail1W)) return false; else return true; }// if else { if( NumericUtil::lower(tail2W, head1W)) return false; else return true; }// else }// if if (NumericUtil::lower(tail1T,tail2T) || NumericUtil::greater(tail1T,head2T)) { cerr << "this:=" << *this << endl; cerr << "other:=" << intSeg << endl; cerr << "tail2T:=" << tail2T << endl; cerr << "tail1T:=" << tail1T << endl; cerr << "head2T:=" << head2T << endl; NUM_FAIL ("t must between the t value form tail und haed."); }// if RationalSegment2D segment2D1 = this->getRationalSegment2D(); RationalSegment2D segment2D2 = intSeg.getRationalSegment2D(); mpq_class sideOfStart = segment2D2.whichSide(segment2D1.getTail()); if (sideOfStart > NumericUtil::eps) return true; if (sideOfStart < - NumericUtil::eps) return false; mpq_class sideOfEnd = segment2D2.whichSide(segment2D1.getHead()); return sideOfEnd > NumericUtil::eps; }// bool RationalPoint3D IntersectionSegment::evaluate(mpq_class t) const { mpq_class headT = this->getHead().getT(); mpq_class tailT = this->getTail().getT(); RationalPoint3D head3D = head.getRationalPoint3D(); RationalPoint3D tail3D = tail.getRationalPoint3D(); // Precondition: // t is between t on tail and haed if(!(NumericUtil::between(tailT, t, headT))){ cerr << "this:=" << *this << endl; cerr << "tailT:=" << tailT.get_d() << endl; cerr << "t:=" << t.get_d() << endl; cerr << "headT:=" << headT.get_d() << endl; NUM_FAIL ("t must between the t value form tail und haed."); }// if if (NumericUtil::nearlyEqual(t, headT)) return head3D; if (NumericUtil::nearlyEqual(t, tailT)) return tail3D; // Point3D pointInPlane(0.0, 0.0, t); // Vector3D normalVectorOfPlane(0.0, 0.0, 1.0); // Vector3D u = this->getHead().getPoint3D() - // this->getTail().getPoint3D(); // Vector3D w = this->getTail().getPoint3D() - pointInPlane; // double d = normalVectorOfPlane * u; // double n = -normalVectorOfPlane * w; // // This can be simplified to: RationalVector3D u = head3D - tail3D; mpq_class d = mpq_class(headT) - tailT; mpq_class n = mpq_class(t) - tailT; // this segment must not be parallel to plane if (NumericUtil::nearlyEqual(d, 0.0)) { NUM_FAIL ("Intersection segment must not be parallel to plane."); }// if mpq_class s = n/d; if (!(NumericUtil::between(0.0, s, 1.0))) { NUM_FAIL ("No point on segment found."); }// if // compute segment intersection point return (tail3D + s * u); }// evaluate std::ostream& operator <<( std::ostream& os, const IntersectionSegment& segment){ os << "IntersectionSegment(" << segment.tail << ", " << segment.head; os << ", " << toString(segment.getPredicate()); os << ")"; return os; }// Operator << IntersectionSegment& IntersectionSegment::operator =( const IntersectionSegment& segment){ set(segment); return *this; }// OPerator = bool IntersectionSegment::operator ==( const IntersectionSegment& segment) const{ return this->head == segment.head && this->tail == segment.tail && this->predicate == segment.predicate; }// Operator == /* 9 Struct IntSegCompare */ bool IntSegCompare::operator()(const IntersectionSegment* const& segment1, const IntersectionSegment* const& segment2) const{ IntersectionPoint tail1 = segment1->getTail(); IntersectionPoint tail2 = segment2->getTail(); IntersectionPoint head1 = segment1->getHead(); IntersectionPoint head2 = segment2->getHead(); // We sort by (t_start, w_start, IsLeft()) // Precondition: tail1.getT() < haed1.getT() && // tail2.getT() < head2.getT() if (NumericUtil::lower( tail1.getT(), tail2.getT())) return true; if (NumericUtil::greater(tail1.getT(), tail2.getT())) return false; // tail1.getT() == tail2.getT() if (NumericUtil::lower( tail1.getW(), tail2.getW())) return true; if (NumericUtil::greater(tail1.getW(), tail2.getW())) return false; // tail1.getW() == tail2.GetW() if (segment2->getRationalSegment2D().isLeft(head1.getRationalPoint2D())) return true; if (segment1->getRationalSegment2D().isLeft(head2.getRationalPoint2D())) return false; // segment1 is collinear to segment2 if (NumericUtil::lower( head1.getT(), head2.getT())) return false; if (NumericUtil::greater(head1.getT(), head2.getT())) return true; // head1.getT() == head2.getT(), head1.getW() == head2.getW() if(segment1->getPredicate() < segment2->getPredicate()) return true; return false; }// IntSegCompare /* 10 Class PlaneSweepAccess */ void PlaneSweepAccess::first(mpq_class t1, mpq_class t2, Point3DContainer& points, SegmentContainer& segments, bool pFaceIsCritical){ NUM_FAIL ("method must override."); }// first void PlaneSweepAccess::next(mpq_class t1, mpq_class t2, Point3DContainer& points, SegmentContainer& segments, bool pFaceIsCritical){ NUM_FAIL ("method must override."); }// next PlaneSweepAccess::~PlaneSweepAccess(){ }// Destruktor /* 11 class IntSegContainer */ IntSegContainer::IntSegContainer(){ }// Konstruktor IntSegContainer::IntSegContainer(const IntSegContainer& container){ set(container); }// Konstruktor IntSegContainer::~IntSegContainer(){ std::set::iterator iter; for (iter = intSegs.begin(); iter != intSegs.end(); ++iter) { delete *iter; }// for }// Destruktor void IntSegContainer::set(const IntSegContainer& container){ std::set::iterator iter; for (iter = intSegs.begin(); iter != intSegs.end(); ++iter) { delete *iter; }// form this->intSegs = std::set(); this->active = std::list(); for (iter = container.intSegs.begin(); iter != container.intSegs.end(); ++iter) { this->intSegs.insert(new IntersectionSegment(**iter)); }// for }// set void IntSegContainer::addIntSeg(const IntersectionSegment& seg){ intSegs.insert(new IntersectionSegment(seg)); }// addIntSeg size_t IntSegContainer::size()const{ return intSegs.size(); }// size std::ostream& operator <<(std::ostream& os, const IntSegContainer& container){ return container.print(os,""); }// operator std::ostream& IntSegContainer::print(std::ostream& os, std::string prefix)const{ os << "IntSegContainer("; if (intSegs.empty()) os << "is empty)" << endl; else { std::set::iterator iter; for (iter = intSegs.begin(); iter != intSegs.end(); ++iter) { os << endl << prefix + " " << *(*iter); }// for os << endl << prefix << ")" <intSegs.size() != container.intSegs.size()) return false; std::set::iterator iter1, iter2; for (iter1 = this->intSegs.begin(), iter2 = container.intSegs.begin(); iter1 != this->intSegs.end() && iter2 != container.intSegs.end(); ++iter1, ++iter2) { if(!(*(*iter1) == *(*iter2))) return false; }// for return true; }// Operator == IntSegContainer& IntSegContainer::operator =( const IntSegContainer& container){ set(container); return *this; }// Operator = bool IntSegContainer::hasMoreSegsToInsert(mpq_class t)const{ if (intSegIter == intSegs.end()) return false; IntersectionPoint tail((*intSegIter)->getTail()); return NumericUtil::nearlyEqual(tail.getT(),t); }// hasMoreSegsToInsert void IntSegContainer::first(mpq_class t1, mpq_class t2, Point3DContainer& points, SegmentContainer& segments, bool pFaceIsCritical){ intSegIter = intSegs.begin(); next(t1,t2,points,segments,pFaceIsCritical); }// first void IntSegContainer::next(mpq_class t1, mpq_class t2, Point3DContainer& points, SegmentContainer& segments, bool pFaceIsCritical){ list::iterator activeIter; activeIter = active.begin(); while (activeIter != active.end()){ while (activeIter != active.end() && (*activeIter)->isOutOfRange(t1)){ activeIter = active.erase(activeIter); }// while if (activeIter == active.end()) break; if (hasMoreSegsToInsert(t1)) { IntersectionSegment* newSeg = *intSegIter; if (newSeg->isLeftOf(**activeIter)) { activeIter = active.insert(activeIter, newSeg); intSegIter++; }// if }// if activeIter++; }// while // Add the tail, if there is one: while (hasMoreSegsToInsert(t1)) { IntersectionSegment* newSeg = *intSegIter; activeIter = active.insert(activeIter, newSeg); intSegIter++; activeIter = active.end(); }// while // create result segments for (activeIter = active.begin(); activeIter != active.end(); activeIter++) { RationalPoint3D tail, head; IntersectionSegment* segment = *activeIter; if (segment->isOrthogonalToTAxis()) { tail = segment->getTail().getRationalPoint3D(); head = segment->getHead().getRationalPoint3D(); }// if else { tail = segment->evaluate(t1); head = segment->evaluate(t2); }// else size_t p1 = points.add(tail); size_t p2 = points.add(head); Predicate predicate = segment->getPredicate(); segments.add(Segment(p1,p2,predicate),pFaceIsCritical); }// for }// next /* 12 struct DoubleCompare */ bool DoubleCompare::operator()(const mpq_class& d1, const mpq_class& d2) const{ return NumericUtil::lower(d1, d2); }// Operator /* 13 class GlobalTimeValues */ GlobalTimeValues::GlobalTimeValues(double scale /* = 1 */, double orginalStartTime /* = 0 */, double orginalEndTime /* = 1 */){ this->orginalStartTime = orginalStartTime; this->orginalEndTime = orginalEndTime; this->scale = scale; }// Konstruktor GlobalTimeValues::GlobalTimeValues( const Interval& orginalInterval){ this->orginalStartTime = orginalInterval.start.ToDouble(); this->orginalEndTime = orginalInterval.end.ToDouble(); this->scale = 1000; }// Konstruktor void GlobalTimeValues::setScaleFactor(double scaleFactor) { if (scaleFactor > 0){ this->scale = scaleFactor; }// if else NUM_FAIL("Scale factor must be greate as zero"); }// setScale Interval GlobalTimeValues::getOrginalInterval()const{ return createInterval(this->orginalStartTime, this->orginalEndTime); }// getOrginalInterval Interval GlobalTimeValues::getScaledInterval()const{ return createInterval(0.0, this->scale); }// getScalingInterval double GlobalTimeValues::getOrginalStartTime()const{ return this->orginalStartTime; }// getOrginalStartTime double GlobalTimeValues::getOrginalEndTime()const{ return this->orginalEndTime; }// getOrginalEndTime double GlobalTimeValues::getScaledStartTime()const { return 0.0; }// getScaledStartTime double GlobalTimeValues::getScaledEndTime() const{ return this->scale; }// getScaledEndTime Interval GlobalTimeValues::createInterval( double start, double end, bool lc/*=true*/, bool rc/*=false*/) const{ Instant starttime(datetime::instanttype); Instant endtime(datetime::instanttype); starttime.ReadFrom(start); endtime.ReadFrom(end); return (Interval(starttime, endtime, lc, rc)); }// createInterval mpq_class GlobalTimeValues::computeOrginalTimeValue( mpq_class scaledTimeValue)const { mpq_class temp = scaledTimeValue/scale; mpq_class result = (1.0 - temp) * orginalStartTime + temp * orginalEndTime; return result; }// computeOrginalTimeValue void GlobalTimeValues::addTimeValue(mpq_class t){ if (NumericUtil::greaterOrNearlyEqual(t, 0) && NumericUtil::lowerOrNearlyEqual(t, this->scale)){ time.insert(t); }// if else { cerr << setprecision(9); cerr << *this; cerr << setprecision(9); cerr << t.get_d() << endl; NUM_FAIL ("Time value don,t be between starttime und endtime"); }// else }// addTimeValue void GlobalTimeValues::addStartAndEndtime(){ time.insert(0); time.insert(this->scale); }// addStartAndEndtime size_t GlobalTimeValues::size()const{ return time.size(); }// size std::ostream& operator <<(std::ostream& os, const GlobalTimeValues& timeValues){ return timeValues.print(os,""); }// Operator << std::ostream& GlobalTimeValues::print(std::ostream& os, std::string prefix)const{ std::set::const_iterator iter; os << "GlobalTimeValues(" << endl; os << prefix + " Orginal start time:= "; os << this->orginalStartTime; os << ", Orginal end time:= "; os << this->orginalEndTime << "," << endl; os << prefix + " Scaled start time:= 0, Scaled end time:= "; os << this->scale << "," <time.begin(); iter != this->time.end(); iter++){ if (iter != this->time.begin()) os << ", " ; os << (*iter).get_d(); }// for }// else os << ")" << endl; os << prefix << ")" << endl; return os; }// print bool GlobalTimeValues::operator == (const GlobalTimeValues& other)const{ if (!(NumericUtil::nearlyEqual(this->orginalStartTime, other.orginalStartTime))) return false; if (!(NumericUtil::nearlyEqual(this->orginalEndTime, other.orginalEndTime))) return false; if (!(NumericUtil::nearlyEqual(this->scale, other.scale))) return false; if(this->time.size() != other.time.size()) return false; std::set::iterator iter1,iter2; for (iter1 = this->time.begin(),iter2 = other.time.begin(); iter1 != this->time.end(); iter1++,iter2++){ if(!(NumericUtil::nearlyEqual(*iter1,*iter2))) return false; }// for return true; }// Operator == bool GlobalTimeValues::scaledFirst(mpq_class& t1, mpq_class& t2){ // min two timevalues requert if(time.size() < 2) return false; this->timeIter = time.begin(); this->t1 = t1 = *timeIter; this->timeIter++; this->t2 = t2 = *timeIter; this->orginalT1 = computeOrginalTimeValue(this->t1); this->orginalT2 = computeOrginalTimeValue(this->t2); return true; }// scaledFirst bool GlobalTimeValues::scaledNext(mpq_class& t1, mpq_class& t2){ if((++timeIter) != time.end()){ this->t1 = t1 = this->t2; this->orginalT1 = this->orginalT2; this->t2 = t2 = *timeIter; this->orginalT2 = computeOrginalTimeValue(this->t2); return true; }// if return false; }// scaledNext bool GlobalTimeValues::orginalFirst(mpq_class& t1, mpq_class& t2){ if(time.size() < 2) return false; this->timeIter = time.begin(); this->t1 = *timeIter; this->timeIter++; this->t2 = *timeIter; this->orginalT1 = t1 = computeOrginalTimeValue(this->t1); this->orginalT2 = t2 = computeOrginalTimeValue(this->t2); return true; }// orginalFirst bool GlobalTimeValues::orginalNext(mpq_class& t1, mpq_class& t2){ if((++timeIter) != time.end()){ this->t1 = this->t2; this->orginalT1 = t1 = this->orginalT2; this->t2 = *timeIter; this->orginalT2 = t2 = computeOrginalTimeValue(this->t2); return true; }// if return false; }// orginalFirst /* 14 class PResultFace */ PResultFace::PResultFace(){ set(Point3D(0,0,0),Point3D(0,0,0), Point3D(1,0,0),Point3D(1,0,0)); }// Konstruktor PResultFace::PResultFace(const PResultFace& other){ set(other); }// Konstruktor PResultFace::PResultFace(const Segment3D& left, const Segment3D& right){ set(left.getTail(),left.getHead(),right.getTail(),right.getHead()); }// Konstruktor PResultFace::PResultFace(const Segment3D& left, const Segment3D& right, int faceno, int cycleno, int edgeno, bool leftDomPoint, bool insideAbove){ set(left.getTail(),left.getHead(),right.getTail(),right.getHead()); this->medianHS.attr.faceno = faceno; this->medianHS.attr.cycleno = cycleno; this->medianHS.attr.edgeno = edgeno; this->medianHS.SetLeftDomPoint(leftDomPoint); this->insideAbove = medianHS.attr.insideAbove = insideAbove; }// Konstruktor PResultFace::PResultFace(const MSegmentData& mSeg, const GlobalTimeValues& timeValues){ Point2D start; Point2D end; double startTime = timeValues.getScaledStartTime(); double endTime = timeValues.getScaledEndTime(); // Fall the initial points together if (!mSeg.GetPointInitial()) { // Determine startpoint and endpoint on the initial segment start = Point2D(mSeg.GetInitialStartX(), mSeg.GetInitialStartY()); end = Point2D(mSeg.GetInitialEndX(), mSeg.GetInitialEndY()); }// if else { // Determine startpoint and endpoint on the final segment start = Point2D(mSeg.GetFinalStartX(), mSeg.GetFinalStartY()); end = Point2D(mSeg.GetFinalEndX(), mSeg.GetFinalEndY()); }// else // Set start points if ((start < end) == mSeg.GetInsideAbove()) { this->leftStart = Point3D(mSeg.GetInitialStartX(), mSeg.GetInitialStartY(), startTime); this->rightStart = Point3D(mSeg.GetInitialEndX(), mSeg.GetInitialEndY(), startTime); this->leftEnd = Point3D(mSeg.GetFinalStartX(), mSeg.GetFinalStartY(), endTime); this->rightEnd = Point3D(mSeg.GetFinalEndX(), mSeg.GetFinalEndY(), endTime); }// if else { this->leftStart = Point3D(mSeg.GetInitialEndX(), mSeg.GetInitialEndY(), startTime); this->rightStart = Point3D(mSeg.GetInitialStartX(), mSeg.GetInitialStartY(), startTime); this->leftEnd = Point3D(mSeg.GetFinalEndX(), mSeg.GetFinalEndY(), endTime); this->rightEnd = Point3D(mSeg.GetFinalStartX(), mSeg.GetFinalStartY(), endTime); }// else // Calculate middle halfsegment createMedianHS(); // Set indexes medianHS.attr.faceno = mSeg.GetFaceNo(); medianHS.attr.edgeno = mSeg.GetSegmentNo(); medianHS.attr.cycleno = mSeg.GetCycleNo(); medianHS.attr.coverageno = -1; medianHS.attr.partnerno = -1; boundingRect = getBoundingRec(leftStart); boundingRect.Extend(getBoundingRec(leftEnd)); boundingRect.Extend(getBoundingRec(rightStart)); boundingRect.Extend(getBoundingRec(rightEnd)); }// KonstruktorCreate void PResultFace::set(const Point3D leftStart, const Point3D leftEnd, const Point3D rightStart, const Point3D rightEnd){ this->leftStart = leftStart; this->leftEnd = leftEnd; this->rightStart = rightStart; this->rightEnd = rightEnd; createMedianHS(); medianHS.attr.faceno = -1; medianHS.attr.cycleno = -1; medianHS.attr.edgeno = -1; medianHS.attr.coverageno = -1; medianHS.attr.partnerno = -1; boundingRect = getBoundingRec(leftStart); boundingRect.Extend(getBoundingRec(leftEnd)); boundingRect.Extend(getBoundingRec(rightStart)); boundingRect.Extend(getBoundingRec(rightEnd)); }// set void PResultFace::set(const PResultFace& prFace){ this->leftStart = prFace.leftStart; this->leftEnd = prFace.leftEnd; this->rightStart = prFace.rightStart; this->rightEnd = prFace.rightEnd; this->medianHS = prFace.medianHS; this->insideAbove = prFace.insideAbove; boundingRect = getBoundingRec(leftStart); boundingRect.Extend(getBoundingRec(leftEnd)); boundingRect.Extend(getBoundingRec(rightStart)); boundingRect.Extend(getBoundingRec(rightEnd)); }// set void PResultFace::createMedianHS(){ double medianStartX = (this->leftStart.getX() + this->leftEnd.getX())/2; double medianStartY = (this->leftStart.getY() + this->leftEnd.getY())/2; double medianEndX = (this->rightStart.getX() + this->rightEnd.getX())/2; double medianEndY = (this->rightStart.getY() + this->rightEnd.getY())/2; medianStartX = medianStartX * medianHSZoom; medianStartY = medianStartY * medianHSZoom; medianEndX = medianEndX * medianHSZoom; medianEndY = medianEndY * medianHSZoom; Point medianStart(true,medianStartX, medianStartY); Point medianEnd (true,medianEndX,medianEndY); medianHS = HalfSegment(true, medianStart, medianEnd); insideAbove = medianHS.attr.insideAbove = !(medianStart > medianEnd); }// createMedianHS int PResultFace::getFaceNo() const{ return medianHS.attr.faceno; }// getFaceNo int PResultFace::getCycleNo() const{ return medianHS.attr.cycleno; }// getCycleNo int PResultFace::getSegmentNo() const{ return medianHS.attr.edgeno; }// getSegmentNo bool PResultFace::getInsideAbove() const{ return insideAbove; }// getInsideAbove HalfSegment PResultFace::getMedianHS() const{ return medianHS; }// getMedianHS Point3D PResultFace::getLeftStart() const{ return leftStart; }// getLeftStart Point3D PResultFace::getLeftEnd() const{ return leftEnd; }// getLeftEnd Point3D PResultFace::getRightStart() const{ return rightStart; }// getRightStart Point3D PResultFace::getRightEnd() const{ return rightEnd; }// getRightEnd Rectangle<2> PResultFace::getBoundingRec(const Point3D& point)const{ double array[2] = {point.getX(),point.getY()}; return Rectangle<2>(true,array,array); }// getBoundingBox Rectangle<2> PResultFace::getBoundingRec()const{ return boundingRect; }// getBoundingBox MSegmentData PResultFace::getMSegmentData() const{ MSegmentData msd(getFaceNo(), getCycleNo(), getSegmentNo(), getInsideAbove(), leftStart.getX(),leftStart.getY(), rightStart.getX(),rightStart.getY(), leftEnd.getX(),leftEnd.getY(), rightEnd.getX(), rightEnd.getY()); msd.SetDegeneratedInitial(DGM_NONE); msd.SetDegeneratedFinal(DGM_NONE); return msd; }// getMSegmentData bool PResultFace::isLeftDomPoint() const{ return medianHS.IsLeftDomPoint(); }// isLeftDomPoint void PResultFace::setSegmentNo(int sn){ medianHS.attr.edgeno = sn; }// setSegmentNo void PResultFace::setLeftDomPoint(bool ldp){ medianHS.SetLeftDomPoint(ldp); }// setLeftDomPoint bool PResultFace::lessByMedianHS(const PResultFace& other) const { return this->medianHS < other.medianHS; }// lessByMedianHS bool PResultFace::logicLess(const PResultFace& other) const { if (isLeftDomPoint() != other.isLeftDomPoint()) return isLeftDomPoint() > other.isLeftDomPoint(); return this->medianHS.LogicCompare(other.medianHS) == -1; }// logicLess void PResultFace::copyIndicesFrom(const HalfSegment* hs) { medianHS.attr.faceno = hs->attr.faceno; medianHS.attr.cycleno = hs->attr.cycleno; medianHS.attr.edgeno = hs->attr.edgeno; }// copyIndicesFrom std::ostream& PResultFace::print(std::ostream& os, std::string prefix)const{ os << "PResultFace(" << endl; os << prefix << " Left:= " << Segment3D(leftStart, leftEnd) << endl; os << prefix << " Right:= " << Segment3D(rightStart, rightEnd) << endl; os << prefix << " MedianHS:=" << this->medianHS << endl; os << prefix <<")" << endl; return os; }// print std::ostream& operator <<(std::ostream& os, const PResultFace& prFace){ prFace.print(os,""); return os; }// Operator << bool PResultFace::operator ==(const PResultFace& prFace)const{ if((this->leftStart == prFace.leftStart) && (this->leftEnd == prFace.leftEnd) && (this->rightStart == prFace.rightStart) && (this->rightEnd == prFace.rightEnd) && (this->medianHS == prFace.medianHS)&& (this->insideAbove == prFace.insideAbove)) return true; return false; }// Operator == bool PResultFace::checkBorder( double e)const{ return(!(leftStart.nearlyEqual(rightStart,e) && leftEnd.nearlyEqual(rightEnd,e))); }// checkBorder void PResultFace::merge(const PResultFace& other){ if(leftStart == other.rightStart && leftEnd == other.rightEnd){ leftStart = other.leftStart; leftEnd = other.leftEnd; }// if else if (rightStart == other.leftStart && rightEnd == other.leftEnd){ rightStart = other.rightStart; rightEnd = other.rightEnd; }// else if else { cerr << *this; cerr << other; NUM_FAIL ("PResultFace are not neighbors"); }// else createMedianHS(); }// merge PResultFace& PResultFace::operator =(const PResultFace& prFace){ set(prFace); return *this; }// Operator = /* 15 class CriticalPResultFace */ CriticalPResultFace::CriticalPResultFace(): source(UNIT_A),predicate(UNDEFINED){ }// Konstruktor CriticalPResultFace::CriticalPResultFace( const CriticalPResultFace& cmsegment){ set(cmsegment); }// Konstruktor CriticalPResultFace::CriticalPResultFace(const Segment3D& left, const Segment3D& right, SourceFlag source, Predicate predicate){ set(left, right, source,predicate); }// Konstruktor void CriticalPResultFace::set(const CriticalPResultFace& cprFace){ this->left = cprFace.left; this->right = cprFace.right; this->source = cprFace.source; this->midPoint = cprFace.midPoint; this->normalVector= cprFace.normalVector; this->predicate = cprFace.predicate; }// set void CriticalPResultFace::set(const Segment3D& left, const Segment3D& right, SourceFlag source, Predicate predicate){ this->left = left; this->right = right; RationalPoint3D initialStart = left.getTail().getR(); RationalPoint3D initialEnd = right.getTail().getR(); RationalPoint3D finalStart = left.getHead().getR(); RationalPoint3D finalEnd = right.getHead().getR(); // We compute the normalvector // We compute the normalvector if(initialEnd.distance(initialStart) > finalEnd.distance(finalStart)){ // Cross product of vector this->normalVector = (initialEnd - initialStart) ^ (finalStart - initialStart); }// if else { // A == B // Cross product of vector : this->normalVector = (finalStart - finalEnd) ^ (initialEnd - finalEnd); }// else this->normalVector.normalize(); double x = (left.getTail().getX() + right.getTail().getX() + left.getHead().getX() + right.getHead().getX())/4; double y = (left.getTail().getY() + right.getTail().getY() + left.getHead().getY() + right.getHead().getY())/4; double z = (left.getTail().getZ() + right.getTail().getZ() + left.getHead().getZ() + right.getHead().getZ())/4; this->midPoint =Point3D(x,y,z); this->source = source; this->predicate = predicate; }// set Point3D CriticalPResultFace::getMidPoint()const{ return midPoint; }// getMidPoint Segment3D CriticalPResultFace::getLeft() const{ return left; }// getLeft Segment3D CriticalPResultFace::getRight() const{ return right; }// getRight std::ostream& CriticalPResultFace::print(std::ostream& os, std::string prefix)const{ os << "CriticalPResultFace(" << endl; os << prefix << " Left:=" << this->left << endl; os << prefix << " Right:="<< this->right << endl; if(this->source == UNIT_A) os << prefix << " Source:= UNIT A" << endl; else os << prefix << " Source:= UNIT B" << endl; os << prefix << " Predicate:=" << toString(this->predicate) << endl; os << prefix << " MidPoint:=" << this->midPoint << endl; os << prefix << " Normalvector:=" << this->normalVector << endl; os << prefix <<")" << endl; return os; }// print std::ostream& operator <<(std::ostream& os, const CriticalPResultFace& cprFace){ cprFace.print(os,""); return os; }// Operator << bool CriticalPResultFace::operator ==( const CriticalPResultFace& cprFace)const{ if((this->left == cprFace.left) && (this->right == cprFace.right) && (this->source == cprFace.source)&& (this->predicate == cprFace.predicate)) return true; return false; }// Operator == CriticalPResultFace& CriticalPResultFace::operator =( const CriticalPResultFace& cprFace){ set(cprFace); return *this; }// Operator = bool CriticalPResultFace::isPartOfUnitA() const{ return source == UNIT_A; }// isPartOfUnitA bool CriticalPResultFace::hasEqualNormalVector( const CriticalPResultFace& other) const{ // Precondition: this is parallel to other. // The normal vectors are equal, iff // the cosinus of the angle between them is positive: return NumericUtil::greater(normalVector * other.normalVector, 0.0); }// hasEqualNormalVectors bool CriticalPResultFace::operator <( const CriticalPResultFace& cprFace)const{ return this->midPoint < cprFace.midPoint; }// Operator < Predicate CriticalPResultFace::getPredicate() const { return this->predicate; }// getPredicate PResultFace CriticalPResultFace::getPResultFace()const{ return PResultFace(left,right); }// getPResultFace /* 16 class ResultUnit */ ResultUnit::ResultUnit(){ this->orginalStartTime = 0; this->orginalEndTime = 1; }// Konstruktor ResultUnit::ResultUnit(double orginalStartTime, double orginalEndTime){ this->orginalStartTime = orginalStartTime; this->orginalEndTime = orginalEndTime; }// Konstruktor ResultUnit::ResultUnit(const ResultUnit& other){ set(other); }// Konstruktor void ResultUnit::set(const ResultUnit& other){ this->prFaces = std::vector(); this->mCSegments = std::vector(); this->orginalStartTime = other.orginalStartTime; this->orginalEndTime = other.orginalEndTime; for (size_t i = 0; i < other.prFaces.size(); i++) { this->prFaces.push_back(other.prFaces[i]); }// for for (size_t i = 0; i < other.mCSegments.size(); i++) { this->mCSegments.push_back(other.mCSegments[i]); }// for }// set size_t ResultUnit::size(){ return prFaces.size(); }// size( void ResultUnit::addPResultFace(PResultFace& prFace, bool completely ){ if (prFace.getLeftStart() == prFace.getRightStart() && prFace.getLeftEnd() == prFace.getRightEnd()){ cerr << prFace << endl; NUM_FAIL("Error"); }// if if (completely) { prFaces.push_back(prFace); }// if else { prFace.setLeftDomPoint(true); prFaces.push_back(prFace); }// else }// addPResultFace void ResultUnit::addPResultFace(const CriticalPResultFace& mCSegment){ PResultFace prFace = mCSegment.getPResultFace(); addPResultFace(prFace,false); }// addPResultFace void ResultUnit::addCPResultFace(const CriticalPResultFace& prFace){ mCSegments.push_back(prFace); }// addPResultFace Interval ResultUnit::getTimeInterval() const { Instant start(datetime::instanttype); Instant end(datetime::instanttype); start.ReadFrom(this->orginalStartTime); end.ReadFrom(this->orginalEndTime); return Interval(start, end, true, false); }// getTimeInterval std::ostream& ResultUnit::print(std::ostream& os, std::string prefix)const{ os << "ResultUnit(" << endl; os << prefix + " Startime:=" << this->orginalStartTime; os << ", EndTime:=" << this->orginalEndTime << endl; os << prefix + " PResultFaces ("; if (this->prFaces.size() == 0) os << "is empty)" << endl; else { os << endl; for (size_t i = 0; i < this->prFaces.size(); i++) { os << prefix + " Index:=" << i << ", "; this->prFaces[i].print(os,prefix + " "); }// for os << prefix + " )" << endl; }// else os << prefix + " CriticalPResultFace ("; if (this->mCSegments.size() == 0) os << "is empty)" << endl; else { os << endl; for (size_t i = 0; i < this->mCSegments.size(); i++) { os << prefix + " Index:=" << i << ", "; this->mCSegments[i].print(os,prefix + " "); }// for os << prefix << " )"<orginalStartTime, other.orginalStartTime) && NumericUtil::nearlyEqual(this->orginalEndTime, other.orginalEndTime))) { cerr << "Start time or end time not equal" << endl; return false; }// if if (this->prFaces.size() != other.prFaces.size()) { cerr << "Size of prFaces is differnt" << endl; return false; }// if for (size_t i = 0; i < this->prFaces.size(); i++) { if (!(this->prFaces[i] == other.prFaces[i])) { cerr << "ResultUnit is not equal on Index for PResultFace:="; cerr << i << endl; return false; }// if }// for return true; }// Operator == ResultUnit& ResultUnit::operator =(const ResultUnit& unit){ set(unit); return *this; }// Operator = bool ResultUnit::less(const PResultFace& prf1, const PResultFace& prf2) { return prf1.lessByMedianHS(prf2); }// less bool ResultUnit::logicLess(const PResultFace& prf1, const PResultFace& prf2) { return prf1.logicLess(prf2); }// logicLess void ResultUnit::finalize(){ if(prFaces.size() == 0) return; do { size_t size = prFaces.size(); for(size_t i = 0; i < size; i++){ PResultFace rFace = prFaces[i]; rFace.setSegmentNo(i); prFaces[i] = rFace; rFace.setLeftDomPoint(false); prFaces.push_back(rFace); }// for // First, we sort the prFaces of this unit by their // median-halfsegments. Comparison between halfsegments // is done by the < operator, implemented in the SpatialAlgebra. sort(prFaces.begin(), prFaces.end(), ResultUnit::less); // Second, we construct a region from all median-halfsegments // of each msegment of this unit: Region region(prFaces.size()); region.StartBulkLoad(); for (size_t i = 0; i < prFaces.size(); i++) { // cout << prFaces[i].getMedianHS() << endl; region.Put(i, prFaces[i].getMedianHS()); }// for // Note: Sorting is already done. region.EndBulkLoad(false, true, true, true); // Third, we retrive the faceNo, cycleNo and edgeNo of // each halfsegment from the region, computed in the // Region::EndBulkLoad procedure: for (unsigned int i = 0; i < prFaces.size(); i++) { HalfSegment halfSegment; region.Get(i, halfSegment); prFaces[i].copyIndicesFrom(&halfSegment); }// for // Sort prFaces by faceno, cycleno and segmentno sort(prFaces.begin(), prFaces.end(), ResultUnit::logicLess); // this->Print(); // Erase the second half of prFaces, // which contains all PResultFaces with right dominating point prFaces.erase(prFaces.begin() + prFaces.size() / 2, prFaces.end()); }while(merge(NumericUtil::eps*NumericUtil::epsRelaxFactor)); }// finalize URegionEmb* ResultUnit::convertToURegionEmb( DbArray* segments) const { size_t segmentsStartPos = segments->Size(); URegionEmb* uregion = new URegionEmb(getTimeInterval(), segmentsStartPos); Rectangle<2> resultBRec; if(prFaces.size() > 0){ resultBRec = prFaces[0].getBoundingRec(); }// if for(unsigned int i = 0; i < prFaces.size(); i++) { MSegmentData msd = prFaces[i].getMSegmentData(); uregion->PutSegment(segments, i, msd, true); Rectangle<2> bRec = prFaces[i].getBoundingRec(); resultBRec.Extend(bRec); }// for // Set the bbox double min[3] = { resultBRec.MinD(0),resultBRec.MinD(1), this->orginalStartTime }; double max[3] = { resultBRec.MaxD(0),resultBRec.MaxD(1), this->orginalEndTime }; uregion->SetBBox(Rectangle<3>(true, min, max)); return uregion; }// convertToURegionEmb void ResultUnit::copyCriticalMSegmens(const CriticalPResultFace& cmSeg, SetOp setOp){ if (setOp == UNION && cmSeg.getPredicate() == OUTER) { addPResultFace(cmSeg); return; }// if if (setOp == INTERSECTION && cmSeg.getPredicate() == INNER) { addPResultFace(cmSeg); return; }// if if ( setOp == MINUS && ((cmSeg.isPartOfUnitA() && cmSeg.getPredicate() == OUTER)|| (!cmSeg.isPartOfUnitA() && cmSeg.getPredicate() == INNER))) { addPResultFace(cmSeg); return; }// if }// CopyCriticalMSegmens void ResultUnit::evaluateCriticalMSegmens(SetOp setOp){ // Sort by midpoints: sort(mCSegments.begin(), mCSegments.end()); if (mCSegments.size() > 0) { size_t i; for (i = 0; i < mCSegments.size()-1; i++) { CriticalPResultFace cmSeg0 = mCSegments[i]; CriticalPResultFace cmSeg1 = mCSegments[i+1]; if(cmSeg0.getMidPoint() == cmSeg1.getMidPoint()) { if (cmSeg0.hasEqualNormalVector(cmSeg1)) { addPResultFace(cmSeg0); }// if i++; }// if else { copyCriticalMSegmens(cmSeg0,setOp); }// else }// for if (i == mCSegments.size()-1) { CriticalPResultFace cmSeg = mCSegments[i]; copyCriticalMSegmens(cmSeg,setOp); }// if }// if mCSegments.clear(); }// evaluateCriticalMSegmens bool ResultUnit::merge(double e){ bool merge = false; for(size_t i = prFaces.size()-2; i != 0; i--){ if(prFaces.size() < 3){ NUM_FAIL ("Upps"); }// if PResultFace prFace0 = prFaces[i]; PResultFace prFace1 = prFaces[i+1]; if(!prFace1.checkBorder(e)){ prFace0.merge(prFace1); prFaces[i] = prFace0; prFaces.erase(prFaces.begin()+i+1); merge = true; }// if }// for return merge; }// check /* 17 class Layer */ Layer::Layer(bool isCritical /*= false*/){ this->isCritical = isCritical; this->touchBelow = 0; this->touchAbove = 0; }// Construktor Layer::Layer(const Layer& other){ set(other); }// Construktor void Layer::addOrthSegment(const Segment& segment){ size_t index = this->segments.add(segment); Predicate predicate = segment.getPredicate(); if (this->nonOrthSegments.size() > 0 && (predicate == RIGHT_IS_INNER || predicate == LEFT_IS_INNER)){ // the first segment is the left boundary Segment leftBoder = this->segments.get(this->nonOrthSegments[0]); if(leftBoder.getHead() == segment.getTail()) this->touchAbove++; if(leftBoder.getTail() == segment.getTail()) this->touchBelow++; }// if this->orthSegments.push_back(index); }// addOrthSegment void Layer::addNonOrthSegment(const Segment& segment){ size_t index = this->segments.add(segment); Predicate predicate = segment.getPredicate(); if (this->nonOrthSegments.size() > 0 && (predicate == RIGHT_IS_INNER || predicate == LEFT_IS_INNER)){ // the first segment is the left boundary Segment leftBoder = this->segments.get(this->nonOrthSegments[0]); if(leftBoder.getHead() == segment.getHead()) this->touchAbove++; if(leftBoder.getTail() == segment.getTail()) this->touchBelow++; }// if this->nonOrthSegments.push_back(index); }// addNonOrthSegment void Layer::print(std::ostream& os, const vector values)const{ for( size_t i = 0; i < values.size(); i++){ os << values[i]; if(i != values.size() -1) os << ", "; }// for }// print std::ostream& Layer::print(std::ostream& os,std::string prefix)const{ os << "Layer("; if (this->segments.size() == 0) os << "is empty)" << endl; else { os << endl; if(this->isCritical){ os << prefix + " Source PFace is critical" << endl; }// if else os << prefix + " Source PFace is not critical" <nonOrthSegments); os << ")" << endl; os << prefix + " Orthogonal segments("; print(os, this->orthSegments); os << ")" << endl; os << prefix + " Touch on the left border below := "; os << this->touchBelow << endl; os << prefix + " Touch on the left border above := "; os << this->touchAbove << endl; os << prefix << ")" << endl; }// else return os; }// print std::ostream& operator <<(std::ostream& os, const Layer& layer){ return layer.print(os,""); }// Operator << Predicate Layer::getBorderPredicate(const Segment& segment, Border border)const{ Predicate predicate = segment.getPredicate(); if (predicate == LEFT_IS_INNER){ if (border == LEFT) return OUTER; else return INNER; }// if else if (predicate == RIGHT_IS_INNER){ if (border == LEFT) return INNER; else return OUTER; }// else if else if (predicate == INNER || predicate == OUTER) return predicate; else return UNDEFINED; }// getBorderPredicate Predicate Layer::getAreaPredicate(size_t left, size_t right, size_t orthogonal, bool orthSegmentExist)const{ Segment leftSegment = this->segments.get(left); Segment rightSegment = this->segments.get(right); Segment orthSegment = this->segments.get(orthogonal); // cout << "Left:= " << leftSegment << endl; // cout << "Right:= " << rightSegment << endl; // if( orthSegmentExist) { // cout << "Orthogonal:= " << orthSegment << endl; // }// if Predicate result = UNDEFINED; Predicate predicateLeft = getBorderPredicate(leftSegment, LEFT); Predicate predicateRight = getBorderPredicate(rightSegment, RIGHT); // cout << "Left Predicate:=" << toString(predicateLeft) << endl; // cout << "Right Predicate:=" << toString(predicateRight) << endl; if (predicateLeft != UNDEFINED) { if (predicateRight != UNDEFINED) { if (predicateLeft == predicateRight) { result = predicateLeft; }// if // possibly no predicate can be determined for critical P-Faces else if(this->isCritical) { result = INTERSECT; }// if else { cerr << *this; NUM_FAIL("Different predicates at the edges of a area"); }// else }// else // right boundary is undefined else result = predicateLeft; }// if else { // right boundary is undefined result = predicateRight; }// else // if necessary, the orthogonal segments must be evaluated if (result == UNDEFINED && orthSegmentExist && !this->isCritical){ result = getBorderPredicate(orthSegment, RIGHT); }// if // cout << "Predicate:=" << toString(result) << endl; // cout << endl; return result; }// getAreaPredicate void Layer::getBorderPredicates(Predicate& left, Predicate& right)const{ size_t first = this->nonOrthSegments[0]; size_t last = this->nonOrthSegments[this->nonOrthSegments.size()-1]; left = getBorderPredicate(this->segments.get(first),LEFT); right = getBorderPredicate(this->segments.get(last),RIGHT); }// getBorderPredicate bool Layer::evaluate(){ // orthogonal segments size_t j = 0; size_t orthogonal = 0; bool orthSegmentExist = false; // left border size_t left = this->nonOrthSegments[0]; size_t right; // over all non-orthogonal segments for(size_t i = 1; i < this->nonOrthSegments.size(); i++ ){ // right border right = this->nonOrthSegments[i]; // do orthogonal segments exist? if( j < orthSegments.size()){ orthogonal = this->orthSegments[j]; // does the orthogonal segment touch the left border? if (this->segments.get(left).getTail() == this->segments.get(orthogonal).getTail()) { orthSegmentExist = true; j++; }// if else orthSegmentExist = false; }// if Predicate predicate = getAreaPredicate(left, right, orthogonal,orthSegmentExist); segments.set(left, predicate); segments.set(right, predicate); left = right; }// for // is the predicate of the right segment not undefined but the predicate // of the left segment is set to undefined? Predicate leftPredicate, rightPredicate; getBorderPredicates(leftPredicate, rightPredicate); if(leftPredicate == UNDEFINED && rightPredicate != UNDEFINED){ // right border right = this->nonOrthSegments[this->nonOrthSegments.size()-1]; orthogonal = 0; for(int i = this->nonOrthSegments.size()-2; i >= 0; i--){ // left border size_t left = this->nonOrthSegments[i]; Predicate predicate = getAreaPredicate(left, right, orthogonal, orthSegmentExist); segments.set(left, predicate); segments.set(right, predicate); right = left; }// for }// if size_t first = this->nonOrthSegments[0]; size_t last = this->nonOrthSegments[this->nonOrthSegments.size()-1]; leftPredicate = this->segments.get(first).getPredicate(); rightPredicate = this->segments.get(last).getPredicate(); return (leftPredicate != UNDEFINED && rightPredicate != UNDEFINED); }// evaluate bool Layer::operator ==(const Layer& layer)const{ if(!(this->segments == layer.segments)) return false; if(this->orthSegments.size() != layer.orthSegments.size()) return false; for(size_t i = 0; i < this->orthSegments.size(); i++){ if(this->orthSegments[i] != layer.orthSegments[i]) return false; }// for if(this->nonOrthSegments.size() != layer.nonOrthSegments.size()) return false; for(size_t i = 0; i < this->nonOrthSegments.size(); i++){ if(this->nonOrthSegments[i] != layer.nonOrthSegments[i]) return false; }// for if(this->touchAbove != layer.touchAbove) return false; if(this->touchBelow != layer.touchBelow) return false; if(this->isCritical != layer.isCritical) return false; return true; }// Operator == void Layer::set(const Layer& layer){ this->segments = layer.segments; this->orthSegments = layer.orthSegments; this->nonOrthSegments = layer.nonOrthSegments; this->touchAbove = layer.touchAbove; this->touchBelow = layer.touchBelow; this->isCritical = layer.isCritical; }// set Layer& Layer::operator =(const Layer& layer){ set(layer); return *this; }// Operator = Predicate Layer::getPredicateForSuccessor()const{ if (this->nonOrthSegments.size() < 2) return UNDEFINED; size_t first = this->nonOrthSegments[0]; size_t second = this->nonOrthSegments[1]; Predicate predicate = getAreaPredicate(first, second, first, false); if (predicate != UNDEFINED){ if (touchAbove%2 == 1){ if (predicate == INNER) return OUTER; else return INNER; }// if }// if return predicate; }// getSuccessorPredicate Predicate Layer::getPredicateForPredecessor()const{ if (this->nonOrthSegments.size() < 2) return UNDEFINED; size_t first = this->nonOrthSegments[0]; size_t second = this->nonOrthSegments[1]; Predicate predicate = getAreaPredicate(first, second, first, false); if (predicate != UNDEFINED){ if (touchBelow%2 == 1){ if (predicate == INNER) return OUTER; else return INNER; }// if }// if return predicate; }// getPredecessorPredicate void Layer::setPredicateFromSuccessor(Predicate predicate){ if (predicate == UNDEFINED || this->nonOrthSegments.size() < 2) return; if (touchAbove%2 == 1){ if (predicate == INNER) predicate = OUTER; else predicate = INNER; }// if size_t first = this->nonOrthSegments[0]; size_t second = this->nonOrthSegments[1]; segments.set(first, predicate); segments.set(second, predicate); }// setPredicateFromPredecessor void Layer::setPredicateFromPredecessor(Predicate predicate){ if (predicate == UNDEFINED || this->nonOrthSegments.size() < 2) return; if (touchBelow%2 == 1){ if (predicate == INNER) predicate = OUTER; else predicate = INNER; }// if size_t first = this->nonOrthSegments[0]; size_t second = this->nonOrthSegments[1]; segments.set(first, predicate); segments.set(second, predicate); }// setPredicateFromPredecessor bool Layer::intersects(bool& predicate)const{ size_t size = this->nonOrthSegments.size(); if(size < 2) { NUM_FAIL ("there must be at least two segments."); }// if // relevantes P-Face with more than two segments if (/*!this->isCritical && */ size > 2){ predicate = true; return true; }// if // relevantes P-Face with exactly two segments if (/*!this->isCritical && */size == 2){ size_t first = this->nonOrthSegments[0]; size_t second = this->nonOrthSegments[1]; Predicate result = getAreaPredicate(first, second, first, false); // cout << "Predicate:=" << toString(result) << endl; if ( segments.get(first).getPredicate() == INTERSECT || segments.get(second).getPredicate() == INTERSECT){ predicate = true; return true; }// if else if (result == INNER) { predicate = true; return true; }// if else if (result == OUTER) { predicate = false; return true; }// else if }// if predicate = false; return false; }// intersects bool Layer::inside(bool& predicate)const{ size_t size = this->nonOrthSegments.size(); if(size < 2) { NUM_FAIL ("there must be at least two segments."); }// if // relevantes P-Face with more than two segments if (!this->isCritical && size > 2){ predicate = false; return true; }// if // relevantes P-Face with exactly than two segments if (!isCritical && size == 2){ size_t first = this->nonOrthSegments[0]; size_t second = this->nonOrthSegments[1]; Predicate result = getAreaPredicate(first, second, first, false); // cout << "Predicate:=" << toString(result) << endl; if (result == INNER) { predicate = true; return true; }// if else if (result == OUTER) { predicate = false; return true; }// else if }// if else { //critical P-Face Predicate oldPredicate = UNDEFINED; for (size_t i = 0; i < size-1; i++){ Predicate newPredicate = getAreaPredicate(this->nonOrthSegments[i], this->nonOrthSegments[i+1],this->nonOrthSegments[i], false); // cout << "Old Predicate:=" << toString(oldPredicate) << endl; // cout << "New Predicate:=" << toString(newPredicate) << endl; // cout << "Left segment.="; // cout << this->segments.get(this->nonOrthSegments[i]) << endl; // cout << "Right segments:="; // cout << this->segments.get(this->nonOrthSegments[i+1]) << endl; if (newPredicate == OUTER) { predicate = false; return true; }// if if(newPredicate != UNDEFINED) oldPredicate = newPredicate; }// for if(oldPredicate == INNER){ predicate = true; return true; }// if }// else predicate = false; return false; }// inside void Layer::getResultUnit(Predicate soughtPredicate, bool reverse, const Point3DContainer& points, ResultUnit& unit, SourceFlag source)const { for(size_t i = 0; i < this->nonOrthSegments.size()-1; i++){ size_t left = this->nonOrthSegments[i]; size_t right = this->nonOrthSegments[i+1]; Segment leftSegment = this->segments.get(left); Segment rightSegment = this->segments.get(right); Predicate predicate = getAreaPredicate(left, right, left, false); if (predicate == soughtPredicate || this->isCritical){ if (reverse) { Segment temp = leftSegment; leftSegment = rightSegment; rightSegment = temp; }// if Point3D leftTail = points.get(leftSegment.getTail()); Point3D leftHead = points.get(leftSegment.getHead()); Point3D rightTail = points.get(rightSegment.getTail()); Point3D rightHead = points.get(rightSegment.getHead()); Segment3D left = Segment3D(leftTail,leftHead); Segment3D right = Segment3D(rightTail,rightHead); if (this->isCritical) { CriticalPResultFace segment(left,right,source,predicate); unit.addCPResultFace(segment); }// if else { PResultFace segment(left, right); unit.addPResultFace(segment,false); }// else }// if }// for }// getResultUnit /* 18 class LayerContainer */ LayerContainer::LayerContainer(size_t size /* = 0 */, bool isCritcal /* = false*/){ this->layers = std::vector(size,Layer(isCritcal)); }// Constructor LayerContainer::LayerContainer(const LayerContainer& other){ set(other); }// Constructor LayerContainer::LayerContainer( Point3DContainer& points, GlobalTimeValues &timeValues, PlaneSweepAccess &access, bool pFaceIsCritical){ size_t size = timeValues.size()-1; this->layers = vector(size,Layer(pFaceIsCritical)); mpq_class t1,t2; SegmentContainer segments; if (timeValues.scaledFirst(t1, t2) ) { access.first(t1, t2, points, segments, pFaceIsCritical); // over all time periods for (size_t i = 0; i < size; i++) { // over all segments for (size_t j = 0; j < segments.size(); j++) { Point3D head, tail; Segment segment = segments.get(j); head = points.get(segment.getHead()); tail = points.get(segment.getTail()); if (NumericUtil::nearlyEqual(head.getZ(),tail.getZ())) { addOrthSegment(i, segment); }// if else { addNonOrthSegment(i, segment); }// else }// for // cout << "i:=" << i << endl; // cout << "t1:=" << t1 << ",t2:="<< t2 << endl; // cout << *this; // cout << timeValues; t1 = t2; timeValues.scaledNext(t1, t2); segments.clear(); access.next(t1, t2, points, segments, pFaceIsCritical); }// for }// if }// Konstruktor void LayerContainer::set(const LayerContainer& other){ this->layers = other.layers; }// set void LayerContainer::addOrthSegment(size_t layer, const Segment& segment){ if (layer < this->layers.size()) { this->layers[layer].addOrthSegment(segment); }// if else NUM_FAIL("Index of layer is out of range."); }// addOrthSegment void LayerContainer::addNonOrthSegment(size_t layer, const Segment& segment){ if (layer < this->layers.size()) { this->layers[layer].addNonOrthSegment(segment); }// if else NUM_FAIL("Index of layer is out of range."); }// addNonOrthSegment std::ostream& LayerContainer::print(std::ostream& os, std::string prefix)const{ os << "LayerContainer(" << endl; for(size_t i = 0; i < this->layers.size(); i++){ os << prefix + " Index:=" << i << ", "; layers[i].print(os,prefix + " "); }// for os << prefix + ")" << endl; return os; }// print std::ostream& operator<<( std::ostream& os, const LayerContainer& container){ return container.print(os,""); }// Operator << bool LayerContainer::evaluate(){ bool status = true; vector evaluated(layers.size(),false); // Pass all layers forward Predicate predicate = UNDEFINED; for (size_t i = 0; i < layers.size(); i++){ bool result = layers[i].evaluate(); // Can a predicate be taken from the predecessor? if (!result && predicate != UNDEFINED){ layers[i].setPredicateFromPredecessor(predicate); result = layers[i].evaluate(); if(!result){ cerr << *this; NUM_FAIL("The processing of the intersections was not successful."); }// if }// if evaluated[i] = result; predicate = layers[i].getPredicateForSuccessor(); }// for // Pass all layers backward predicate = UNDEFINED; for(int i = layers.size()-1; i >= 0; i--){ // Can a predicate be taken from the successor? if (!evaluated[i] && predicate != UNDEFINED){ layers[i].setPredicateFromSuccessor(predicate); bool result = layers[i].evaluate(); evaluated[i] = result; if(!result){ cerr << *this; NUM_FAIL("The processing of the intersections was not successful."); }// if }// if predicate = this->layers[i].getPredicateForPredecessor(); status = status && evaluated[i]; }// for return status; }// evaluate void LayerContainer::getBorderPredicates(Predicate& left, Predicate& right)const{ left = UNDEFINED; right = UNDEFINED; if (this->layers.size() > 0){ layers[0].getBorderPredicates(left,right); for( size_t i = 1; i < this->layers.size(); i ++){ Predicate tmpLeft, tmpRight; layers[i].getBorderPredicates(tmpLeft,tmpRight); if (right != tmpRight) right = INTERSECT; if (left != tmpLeft) left = INTERSECT; }// for }// if }// getBorderPredicate bool LayerContainer::operator ==(const LayerContainer& other)const{ if (this->layers.size() != other.layers.size()) return false; for (size_t i = 0 ; i < this->layers.size(); i ++){ if(!(this->layers[i] == other.layers[i])) return false; }// for return true; }// Operator == LayerContainer& LayerContainer::operator =(const LayerContainer& other){ set(other); return *this; }// Operator = bool LayerContainer::intersects(std::vector& predicate)const{ for(size_t i = 0; i < this->layers.size(); i ++){ bool value; bool result = this->layers[i].intersects(value); predicate[i] = value; if(!result)return false; }// for return true; }// intersects bool LayerContainer::inside(std::vector& predicate)const{ for(size_t i = 0; i < this->layers.size(); i ++){ bool value; bool result = this->layers[i].inside(value); predicate[i] = value; if(!result)return false; }// for return true; }// inside void LayerContainer::getResultUnit(size_t layer, Predicate soughtPredicate, bool reverse, const Point3DContainer& points, ResultUnit& unit, SourceFlag source)const { if(layer < this->layers.size()){ this->layers[layer].getResultUnit(soughtPredicate, reverse, points, unit, source); }// if else { cerr << "Index:=" << layer <left = left; this->right = right; this->state = UNKNOWN; }// Konstruktor PFace::PFace(const MSegmentData& mSeg, const GlobalTimeValues& timeValues, Point3DContainer& points, SegmentContainer& segments){ Point2D start; Point2D end; double startTime = timeValues.getScaledStartTime(); double endTime = timeValues.getScaledEndTime(); if (!mSeg.GetPointInitial()) { start = Point2D(mSeg.GetInitialStartX(), mSeg.GetInitialStartY()); end = Point2D(mSeg.GetInitialEndX(), mSeg.GetInitialEndY()); }// if else { start = Point2D(mSeg.GetFinalStartX(), mSeg.GetFinalStartY()); end = Point2D(mSeg.GetFinalEndX(), mSeg.GetFinalEndY()); }// else Point3D leftStart, rightStart, leftEnd, rightEnd; if ((start < end) == mSeg.GetInsideAbove()) { leftStart = Point3D(mSeg.GetInitialStartX(), mSeg.GetInitialStartY(), startTime); rightStart = Point3D(mSeg.GetInitialEndX(), mSeg.GetInitialEndY(), startTime); leftEnd = Point3D(mSeg.GetFinalStartX(), mSeg.GetFinalStartY(), endTime); rightEnd = Point3D(mSeg.GetFinalEndX(), mSeg.GetFinalEndY(), endTime); }// if else { leftStart = Point3D(mSeg.GetInitialEndX(), mSeg.GetInitialEndY(), startTime); rightStart = Point3D(mSeg.GetInitialStartX(), mSeg.GetInitialStartY(), startTime); leftEnd = Point3D(mSeg.GetFinalEndX(), mSeg.GetFinalEndY(), endTime); rightEnd = Point3D(mSeg.GetFinalStartX(), mSeg.GetFinalStartY(), endTime); }// else size_t iLeftStart = points.add(leftStart); size_t iLeftEnd = points.add(leftEnd); size_t iRightStart= points.add(rightStart); size_t iRightEnd = points.add(rightEnd); this->leftStart = points.get(iLeftStart); this->leftEnd = points.get(iLeftEnd); this->rightStart = points.get(iRightStart); this->rightEnd = points.get(iRightEnd); createMedianHS(); medianHS.attr.faceno = mSeg.GetFaceNo(); medianHS.attr.edgeno = mSeg.GetSegmentNo(); medianHS.attr.cycleno = mSeg.GetCycleNo(); medianHS.attr.coverageno = -1; medianHS.attr.partnerno = -1; boundingRect = getBoundingRec(this->leftStart); boundingRect.Extend(getBoundingRec(this->leftEnd)); boundingRect.Extend(getBoundingRec(this->rightStart)); boundingRect.Extend(getBoundingRec(this->rightEnd)); Segment leftSegment(iLeftStart,iLeftEnd, UNDEFINED); Segment rightSegment(iRightStart, iRightEnd, UNDEFINED); this->left = segments.add(leftSegment); this->right = segments.add(rightSegment); this->state = UNKNOWN; }// Konstruktor PFace::PFace(const PFace& pf){ set(pf); }// Konstruktor void PFace::set(const PFace& pf){ this->leftStart = pf.leftStart; this->leftEnd = pf.leftEnd; this->rightStart = pf.rightStart; this->rightEnd = pf.rightEnd; this->medianHS = pf.medianHS; this->boundingRect= pf.boundingRect; this->intSegs = pf.intSegs; this->layers = pf.layers; this->state = pf.state; this->left = pf.left; this->right = pf.right; }// Konstruktor void PFace::setState(State state){ this->state = state; }// setState State PFace::getState() const{ return state; }// getState bool PFace::existsIntSegs()const{ return (this->intSegs.size() != 0); }// hasIntseg string PFace::toString(State state){ switch (state) { case UNKNOWN: return "UNKNOWN"; case RELEVANT: return "RELEVANT"; case CRITICAL: return "CRITICAL"; case NOT_RELEVANT: return "NOT_RELEVANT"; default: return ""; }// switch }// toString std::ostream& operator <<(std::ostream& os, const PFace& pf){ return pf.print(os,""); }// operator std::ostream& PFace::print(std::ostream& os, std::string prefix)const{ os << "PFace( " << endl; os << prefix + " left border index:=" << this->left; os << ", right border index:=" << this->right << "," << endl; os << prefix + " state:=" << PFace::toString(state) << "," << endl; os << prefix + " left start point:=" << this->leftStart; os << " , left end point:="<< this->leftEnd << "," << endl; os << prefix + " right start point:=" << this->rightStart; os << " , right end point:=" << this->rightEnd << "," << endl; os << prefix + " MedianHS:=" << this->medianHS << "," << endl; os << prefix + " "; os << setprecision(12); this->intSegs.print(os," "+prefix); os << prefix + " "; this->layers.print(os," "+prefix); os << prefix + ")" << endl; return os; }// print PFace& PFace::operator =( const PFace& pf){ set(pf); return *this; }// Operator = bool PFace::operator ==(const PFace& pf)const{ if ((this->leftStart == pf.leftStart) && (this->leftEnd == pf.leftEnd) && (this->rightStart == pf.rightStart) && (this->rightEnd == pf.rightEnd) && (this->medianHS == pf.medianHS) && (this->state == pf.state) && (this->boundingRect == pf.boundingRect)&& (this->intSegs == pf.intSegs)) return true; return false; }// Operator == void PFace::addIntSeg(const IntersectionSegment& seg){ this->intSegs.addIntSeg(seg); }// addIntSeg void PFace::addIntSeg(const RationalPlane3D &planeSelf, const RationalPlane3D &planeOther, const RationalSegment3D &intSeg, GlobalTimeValues &timeValues){ bool result = planeSelf.isLeftSideInner(intSeg,planeOther); Predicate predicate = LEFT_IS_INNER; if (!result) predicate = RIGHT_IS_INNER; RationalSegment2D segment = planeSelf.transform(intSeg); if (this->state != CRITICAL) this->state = RELEVANT; IntersectionSegment iSeg(intSeg,segment,predicate); timeValues.addTimeValue(iSeg.getTail().getT()); timeValues.addTimeValue(iSeg.getHead().getT()); addIntSeg(iSeg); }// addIntSeg IntersectionSegment PFace::createBorder( const RationalPlane3D &planeSelf, Border border, Predicate predicate){ Segment3D segment3D; Segment2D segment2D; if (border == LEFT) { segment3D = Segment3D(this->leftStart,this->leftEnd); segment2D = planeSelf.transform(segment3D).getD(); }// if else { segment3D = Segment3D(this->rightStart,this->rightEnd); segment2D = planeSelf.transform(segment3D).getD(); }// else return IntersectionSegment(segment3D,segment2D,predicate); }// createBorder void PFace::addBorder(const RationalPlane3D &plane, Predicate predicate){ IntersectionSegment iSeg = createBorder(plane,LEFT,predicate); addIntSeg(iSeg); iSeg = createBorder(plane,RIGHT,predicate); addIntSeg(iSeg); }// addBorder void PFace::addBorder(const SegmentContainer& segments, Predicate predicate){ Predicate leftPredicate = segments.get(left).getPredicate(); Predicate rightPredicate = segments.get(right).getPredicate(); if (state == UNKNOWN && leftPredicate != UNDEFINED && rightPredicate != UNDEFINED) { if (leftPredicate == predicate || rightPredicate == predicate) { state = RELEVANT; RationalPlane3D plane(*this); addBorder(plane,predicate); }// if else { state = NOT_RELEVANT; }// if }// if // A P-Face with a intersection cut could not be processed // in a previous round. The edges are re-added with their predicates else if ((state == RELEVANT || state == CRITICAL) && (leftPredicate != UNDEFINED || rightPredicate != UNDEFINED)) { RationalPlane3D plane(*this); IntersectionSegment iSeg = createBorder(plane,LEFT,leftPredicate); addIntSeg(iSeg); iSeg = createBorder(plane,RIGHT,rightPredicate); addIntSeg(iSeg); }// if }// addBorder void PFace::setBorderPredicate(SegmentContainer& segments, Predicate predicate){ Predicate leftPredicate = segments.get(this->left).getPredicate(); Predicate rightPredicate = segments.get(this->right).getPredicate(); if (leftPredicate == UNDEFINED) segments.set(this->left,predicate); if (rightPredicate == UNDEFINED) segments.set(this->right,predicate); }// setBorderPredicate void PFace::getBorderSegments(bool all, vector& borders){ borders.push_back(RationalSegment3D(this->leftStart,this->leftEnd)); borders.push_back(RationalSegment3D(this->rightStart,this->rightEnd)); if(all) { borders.push_back(RationalSegment3D(this->leftStart,this->rightStart)); borders.push_back(RationalSegment3D(this->leftEnd,this->rightEnd)); }// if }// getBorderSegments bool PFace::intersection(const vector& borders, const RationalSegment2D& segment, RationalSegment2D& result){ std::set points; std::set::iterator first,second; for (size_t i = 0; i < borders.size(); i++){ RationalPoint2D iPoint; if(segment == borders[i]){ continue; }// if bool result = segment.intersection(borders[i],iPoint); if(result){ // cout << segment << endl; // cout << borders[i] << endl; // cout << iPoint << endl; points.insert(iPoint); }// if }// for if(points.size() > 1 ){ second = first = points.begin(); second++; // The intersections points were sorted in the set "points" // according to the sizes of x, y. // Undo this sorting if(first->getY() < second->getY()){ result = RationalSegment2D(*first,*second); }// if else { result = RationalSegment2D(*second,*first); }// else return true; }// if return false; }// intersection RationalSegment3D PFace::map(const RationalSegment3D& orginal3D, const RationalSegment2D& orginal2D, const RationalSegment2D& intersection){ mpq_class length = (orginal2D.getHead() - orginal2D.getTail()).length(); mpq_class length0 = (intersection.getTail() - orginal2D.getTail()).length(); mpq_class length1 = (intersection.getHead() - orginal2D.getTail()).length(); RationalVector3D vector = orginal3D.getHead() - orginal3D.getTail(); RationalPoint3D tail3D = orginal3D.getTail() + length0/length*vector; RationalPoint3D head3D = orginal3D.getTail() + length1/length*vector; return RationalSegment3D(tail3D,head3D); }// map bool PFace::intersectionOnPlane(PFace& other, const RationalPlane3D& planeSelf, GlobalTimeValues &timeValues){ vector self3D; vector self2D; vector other3D; vector other2D; // create segments other.getBorderSegments(false, other3D); this->getBorderSegments(true, self3D); // transform segments planeSelf.transform(other3D,other2D); planeSelf.transform(self3D,self2D); // calculate the intersegment segments for (size_t i = 0; i < other2D.size(); i++){ RationalSegment2D segment2D; bool result = intersection(self2D, other2D[i], segment2D); if (result) { RationalSegment3D segment3D = map(other3D[i], other2D[i],segment2D); // cout << "Segment2D:=" << segment2D << endl; // cout << "Ssegment3D:=" << segment3D << endl; if (!(segment3D == self3D[0] || segment3D == self3D[1])){ IntersectionSegment iSegment(segment3D,segment2D, NO_INTERSECT); // cout << "Schnittsegment:=" << iSegment << endl; timeValues.addTimeValue(iSegment.getTail().getT()); timeValues.addTimeValue(iSegment.getHead().getT()); addIntSeg(iSegment); }// if }// if }// for this->state = CRITICAL; return true; }// intersectionOnPLane bool PFace::intersection(PFace& other,GlobalTimeValues &timeValues){ Rectangle<2> bRec = boundingRect; bRec.Extend(NumericUtil::eps); // No intersection if the bounding boxes do not intersect if (!(this->boundingRect.Intersects(other.boundingRect))) { return false; }// if // create planes RationalPlane3D planeSelf(*this); RationalPlane3D planeOther(other); // check planes if (planeSelf.isParallelTo(planeOther)) { if (planeSelf.isCoplanarTo(planeOther)) { intersectionOnPlane(other,planeSelf,timeValues); other.intersectionOnPlane(*this,planeOther,timeValues); }// if return false; }// if RationalPoint3DExtSet intPointSet; planeSelf.intersection(other, UNIT_A, intPointSet); // We need exactly two intersection points. if (intPointSet.size() != 2) return false; planeOther.intersection(*this, UNIT_B, intPointSet); RationalSegment3D intSeg; // cout << intPointSet; if (!intPointSet.getIntersectionSegment(intSeg)) return false; IntersectionSegment iSeg; // create and save result segments addIntSeg(planeSelf,planeOther,intSeg,timeValues); other.addIntSeg(planeOther,planeSelf,intSeg,timeValues); return true; }// intersection void PFace::first(mpq_class t1, mpq_class t2, Point3DContainer& points, SegmentContainer& segments, bool pFaceIsCritical){ intSegs.first(t1, t2, points, segments, pFaceIsCritical); }// first void PFace::next(mpq_class t1, mpq_class t2, Point3DContainer& points, SegmentContainer& segments,bool pFaceIsCritical){ intSegs.next(t1, t2, points, segments, pFaceIsCritical); }// next bool PFace::finalize(Point3DContainer& points, SegmentContainer& segments, GlobalTimeValues& timeValues){ Predicate leftPredicate, rightPredicate; bool result; if (this->state == RELEVANT || this->state == CRITICAL) { bool isCritical = false; if(this->state == CRITICAL) isCritical = true; this->layers = LayerContainer(points, timeValues, *this, isCritical); this->layers.evaluate(); this->layers.getBorderPredicates(leftPredicate,rightPredicate); if (leftPredicate == UNDEFINED && rightPredicate == UNDEFINED && !isCritical) { result = false; }// if else { if (leftPredicate != UNDEFINED){ segments.set(this->left,leftPredicate); result = true; }// if if (rightPredicate != UNDEFINED){ segments.set(this->right,rightPredicate); result = true; }// if }// else }// if else if (this->state == NOT_RELEVANT) result = true; else { leftPredicate = segments.get(this->left).getPredicate(); rightPredicate = segments.get(this->right).getPredicate(); if (leftPredicate == INNER || leftPredicate == OUTER) { if (rightPredicate == UNDEFINED) { segments.set(this->right,leftPredicate); }// if result = true; }// if if (rightPredicate == INNER || rightPredicate == OUTER) { if (leftPredicate == UNDEFINED) { segments.set(this->left,rightPredicate); }// if result = true; }// if result = false; }// else return result; }// finalize bool PFace::intersects(Point3DContainer& points, GlobalTimeValues& timeValues, std::vector& predicate){ if (this->state == RELEVANT || this->state == CRITICAL) { bool isCritical = false; if(this->state == CRITICAL) isCritical = true; this->layers = LayerContainer(points, timeValues, *this, isCritical); this->layers.evaluate(); return this->layers.intersects(predicate); }// if return false; }// intersects bool PFace::inside(Point3DContainer& points, GlobalTimeValues& timeValues, std::vector& predicate){ if (this->state == RELEVANT || this->state == CRITICAL) { bool isCritical = false; if(this->state == CRITICAL) isCritical = true; this->layers = LayerContainer(points, timeValues, *this, isCritical); this->layers.evaluate(); return this->layers.inside(predicate); }// if return false; }// inside void PFace::getResultUnit(size_t slide, Predicate predicate, bool reverse, const Point3DContainer& points, ResultUnit& unit, SourceFlag source){ if (this->state == RELEVANT || this->state == CRITICAL) { this->layers.getResultUnit(slide,predicate,reverse,points,unit,source); }// if }// getResultPFace /* 20 class FaceCycleInfo */ FaceCycleInfo::FaceCycleInfo():touch(false){ }// Konstruktor void FaceCycleInfo::setFirstIndex(size_t firstIndex){ this->firstIndex = firstIndex; }// setFirstIndex void FaceCycleInfo::setTouch(){ this->touch = true; }// setTouch bool FaceCycleInfo::getTouch() const{ return this->touch; }// getTouch size_t FaceCycleInfo::getFirstIndex() const{ return this->firstIndex; }// getFirstIndex /* 21 class SourceUnit */ SourceUnit::SourceUnit():pFaceTree(4,8),testRegion(0), testRegionDefined(false){ }// Konstruktor SourceUnit::SourceUnit(const SourceUnit& other):pFaceTree(4,8), testRegion(0),testRegionDefined(false){ set(other); }// Konstruktor SourceUnit::~SourceUnit(){ vector::iterator iter; for (iter = pFaces.begin(); iter != pFaces.end(); iter++) { delete *iter; }// for }// Destruktor void SourceUnit::set(const SourceUnit& other){ vector::iterator iter; for (iter = pFaces.begin(); iter != pFaces.end(); iter++) { delete *iter; }// for this->pFaces = vector(); this->pFaceTree = mmrtree::RtreeT<2, size_t>(4,8); this->itersectedPFace = other.itersectedPFace; this->segments = other.segments; this->faceCycleInfo = other.faceCycleInfo; this->testRegion = other.testRegion; this->testRegionDefined = other.testRegionDefined; for (size_t i = 0; i < other.pFaces.size(); i++) { PFace* pFace = new PFace(PFace(*other.pFaces[i])); size_t index = this->pFaces.size(); this->pFaces.push_back(pFace); Rectangle<2> boundigRec = pFace->getBoundingRec(); this->pFaceTree.insert(boundigRec,index); }// for }// set void SourceUnit::addPFace(const Segment& leftSegment, const Segment& rightSegment, const Point3DContainer& points){ size_t left = this->segments.add(leftSegment); size_t right = this->segments.add(rightSegment); size_t index = pFaces.size(); PFace* pFace = new PFace(left,right,points,this->segments); pFaces.push_back(pFace); Rectangle<2> boundigRec = pFace->getBoundingRec(); pFaceTree.insert(boundigRec,index); }// addPFace void SourceUnit::addMSegmentData(const MSegmentData& mSeg, const GlobalTimeValues& timeValues, Point3DContainer& points){ size_t index = pFaces.size(); PFace* pFace = new PFace(mSeg, timeValues, points,this->segments); pFaces.push_back(pFace); Rectangle<2> boundigRec = pFace->getBoundingRec(); pFaceTree.insert(boundigRec,index); createFaceCycleEntry(pFace,index); }// addMSegmentData bool SourceUnit::isEmpty()const{ return pFaces.size()==0; }// is Empty bool SourceUnit::intersect(const SourceUnit& other)const{ Rectangle<2> bRecA = this->pFaceTree.getBBox(); Rectangle<2> bRecB = other.pFaceTree.getBBox(); return bRecA.Intersects(bRecB); }// intersect void SourceUnit::addToResultUnit(ResultUnit& result)const{ for (size_t i = 0; i < pFaces.size(); i ++) { PResultFace msegment = static_cast (*pFaces[i]); result.addPResultFace(msegment,false); }// for }// addToResult void SourceUnit::intersection(SourceUnit& other, GlobalTimeValues& timeValues){ // Over all P-Face of the source. for (size_t i = 0; i < this->pFaces.size(); i++) { PFace* pFaceA = this->pFaces[i]; Rectangle<2> bRec = (*pFaceA).getBoundingRec(); bRec.Extend(NumericUtil::eps); // Iterator over all found P-PFace std::unique_ptr::iterator> it(other.pFaceTree.find(bRec)); size_t const* j; while ((j = it->next()) != 0) { PFace* pFaceB = other.pFaces[*j]; pFaceA->intersection(*pFaceB,timeValues); // cout << *pFaceA; // cout << *pFaceB; }// while if (pFaceA->existsIntSegs() || pFaceA->getState()==CRITICAL) { RationalPlane3D plane(*pFaceA); pFaceA->addBorder(plane,UNDEFINED); this->itersectedPFace.push_back(i); touchFaceCycleEntry(pFaceA); }// if }//for for (size_t j = 0; j < other.pFaces.size(); j++) { PFace* pFaceB =other.pFaces[j]; if (pFaceB->existsIntSegs() || pFaceB->getState()==CRITICAL) { RationalPlane3D plane(*pFaceB); pFaceB->addBorder(plane,UNDEFINED); other.itersectedPFace.push_back(j); other.touchFaceCycleEntry(pFaceB); }// if }// for // For cycles without cuts, a P-Face with reference predicates // is now inserted. checkFaceCycleEntrys(other); other.checkFaceCycleEntrys(*this); }// intersection void SourceUnit::intersectionFast(SourceUnit& other, GlobalTimeValues& timeValues){ // Over all P-Face of the source. for (size_t i = 0; i < this->pFaces.size(); i++) { PFace* pFaceA = this->pFaces[i]; Rectangle<2> bRec = (*pFaceA).getBoundingRec(); bRec.Extend(NumericUtil::eps); RationalPlane3D planeSelf(*pFaceA); // Iterator over all found P-PFace std::unique_ptr::iterator> it(other.pFaceTree.find(bRec)); size_t const* j; while ((j = it->next()) != 0) { PFace* pFaceB = other.pFaces[*j]; // No intersection if the bounding boxes do not intersect if (!(pFaceA->getBoundingRec().Intersects( pFaceB->getBoundingRec()))) { continue; }// if RationalPlane3D planeOther(*pFaceB); // check planes if (planeSelf.isParallelTo(planeOther)) { if (planeSelf.isCoplanarTo(planeOther)) { pFaceA->intersectionOnPlane(*pFaceB,planeSelf,timeValues); pFaceB->intersectionOnPlane(*pFaceA,planeOther,timeValues); }// if continue; }// if RationalPoint3DExtSet intPointSet; planeSelf.intersection(*pFaceB, UNIT_A, intPointSet); // We need exactly two intersection points. if (intPointSet.size() != 2) continue; planeOther.intersection(*pFaceA, UNIT_B, intPointSet); RationalSegment3D intSeg; // cout << intPointSet; if (!intPointSet.getIntersectionSegment(intSeg)) continue; IntersectionSegment iSeg; // create and save result segments pFaceA->addIntSeg(planeSelf,planeOther,intSeg,timeValues); pFaceB->addIntSeg(planeOther,planeSelf,intSeg,timeValues); }// while if (pFaceA->existsIntSegs() || pFaceA->getState()==CRITICAL) { pFaceA->addBorder(planeSelf,UNDEFINED); this->itersectedPFace.push_back(i); touchFaceCycleEntry(pFaceA); }// if }//for for (size_t j = 0; j < other.pFaces.size(); j++) { PFace* pFaceB =other.pFaces[j]; if (pFaceB->existsIntSegs() || pFaceB->getState()==CRITICAL) { RationalPlane3D planeOther(*pFaceB); pFaceB->addBorder(planeOther,UNDEFINED); other.itersectedPFace.push_back(j); other.touchFaceCycleEntry(pFaceB); }// if }// for // For cycles without cuts, a P-Face with reference predicates // is now inserted. checkFaceCycleEntrys(other); other.checkFaceCycleEntrys(*this); // cout << *this; // cout << other; }// intersectionFast bool SourceUnit::finalize(Point3DContainer& points, GlobalTimeValues& timeValues, Predicate predicate, SourceUnit& other){ vector ok = vector(pFaces.size(),false); // first process all P-Face with intersectionsegments for (size_t i = 0; i < this->itersectedPFace.size(); i++) { size_t index = itersectedPFace[i]; // cout << *this; if (!ok[index]) { ok[index] = this->pFaces[index]->finalize( points, this->segments,timeValues); }// if }// for // then process all P-Face without cutting segments forward bool finalize = true; for (size_t i = 0; i < this->pFaces.size(); i++) { if (!ok[i]) { this->pFaces[i]->addBorder(segments,predicate); bool result = this->pFaces[i]->finalize( points, this->segments,timeValues); if (!result) finalize = false; else ok[i] = result; }// if }// for if (finalize) return true; // and backward finalize = true; for (int i = this->pFaces.size()-1; i >= 0; i--) { if (!ok[i]) { this->pFaces[i]->addBorder(segments,predicate); bool result = this->pFaces[i]->finalize( points, this->segments,timeValues); if (!result) finalize = false; else ok[i] = result; }// if }// for if (finalize) return true; // Determine the position of the p-Face explicitly finalize = true; for (size_t i = 0; i < this->pFaces.size(); i++) { if (!ok[i] && this->pFaces[i]->getState() != CRITICAL){ // for non critical P-faces if (other.isInside(this->pFaces[i])) { this->pFaces[i]->setBorderPredicate(segments,INNER); }// if else { this->pFaces[i]->setBorderPredicate(segments,OUTER); }// else this->pFaces[i]->addBorder(segments,predicate); bool result = this->pFaces[i]->finalize( points, this->segments,timeValues); if (!result) finalize = false; else ok[i] = result; }// if }// for for (size_t i = 0; i < this->pFaces.size(); i++) { if (!ok[i] && this->pFaces[i]->getState() == CRITICAL){ // for critical P-faces this->pFaces[i]->addBorder(segments,predicate); bool result = this->pFaces[i]->finalize( points, this->segments,timeValues); if (result) ok[i] = result; }// if }// for if (finalize) return true; cerr << " Finalized Pfaces:= "; for (size_t i = 0; i< ok.size(); i++) { cerr << ok[i]; }// for cerr << endl; cerr << *this; NUM_FAIL("Finalize for Source Unit is not possible."); return false; }// finalize void SourceUnit::intersects(Point3DContainer& points, GlobalTimeValues& timeValues, SourceUnit& other, std::vector& predicates){ vector ok = vector(pFaces.size(),false); std::vector resultPredicates(timeValues.size()-1); predicates = std::vector(timeValues.size()-1,false); bool result = false; for (size_t i = 0; i < this->itersectedPFace.size(); i++) { size_t index = this->itersectedPFace[i]; if(this->pFaces[index]->intersects(points, timeValues, resultPredicates)){ for(size_t i = 0; i < resultPredicates.size(); i++){ // if(predicates[i]){ // cout << "Predicate intersects for slide " << i; // cout << ", true" <pFaces.size(); i++) { if (!ok[i] && this->pFaces[i]->getState() != CRITICAL){ if (other.isInside(this->pFaces[i])) { this->pFaces[i]->setBorderPredicate(segments,INNER); }// if else { this->pFaces[i]->setBorderPredicate(segments,OUTER); }// else this->pFaces[i]->intersects(points,timeValues,predicates); return; }// if }// for predicates = std::vector(timeValues.size()-1,true); }// intersects void SourceUnit::inside(Point3DContainer& points, GlobalTimeValues& timeValues, SourceUnit& other, std::vector& predicates){ vector ok = vector(pFaces.size(),false); std::vector resultPredicates(timeValues.size()-1); predicates = std::vector(timeValues.size()-1,true); bool result = false; for (size_t i = 0; i < this->itersectedPFace.size(); i++) { size_t index = itersectedPFace[i]; if(this->pFaces[index]->inside(points, timeValues, resultPredicates)){ for(size_t i = 0; i < resultPredicates.size(); i++){ // if(predicates[i]){ // cout << "Predicate inside for slide " << i; // cout << ", true" <pFaces.size(); i++) { if (!ok[i] && this->pFaces[i]->getState() != CRITICAL){ if (other.isInside(this->pFaces[i])) { this->pFaces[i]->setBorderPredicate(segments,INNER); }// if else { this->pFaces[i]->setBorderPredicate(segments,OUTER); }// else this->pFaces[i]->inside(points,timeValues,predicates); return; }// if }// for predicates = std::vector(timeValues.size()-1,true); }// inside void SourceUnit::getResultUnit(size_t slide, Predicate predicate, bool reverse, const Point3DContainer& points, ResultUnit& unit, SourceFlag source){ for (size_t i = 0; i < this->pFaces.size(); i++) { this->pFaces[i]->getResultUnit(slide,predicate,reverse,points,unit, source); }// for }// getResultPFace std::ostream& SourceUnit::print(std::ostream& os, std::string prefix)const{ os << "SourceUnit ("; if (segments.size() == 0) os << "is empty)" << endl; else { os << endl; os << prefix + " "; this->segments.print(os,prefix+" "); os << prefix << " PFaces (" << endl; for (size_t i = 0; i < pFaces.size(); i++) { os << prefix << " Index:=" << i << ", " ; this->pFaces[i]->print(os,prefix+" "); }// for os << prefix << " )"<segments == unit.segments)) return false; if (this->pFaces.size() != unit.pFaces.size()) return false; for (size_t i = 0; i < this->pFaces.size(); i++) { if (!(*(this->pFaces[i]) == *(unit.pFaces[i]))) return false; }// for return true; }// Operator == SourceUnit& SourceUnit::operator =(const SourceUnit& unit){ set(unit); return *this; }// Operator = bool SourceUnit::lessByMedianHS(const PFace* pf1, const PFace *pf2){ return pf1->lessByMedianHS(static_cast(*pf2)); }// return bool SourceUnit::logicLess(const PFace* pf1, const PFace *pf2){ return pf1->logicLess(static_cast(*pf2)); }// return void SourceUnit::reSort(){ size_t size = pFaces.size(); for (size_t i = 0; i < size; i++) { PFace* pf1 = pFaces[i]; Rectangle<2> boundigRec = pf1->getBoundingRec(); pFaceTree.erase(boundigRec,i); pf1->setLeftDomPoint(true); pf1->setSegmentNo(i); pFaces[i] = pf1; PFace* pf2 = new PFace(*pf1); pf2->setLeftDomPoint(false); pFaces.push_back(pf2); }// for sort(pFaces.begin(),pFaces.end(),SourceUnit::lessByMedianHS); this->testRegion.StartBulkLoad(); for (size_t i = 0; i < pFaces.size(); i++) { this->testRegion += pFaces[i]->getMedianHS(); }// for // Note: Sorting is already done. this->testRegion.EndBulkLoad(false, true, true, true); this->testRegionDefined = true; for (size_t i = 0; i < pFaces.size(); i++) { HalfSegment halfSegment; this->testRegion.Get(i, halfSegment); pFaces[i]->copyIndicesFrom(&halfSegment); }// for // Sort pFaces by faceno, cycleno and segmentno: sort(pFaces.begin(), pFaces.end(), SourceUnit::logicLess); // Erase the second half of prFaces, // which contains all PResultFaces with right dominating point: for (size_t i = pFaces.size()/2; i < pFaces.size(); i++) { delete pFaces[i]; }// for pFaces.erase(pFaces.begin() + pFaces.size()/2, pFaces.end()); // Rebuild R-Tree for (size_t i = 0; i < pFaces.size(); i++) { PFace* pf1 = pFaces[i]; Rectangle<2> boundigRec = pf1->getBoundingRec(); pFaceTree.insert(boundigRec,i); createFaceCycleEntry(pf1,i); }// for }// reSort void SourceUnit::createFaceCycleEntry(const PFace* pf, size_t index){ int segmentNo = pf->getSegmentNo(); int cycleNo = pf->getCycleNo(); int faceNo = pf->getFaceNo(); if(segmentNo == -1 || cycleNo == -1 || faceNo == -1){ NUM_FAIL("SegmentNo, CycleNo or FaceNo for a PFace schould not be -1."); }// if if (segmentNo == 0) { while (faceNo >= static_cast(faceCycleInfo.size())) { faceCycleInfo.push_back(vector()); }// while while (cycleNo >= static_cast(faceCycleInfo[faceNo].size())) { faceCycleInfo[faceNo].push_back(FaceCycleInfo()); }// while faceCycleInfo[faceNo][cycleNo].setFirstIndex(index); }// if }// checkIndizes void SourceUnit::touchFaceCycleEntry(const PFace* pf){ int cycleNo = pf->getCycleNo(); int faceNo = pf->getFaceNo(); if (cycleNo == -1 || faceNo == -1) return; if (faceNo < static_cast(faceCycleInfo.size())) { if (cycleNo < static_cast(faceCycleInfo[faceNo].size())) { faceCycleInfo[faceNo][cycleNo].setTouch(); }// if }//if }// touchFaceCycleSegment void SourceUnit::checkFaceCycleEntrys(SourceUnit& other){ for (size_t i = 0; i < faceCycleInfo.size(); i++) { for (size_t j = 0; j < faceCycleInfo[i].size();j++) { FaceCycleInfo info = faceCycleInfo[i][j]; if (!info.getTouch()){ if (!other.testRegionDefined) { other.createTestRegion(); }// if PFace* pFace = pFaces[info.getFirstIndex()]; if (other.isInside(pFace)) { pFace->setBorderPredicate(this->segments,INNER); }// if else { pFace->setBorderPredicate(this->segments,OUTER); }// else }// if }// for }// for }// checkFaceCycleEntrys void SourceUnit::printFaceCycleEntrys(){ for (size_t i = 0; i < faceCycleInfo.size(); i++) { for (size_t j = 0; j < faceCycleInfo[i].size();j++) { FaceCycleInfo info = faceCycleInfo[i][j]; cout << "FaceNo:=" << i << ", CycleNo:=" << j; cout << ", FirstIndex:=" << info.getFirstIndex(); if (info.getTouch()) { cout << ", Touch:=true"<< endl; }// if else { cout << ", Touch:=false"<< endl; }// else }// for }// for }// printFaceCycleInfo void SourceUnit::createTestRegion(){ this->testRegion.StartBulkLoad(); for (size_t i = 0; i < pFaces.size(); i++) { HalfSegment medianHS = pFaces[i]->getMedianHS(); medianHS.attr.edgeno = i; medianHS.attr.cycleno = -1; medianHS.attr.faceno = -1; medianHS.SetLeftDomPoint(false); this->testRegion += medianHS; medianHS.SetLeftDomPoint(true); this->testRegion += medianHS; }// for this->testRegion.EndBulkLoad(true, true, true, true); this->testRegionDefined = true; }// createTestRegion bool SourceUnit::isInside(const PFace* pFace) { if (!(this->testRegionDefined)) { createTestRegion(); }// if HalfSegment halfSegment = pFace->getMedianHS(); Point left = halfSegment.GetLeftPoint(); Point middle = halfSegment.middlePoint(); Point right = halfSegment.GetRightPoint(); Point nearleft = Point(true,(left.GetX()+middle.GetX())/2, (left.GetY()+middle.GetY())/2); Point nearright = Point(true,(right.GetX()+middle.GetX())/2, (right.GetY()+middle.GetY())/2); bool result1 = testRegion.Contains(nearleft); bool result2 = testRegion.Contains(middle); if(result1 == result2){ return result1; }// if else { bool result3 = testRegion.Contains(nearright); if (result1 == result2) return result1; else if (result1 == result3) return result1; return result2; }// else }// isInside /* 22 Class SourceUnitPair */ SourceUnitPair::SourceUnitPair(double orginalStartTime /* = 0*/, double orginalEndTime /* = 1 */, double scale /*= 1*/): timeValues(scale, orginalStartTime,orginalEndTime){ timeValues.addStartAndEndtime(); }// Konstruktor SourceUnitPair::SourceUnitPair(const Interval& orginalInterval): timeValues(orginalInterval){ }// Konstruktor void SourceUnitPair::setScaleFactor(double scale){ // cout << "Scale:=" << scale << endl; timeValues.setScaleFactor(scale); timeValues.addStartAndEndtime(); }// setScaleFactor void SourceUnitPair::addPFace(SourceFlag flag, Segment3D& leftSegment, Segment3D& rightSegment){ Point3D leftStart = leftSegment.getTail(); Point3D leftEnd = leftSegment.getHead(); Point3D rightStart= rightSegment.getTail(); Point3D rightEnd = rightSegment.getHead(); size_t iLeftStart = points.add(leftStart); size_t iLeftEnd = points.add(leftEnd); size_t iRightStart= points.add(rightStart); size_t iRightEnd = points.add(rightEnd); Segment left(iLeftStart, iLeftEnd, UNDEFINED); Segment right(iRightStart, iRightEnd, UNDEFINED); if (flag == UNIT_A) { unitA.addPFace(left,right,points); }// if else { unitB.addPFace(left,right,points); }// else }// addPFace void SourceUnitPair::addMSegmentData(const MSegmentData& mSeg, SourceFlag flag){ if (flag == UNIT_A){ unitA.addMSegmentData(mSeg, this->timeValues, points); }// if else { unitB.addMSegmentData(mSeg, this->timeValues, points); }// else }// addPFace std::ostream& SourceUnitPair::print(std::ostream& os, std::string prefix)const{ os << "SourceUnitPair (" << endl; os << prefix + " "; this->points.print(os, prefix+ " "); os << prefix + " "; this->timeValues.print(os, prefix +" "); os << prefix + " UnitA:= "; this->unitA.print(os, prefix + " "); os << prefix + " UnitB:= "; this->unitB.print(os, prefix + " "); if (result.size() == 0) os << prefix << " No result exist" << endl; else { os << prefix << " Result (" << endl; for (size_t i = 0; i < result.size(); i++) { os << prefix + " "; result[i].print(os, prefix + " "); }// for os << prefix +" )" << endl; }// if os << prefix + ")" << endl; return os; }// print std::ostream& operator <<(std::ostream& os, const SourceUnitPair& unitPair){ unitPair.print(os,""); return os; }// Operator << bool SourceUnitPair::operate(SetOp setOp){ if (unitA.isEmpty()|| unitB.isEmpty() || (!unitA.intersect(unitB))) { if (setOp == INTERSECTION) { // Result is empty: nothing to do. return false; }// if if (setOp == MINUS) { if (unitA.isEmpty()) { // Result is empty: nothing to do. return false; }// if // unitB is empty else { result = vector(1,ResultUnit()); // unitA.createResultUnit(result[0]); result[0] = ResultUnit(timeValues.getOrginalStartTime(), timeValues.getOrginalEndTime()); unitA.addToResultUnit(result[0]); result[0].finalize(); return false; }// if }// if // setOp == UNION result = vector(1,ResultUnit()); // unitA.createResultUnit(result[0]); result[0] = ResultUnit(timeValues.getOrginalStartTime(), timeValues.getOrginalEndTime()); unitA.addToResultUnit(result[0]); unitB.addToResultUnit(result[0]); result[0].finalize(); return false; }// if // Intersection // cout << "Start Intersection" << endl; // unitA.intersectionFast(unitB, timeValues); unitA.intersection(unitB, timeValues); // cout << "End Intersection" << endl; // Finalize bool inverseB = false; Predicate predicateA = OUTER; Predicate predicateB = OUTER; if (setOp == MINUS){ inverseB = true; predicateB = INNER; }// if else if (setOp == INTERSECTION){ predicateA = INNER; predicateB = INNER; }// else if // cout << points; // cout << setprecision(9) << timeValues; // cout << unitA; // cout << unitB; unitA.finalize(points, timeValues, predicateA, unitB); // cout << "End Finalize A" << endl; // cout << unitA; unitB.finalize(points, timeValues, predicateB, unitA); // cout << "End Finalize B" << endl; // cout << unitB; // get result Units if (timeValues.size() > 1){ result = vector(timeValues.size()-1, ResultUnit()); mpq_class t1,t2; size_t i = 0; timeValues.orginalFirst(t1,t2); // cout << "Units " << timeValues.size()-1 << endl; do{ result[i] = ResultUnit(t1.get_d(),t2.get_d()); unitA.getResultUnit(i,predicateA,false, points,result[i],UNIT_A); unitB.getResultUnit(i,predicateB,inverseB,points,result[i],UNIT_B); // cout << result[i] <& interval, MRegion* mregion, SourceFlag sourceFlag){ MRegion* temp; URegionEmb unitRestrict; URegionEmb* unit; const DbArray* array; Periods intervalAsPeriod(1); intervalAsPeriod.Add(interval); temp = new MRegion(1); temp->AtPeriods(&intervalAsPeriod, mregion); temp->Get(0, unitRestrict); array = temp->GetMSegmentData(); unit = new URegionEmb(unitRestrict.timeInterval, unitRestrict.GetStartPos()); unit->SetSegmentsNum(unitRestrict.GetSegmentsNum()); unit->SetBBox(unitRestrict.BoundingBox()); if(sourceFlag == UNIT_A) { Rectangle<3> bBox = unitRestrict.BoundingBox(); setScaleFactor(bBox.MaxD(0) - bBox.MinD(0)); }// if MSegmentData segment; for(int i = 0; i < unit->GetSegmentsNum();i++){ unit->GetSegment(array, i, segment); addMSegmentData(segment, sourceFlag); }// for delete temp; delete unit; }// CreateSourceUnit void SourceUnitPair::createResultMRegion(MRegion* resMRegion){ DbArray* array = (DbArray*)resMRegion->GetFLOB(1); for (size_t i = 0; i < result.size(); i++){ if (result[i].size()!=0) { Interval interval = result[i].getTimeInterval(); // do not generate degenerate time intervals if(interval.start != interval.end){ URegionEmb* ure = result[i].convertToURegionEmb(array); resMRegion->Add(*ure); delete ure; }// if }// if }// for }// createResultMRegion size_t SourceUnitPair::countResultUnits()const{ return result.size(); }// countResultUnits ResultUnit SourceUnitPair::getResultUnit(size_t slide)const{ return result[slide]; }// getResultUnit bool SourceUnitPair::predicate(PredicateOp predicateOp){ if (unitA.isEmpty()|| unitB.isEmpty()){ return false; }// if // Intersection unitA.intersection(unitB, timeValues); if (predicateOp == INTERSECTS){ unitA.intersects(points,timeValues,unitB,predicates); }// if else { unitA.inside(points,timeValues,unitB,predicates); }// else return false; }// predicate void SourceUnitPair::createResultMBool( MBool* resMBool, bool lc, bool rc){ if ((timeValues.size() > 1) && predicates.size() > 0){ mpq_class t1,t2,t3; // cout << " timeValues " << timeValues <timeValues.orginalFirst(t1,t2); bool value = predicates[0]; bool left = lc; size_t i = 1; while (timeValues.orginalNext(t2, t3)){ // cout << "t1:=" << t1 << endl; // cout << "t2:=" << t2 << endl; // if (predicates[i]) cout << "value:= true" << endl; // else cout << "value:= false" << endl; if(value != predicates[i]){ CcBool predicate(true, value); UBool ubool(timeValues.createInterval(t1.get_d(),t2.get_d(), left,false),predicate); resMBool->Add(ubool); left = true; value = predicates[i]; t1 = t2; }// if t2 = t3; i++; }// while CcBool predicate(true, value); Interval interval = timeValues.createInterval(t1.get_d(), t2.get_d(), true,rc); UBool ubool(interval, predicate); // do not generate degenerate time intervals if(interval.start != interval.end) resMBool->Add(ubool); }// if }// createResultMBool /* 23 class SetOperator */ SetOperator::SetOperator(MRegion* const _mRegionA, MRegion* const _mRegionB, MRegion* const _mRegionResult): mRegionA(_mRegionA), mRegionB(_mRegionB), mRegionResult(_mRegionResult){ }// Konstruktor void SetOperator::operate(SetOp setOp){ if (!mRegionA->IsDefined() || !mRegionB->IsDefined()) { mRegionResult->SetDefined(false); return; }// if // Compute the RefinementPartition of the two MRegions RefinementPartition< MRegion, MRegion, URegionEmb, URegionEmb> rp(*mRegionA, *mRegionB); // cout << "RefinementPartition with " << rp.Size() << " units created."; mRegionResult->Clear(); ((DbArray*)mRegionResult->GetFLOB(1))->clean(); mRegionResult->StartBulkLoad(); // For each interval of the refinement partition for (unsigned int i = 0; i < rp.Size(); i++) { Interval interval; int aPos, bPos; bool aIsEmpty, bIsEmpty; rp.Get(i, interval, aPos, bPos); SourceUnitPair unitPair(interval); if(interval.start == interval.end) continue; aIsEmpty = (aPos == -1); bIsEmpty = (bPos == -1); if (!aIsEmpty) { unitPair.createSourceUnit(interval, mRegionA, UNIT_A); }// if if (!bIsEmpty) { unitPair.createSourceUnit(interval, mRegionB, UNIT_B); }// if unitPair.operate(setOp); // cout << unitPair; unitPair.createResultMRegion( mRegionResult); }// for mRegionResult->EndBulkLoad(false); }// operate /* 24 class PredicateOperator */ PredicateOperator::PredicateOperator(MRegion* const _mRegionA, MRegion* const _mRegionB, MBool* const _mBool): mRegionA(_mRegionA), mRegionB(_mRegionB), mBool(_mBool){ }// Konstruktor void PredicateOperator::operate(PredicateOp predicateOp){ if (!mRegionA->IsDefined() || !mRegionB->IsDefined()) { mBool->SetDefined(false); return; }// if // Compute the RefinementPartition of the two MRegions RefinementPartition< MRegion, MRegion, URegionEmb, URegionEmb> rp(*mRegionA, *mRegionB); // cout << "RefinementPartition with " << rp.Size() << " units created."; mBool->Clear(); // For each interval of the refinement partition for (unsigned int i = 0; i < rp.Size(); i++) { Interval interval; int aPos, bPos; bool aIsEmpty, bIsEmpty; rp.Get(i, interval, aPos, bPos); SourceUnitPair unitPair(interval); if(interval.start == interval.end) continue; aIsEmpty = (aPos == -1); bIsEmpty = (bPos == -1); if (!aIsEmpty) { unitPair.createSourceUnit(interval, mRegionA, UNIT_A); }// if if (!bIsEmpty) { unitPair.createSourceUnit(interval, mRegionB, UNIT_B); }// if unitPair.predicate(predicateOp); unitPair.createResultMBool(mBool,interval.lc,interval.rc); }// for }// operate } // end of namespace mregionops3 } // end of namespace temporalalgebra