From f87ae66f2d43fffd257dfe7c8b723e597c2609ef Mon Sep 17 00:00:00 2001 From: Thomas Fischer <thomas.fischer@ufz.de> Date: Thu, 7 Apr 2016 21:02:32 +0200 Subject: [PATCH] [GL] Impl. of GeoLib::sortSegments(). --- GeoLib/AnalyticalGeometry.cpp | 47 +++++++++++++++++++++++++++++++++++ GeoLib/AnalyticalGeometry.h | 9 +++++++ 2 files changed, 56 insertions(+) diff --git a/GeoLib/AnalyticalGeometry.cpp b/GeoLib/AnalyticalGeometry.cpp index 4422f56d6f5..bf1a4f86264 100644 --- a/GeoLib/AnalyticalGeometry.cpp +++ b/GeoLib/AnalyticalGeometry.cpp @@ -706,4 +706,51 @@ lineSegmentIntersect2d(MathLib::Point3d const& a, MathLib::Point3d const& b, } } +void sortSegments( + MathLib::Point3d const& seg_beg_pnt, + std::vector<GeoLib::LineSegment>& sub_segments) +{ + double const eps(std::numeric_limits<double>::epsilon()); + + auto findNextSegment = [&eps]( + MathLib::Point3d const& seg_beg_pnt, + std::vector<GeoLib::LineSegment>& sub_segments, + std::vector<GeoLib::LineSegment>::iterator& sub_seg_it) + { + if (sub_seg_it == sub_segments.end()) + return; + // find appropriate segment for the given segment begin point + auto act_beg_seg_it = std::find_if( + sub_seg_it, sub_segments.end(), + [&seg_beg_pnt, &eps](GeoLib::LineSegment const& seg) + { + return MathLib::sqrDist(seg_beg_pnt, seg.getBeginPoint()) < eps || + MathLib::sqrDist(seg_beg_pnt, seg.getEndPoint()) < eps; + }); + if (act_beg_seg_it == sub_segments.end()) + return; + // if necessary correct orientation of segment, i.e. swap beg and end + if (MathLib::sqrDist(seg_beg_pnt, act_beg_seg_it->getEndPoint()) < + MathLib::sqrDist(seg_beg_pnt, act_beg_seg_it->getBeginPoint())) + std::swap(act_beg_seg_it->getBeginPoint(), + act_beg_seg_it->getEndPoint()); + assert(sub_seg_it != sub_segments.end()); + // exchange segments within the container + if (sub_seg_it != act_beg_seg_it) + std::swap(*sub_seg_it, *act_beg_seg_it); + }; + + // find start segment + auto seg_it = sub_segments.begin(); + findNextSegment(seg_beg_pnt, sub_segments, seg_it); + + while (seg_it != sub_segments.end()) + { + MathLib::Point3d & new_seg_beg_pnt(seg_it->getEndPoint()); + seg_it++; + if (seg_it != sub_segments.end()) + findNextSegment(new_seg_beg_pnt, sub_segments, seg_it); + } +} + } // end namespace GeoLib diff --git a/GeoLib/AnalyticalGeometry.h b/GeoLib/AnalyticalGeometry.h index ae7af19a7d9..a952d7f502c 100644 --- a/GeoLib/AnalyticalGeometry.h +++ b/GeoLib/AnalyticalGeometry.h @@ -384,6 +384,15 @@ void computeAndInsertAllIntersectionPoints(GeoLib::PointVec &pnt_vec, GeoLib::Polygon rotatePolygonToXY(GeoLib::Polygon const& polygon_in, MathLib::Vector3 & plane_normal); +/// Sorts the vector of segments such that the \f$i\f$-th segment is connected +/// with the \f$i+1\f$st segment, i.e. the end point of the \f$i\f$-th segment +/// is the start point of the \f$i+1\f$st segment. +/// The current implementation requires that all segments have to be +/// connectable. In order to obtain a unique result the segments are sorted such +/// that the begin point of the first segment is \c seg_beg_pnt. +void sortSegments(MathLib::Point3d const& seg_beg_pnt, + std::vector<GeoLib::LineSegment>& sub_segments); + } // end namespace GeoLib #include "AnalyticalGeometry-impl.h" -- GitLab