OGS
GeoLib Namespace Reference

Detailed Description

This module consists of classes governing geometric objects and related algorithms.

Namespaces

namespace  IO
 

Classes

class  AABB
 Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type PNT_TYPE. More...
 
class  DuplicateGeometry
 
class  EarClippingTriangulation
 
struct  GeoObject
 
class  GEOObjects
 Container class for geometric objects. More...
 
class  Grid
 
class  LineSegment
 
class  MinimalBoundingSphere
 
struct  MinMaxPoints
 
struct  NamedRaster
 
class  OctTree
 
class  Point
 
class  PointVec
 This class manages pointers to Points in a std::vector along with a name. It also handles the deletion of points. Furthermore, typically, PointVec objects are managed by GEOObjects using the instance name for identification. For this reason PointVec must have a unique name. More...
 
class  Polygon
 
class  PolygonWithSegmentMarker
 
class  Polyline
 Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices in the point vector. A polyline consists of at least one line segment. The polyline is specified by the points of the line segments. The class Polyline stores ids of pointers to the points in the _ply_pnt_ids vector. More...
 
class  PolylineWithSegmentMarker
 
class  QuadTree
 
class  Raster
 Class Raster is used for managing raster data. More...
 
struct  RasterHeader
 Contains the relevant information when storing a geoscientific raster data. More...
 
class  SimplePolygonTree
 This class computes and stores the topological relations between polygons. Every node of the SimplePolygonTree represents a polygon. A child node c of a parent node p mean that the polygon represented by c is contained in the polygon represented by p. More...
 
class  Station
 A Station (observation site) is basically a Point with some additional information. More...
 
class  StationBorehole
 A borehole as a geometric object. More...
 
class  Surface
 A Surface is represented by Triangles. It consists of a reference to a vector of (pointers to) points (_sfc_pnts) and a vector that stores the Triangles consisting of points from _sfc_pnts. More...
 
class  SurfaceGrid
 
class  TemplateVec
 The class TemplateVec takes a unique name and manages a std::vector of pointers to data elements of type T. More...
 
class  Triangle
 Class Triangle consists of a reference to a point vector and a vector that stores the indices in the point vector. A surface is composed by triangles. The class Surface stores the position of pointers to the points of triangles in the _pnt_ids vector. More...
 

Typedefs

using PolylineVec = TemplateVec<GeoLib::Polyline>
 class PolylineVec encapsulate a std::vector of Polylines additional one can give the vector of polylines a name
 
using SurfaceVec = TemplateVec<GeoLib::Surface>
 

Enumerations

enum  Orientation { CW = -1 , COLLINEAR = 0 , CCW = 1 }
 
enum class  GEOTYPE { POINT , POLYLINE , SURFACE }
 
enum class  Location {
  LEFT , RIGHT , BEYOND , BEHIND ,
  BETWEEN , SOURCE , DESTINATION
}
 
enum class  EdgeType { TOUCHING , CROSSING , INESSENTIAL }
 

Functions

template<typename InputIterator >
std::pair< Eigen::Vector3d, double > getNewellPlane (InputIterator pnts_begin, InputIterator pnts_end)
 
template<class T_POINT >
std::pair< Eigen::Vector3d, double > getNewellPlane (const std::vector< T_POINT * > &pnts)
 
template<class T_POINT >
std::pair< Eigen::Vector3d, double > getNewellPlane (const std::vector< T_POINT > &pnts)
 
template<typename InputIterator >
void rotatePoints (Eigen::Matrix3d const &rot_mat, InputIterator pnts_begin, InputIterator pnts_end)
 
template<typename InputIterator1 , typename InputIterator2 >
Eigen::Matrix3d rotatePointsToXY (InputIterator1 p_pnts_begin, InputIterator1 p_pnts_end, InputIterator2 r_pnts_begin, InputIterator2 r_pnts_end)
 
template<typename P >
void rotatePoints (Eigen::Matrix3d const &rot_mat, std::vector< P * > const &pnts)
 
Orientation getOrientation (MathLib::Point3d const &p0, MathLib::Point3d const &p1, MathLib::Point3d const &p2)
 
Orientation getOrientationFast (MathLib::Point3d const &p0, MathLib::Point3d const &p1, MathLib::Point3d const &p2)
 
bool parallel (Eigen::Vector3d v, Eigen::Vector3d w)
 
bool lineSegmentIntersect (GeoLib::LineSegment const &s0, GeoLib::LineSegment const &s1, GeoLib::Point &s)
 
bool lineSegmentsIntersect (const GeoLib::Polyline *ply, GeoLib::Polyline::SegmentIterator &seg_it0, GeoLib::Polyline::SegmentIterator &seg_it1, GeoLib::Point &intersection_pnt)
 
void rotatePoints (Eigen::Matrix3d const &rot_mat, std::vector< GeoLib::Point * > &pnts)
 
Eigen::Matrix3d computeRotationMatrixToXY (Eigen::Vector3d const &n)
 
Eigen::Matrix3d rotatePointsToXY (std::vector< GeoLib::Point * > &pnts)
 
std::unique_ptr< GeoLib::PointtriangleLineIntersection (MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &c, MathLib::Point3d const &p, MathLib::Point3d const &q)
 
void computeAndInsertAllIntersectionPoints (GeoLib::PointVec &pnt_vec, std::vector< GeoLib::Polyline * > &plys)
 
std::tuple< std::vector< GeoLib::Point * >, Eigen::Vector3d > rotatePolygonPointsToXY (GeoLib::Polygon const &polygon_in)
 
std::vector< MathLib::Point3dlineSegmentIntersect2d (GeoLib::LineSegment const &ab, GeoLib::LineSegment const &cd)
 
void sortSegments (MathLib::Point3d const &seg_beg_pnt, std::vector< GeoLib::LineSegment > &sub_segments)
 
Eigen::Matrix3d compute2DRotationMatrixToX (Eigen::Vector3d const &v)
 
Eigen::Matrix3d compute3DRotationMatrixToX (Eigen::Vector3d const &v)
 
Eigen::Matrix3d rotatePointsToXY (std::vector< Point * > &pnts)
 
void computeAndInsertAllIntersectionPoints (PointVec &pnt_vec, std::vector< Polyline * > &plys)
 
void sortSegments (MathLib::Point3d const &seg_beg_pnt, std::vector< LineSegment > &sub_segments)
 
template<typename Container >
auto findVectorByName (Container const &container, std::string const &name)
 
void markUnusedPoints (GEOObjects const &geo_objects, std::string const &geo_name, std::vector< bool > &transfer_pnts)
 
int geoPointsToStations (GEOObjects &geo_objects, std::string const &geo_name, std::string &stn_name, bool const only_unused_pnts=true)
 Constructs a station-vector based on the points of a given geometry.
 
std::string convertGeoTypeToString (GEOTYPE geo_type)
 
std::ostream & operator<< (std::ostream &os, LineSegment const &s)
 
std::ostream & operator<< (std::ostream &os, std::pair< GeoLib::LineSegment const &, GeoLib::LineSegment const & > const &seg_pair)
 
bool operator== (LineSegment const &s0, LineSegment const &s1)
 
Location getLocationOfPoint (MathLib::Point3d const &source, MathLib::Point3d const &destination, MathLib::Point3d const &pnt)
 
EdgeType getEdgeType (MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &pnt)
 
std::vector< GeoLib::PointgetAllIntersectionPoints (Polygon const &polygon, GeoLib::LineSegment const &segment)
 
bool operator== (Polygon const &lhs, Polygon const &rhs)
 
void resetPointIDs (Polyline &polyline, std::vector< std::size_t > const &mapping)
 Resets the point IDs of the polyline corresponding to the mapping.
 
void markUsedPoints (Polyline const &polyline, std::vector< bool > &used_points)
 Resets the point IDs of the polyline corresponding to the mapping.
 
bool containsEdge (const Polyline &ply, std::size_t id0, std::size_t id1)
 
bool operator== (Polyline const &lhs, Polyline const &rhs)
 
bool pointsAreIdentical (const std::vector< Point * > &pnt_vec, std::size_t i, std::size_t j, double prox)
 
std::unique_ptr< PolylinecreatePolyline (GeoLib::PointVec const &points_vec, std::vector< std::size_t > &&point_ids)
 Create a polyline from given point ids.
 
template<typename POLYGONTREETYPE >
void createPolygonTrees (std::list< POLYGONTREETYPE * > &list_of_simple_polygon_hierarchies)
 
bool isStation (GeoLib::Point const *pnt)
 
bool isBorehole (GeoLib::Point const *pnt)
 
bool operator== (Surface const &lhs, Surface const &rhs)
 
void resetPointIDs (Surface &surface, std::vector< std::size_t > const &mapping)
 Resets the point IDs of the surface corresponding to the mapping.
 
void markUsedPoints (Surface const &surface, std::vector< bool > &used_points)
 
std::vector< GeoLib::Point * > generateEquidistantPoints (MathLib::Point3d const &begin, MathLib::Point3d const &end, int const number_of_subdivisions)
 

Typedef Documentation

◆ PolylineVec

class PolylineVec encapsulate a std::vector of Polylines additional one can give the vector of polylines a name

Definition at line 27 of file PolylineVec.h.

◆ SurfaceVec

Class SurfaceVec encapsulate a std::vector of Surfaces and a name.

Definition at line 28 of file SurfaceVec.h.

Enumeration Type Documentation

◆ EdgeType

enum class GeoLib::EdgeType
strong

edge classification

Enumerator
TOUCHING 

TOUCHING.

CROSSING 

CROSSING.

INESSENTIAL 

INESSENTIAL.

Definition at line 39 of file Polygon.cpp.

40{
41 TOUCHING,
42 CROSSING,
44};
@ INESSENTIAL
INESSENTIAL.
@ CROSSING
CROSSING.
@ TOUCHING
TOUCHING.

◆ GEOTYPE

enum class GeoLib::GEOTYPE
strong
Enumerator
POINT 
POLYLINE 
SURFACE 

Definition at line 22 of file GeoType.h.

◆ Location

enum class GeoLib::Location
strong
Enumerator
LEFT 
RIGHT 
BEYOND 
BEHIND 
BETWEEN 
SOURCE 
DESTINATION 

Definition at line 25 of file Polygon.cpp.

◆ Orientation

Enumerator
CW 
COLLINEAR 
CCW 

Definition at line 24 of file AnalyticalGeometry.h.

25{
26 CW = -1,
27 COLLINEAR = 0,
28 CCW = 1
29};

Function Documentation

◆ compute2DRotationMatrixToX()

Eigen::Matrix3d GeoLib::compute2DRotationMatrixToX ( Eigen::Vector3d const & v)

Computes a rotation matrix that rotates the given 2D normal vector parallel to X-axis

Parameters
va 2D normal vector to be rotated
Returns
a 3x3 rotation matrix where the upper, left, 2x2 block contains the entries necessary for the 2D rotation

Definition at line 695 of file AnalyticalGeometry.cpp.

696{
697 Eigen::Matrix3d rot_mat = Eigen::Matrix3d::Zero();
698 const double cos_theta = v[0];
699 const double sin_theta = v[1];
700 rot_mat(0, 0) = rot_mat(1, 1) = cos_theta;
701 rot_mat(0, 1) = sin_theta;
702 rot_mat(1, 0) = -sin_theta;
703 rot_mat(2, 2) = 1.0;
704 return rot_mat;
705}

Referenced by detail::getRotationMatrixToGlobal().

◆ compute3DRotationMatrixToX()

Eigen::Matrix3d GeoLib::compute3DRotationMatrixToX ( Eigen::Vector3d const & v)

Computes a rotation matrix that rotates the given 3D normal vector parallel to X-axis.

Parameters
va 3D normal vector to be rotated
Returns
a 3x3 rotation matrix

Definition at line 707 of file AnalyticalGeometry.cpp.

708{
709 // a vector on the plane
710 Eigen::Vector3d yy = Eigen::Vector3d::Zero();
711 auto const eps = std::numeric_limits<double>::epsilon();
712 if (std::abs(v[0]) > 0.0 && std::abs(v[1]) + std::abs(v[2]) < eps)
713 {
714 yy[2] = 1.0;
715 }
716 else if (std::abs(v[1]) > 0.0 && std::abs(v[0]) + std::abs(v[2]) < eps)
717 {
718 yy[0] = 1.0;
719 }
720 else if (std::abs(v[2]) > 0.0 && std::abs(v[0]) + std::abs(v[1]) < eps)
721 {
722 yy[1] = 1.0;
723 }
724 else
725 {
726 for (unsigned i = 0; i < 3; i++)
727 {
728 if (std::abs(v[i]) > 0.0)
729 {
730 yy[i] = -v[i];
731 break;
732 }
733 }
734 }
735 // z"_vec
736 Eigen::Vector3d const zz = v.cross(yy).normalized();
737 // y"_vec
738 yy = zz.cross(v).normalized();
739
740 Eigen::Matrix3d rot_mat;
741 rot_mat.row(0) = v;
742 rot_mat.row(1) = yy;
743 rot_mat.row(2) = zz;
744 return rot_mat;
745}

Referenced by detail::getRotationMatrixToGlobal().

◆ computeAndInsertAllIntersectionPoints() [1/2]

void GeoLib::computeAndInsertAllIntersectionPoints ( PointVec & pnt_vec,
std::vector< Polyline * > & plys )

Method first computes the intersection points of line segments of Polyline objects (

See also
computeIntersectionPoints()) and pushes each intersection point in the PointVec pnt_vec. For each intersection an id is returned. This id is used to split the two intersecting straight line segments in four straight line segments.

Definition at line 402 of file AnalyticalGeometry.cpp.

404{
405 auto computeSegmentIntersections =
406 [&pnt_vec](GeoLib::Polyline& poly0, GeoLib::Polyline& poly1)
407 {
408 for (auto seg0_it(poly0.begin()); seg0_it != poly0.end(); ++seg0_it)
409 {
410 for (auto seg1_it(poly1.begin()); seg1_it != poly1.end(); ++seg1_it)
411 {
412 GeoLib::Point s(0.0, 0.0, 0.0, pnt_vec.size());
413 if (lineSegmentIntersect(*seg0_it, *seg1_it, s))
414 {
415 std::size_t const id(
416 pnt_vec.push_back(new GeoLib::Point(s)));
417 poly0.insertPoint(seg0_it.getSegmentNumber() + 1, id);
418 poly1.insertPoint(seg1_it.getSegmentNumber() + 1, id);
419 }
420 }
421 }
422 };
423
424 for (auto it0(plys.begin()); it0 != plys.end(); ++it0)
425 {
426 auto it1(it0);
427 ++it1;
428 for (; it1 != plys.end(); ++it1)
429 {
430 computeSegmentIntersections(*(*it0), *(*it1));
431 }
432 }
433}
std::size_t push_back(Point *pnt)
Definition PointVec.cpp:133
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition Polyline.h:40
virtual bool insertPoint(std::size_t pos, std::size_t pnt_id)
Definition Polyline.cpp:55
SegmentIterator begin() const
Definition Polyline.h:188
SegmentIterator end() const
Definition Polyline.h:190
std::size_t size() const
bool lineSegmentIntersect(GeoLib::LineSegment const &s0, GeoLib::LineSegment const &s1, GeoLib::Point &s)

References GeoLib::Polyline::begin(), GeoLib::Polyline::end(), GeoLib::Polyline::insertPoint(), lineSegmentIntersect(), GeoLib::PointVec::push_back(), and GeoLib::TemplateVec< T >::size().

Referenced by FileIO::GMSH::GMSHInterface::writeGMSHInputFile().

◆ computeAndInsertAllIntersectionPoints() [2/2]

void GeoLib::computeAndInsertAllIntersectionPoints ( PointVec & pnt_vec,
std::vector< Polyline * > & plys )

Method first computes the intersection points of line segments of Polyline objects (

See also
computeIntersectionPoints()) and pushes each intersection point in the PointVec pnt_vec. For each intersection an id is returned. This id is used to split the two intersecting straight line segments in four straight line segments.

Definition at line 402 of file AnalyticalGeometry.cpp.

404{
405 auto computeSegmentIntersections =
406 [&pnt_vec](GeoLib::Polyline& poly0, GeoLib::Polyline& poly1)
407 {
408 for (auto seg0_it(poly0.begin()); seg0_it != poly0.end(); ++seg0_it)
409 {
410 for (auto seg1_it(poly1.begin()); seg1_it != poly1.end(); ++seg1_it)
411 {
412 GeoLib::Point s(0.0, 0.0, 0.0, pnt_vec.size());
413 if (lineSegmentIntersect(*seg0_it, *seg1_it, s))
414 {
415 std::size_t const id(
416 pnt_vec.push_back(new GeoLib::Point(s)));
417 poly0.insertPoint(seg0_it.getSegmentNumber() + 1, id);
418 poly1.insertPoint(seg1_it.getSegmentNumber() + 1, id);
419 }
420 }
421 }
422 };
423
424 for (auto it0(plys.begin()); it0 != plys.end(); ++it0)
425 {
426 auto it1(it0);
427 ++it1;
428 for (; it1 != plys.end(); ++it1)
429 {
430 computeSegmentIntersections(*(*it0), *(*it1));
431 }
432 }
433}

References GeoLib::Polyline::begin(), GeoLib::Polyline::end(), GeoLib::Polyline::insertPoint(), lineSegmentIntersect(), GeoLib::PointVec::push_back(), and GeoLib::TemplateVec< T >::size().

Referenced by FileIO::GMSH::GMSHInterface::writeGMSHInputFile().

◆ computeRotationMatrixToXY()

Eigen::Matrix3d GeoLib::computeRotationMatrixToXY ( Eigen::Vector3d const & n)

Method computes the rotation matrix that rotates the given vector parallel to the \(z\) axis.

Parameters
nthe (3d) vector that is rotated parallel to the \(z\) axis
Returns
rot_mat 3x3 rotation matrix

Definition at line 299 of file AnalyticalGeometry.cpp.

300{
301 Eigen::Matrix3d rot_mat = Eigen::Matrix3d::Zero();
302 // check if normal points already in the right direction
303 if (n[0] == 0 && n[1] == 0)
304 {
305 rot_mat(1, 1) = 1.0;
306
307 if (n[2] > 0)
308 {
309 // identity matrix
310 rot_mat(0, 0) = 1.0;
311 rot_mat(2, 2) = 1.0;
312 }
313 else
314 {
315 // rotate by pi about the y-axis
316 rot_mat(0, 0) = -1.0;
317 rot_mat(2, 2) = -1.0;
318 }
319
320 return rot_mat;
321 }
322
323 // sqrt (n_1^2 + n_3^2)
324 double const h0(std::sqrt(n[0] * n[0] + n[2] * n[2]));
325
326 // In case the x and z components of the normal are both zero the rotation
327 // to the x-z-plane is not required, i.e. only the rotation in the z-axis is
328 // required. The angle is either pi/2 or 3/2*pi. Thus the components of
329 // rot_mat are as follows.
330 if (h0 < std::numeric_limits<double>::epsilon())
331 {
332 rot_mat(0, 0) = 1.0;
333 if (n[1] > 0)
334 {
335 rot_mat(1, 2) = -1.0;
336 rot_mat(2, 1) = 1.0;
337 }
338 else
339 {
340 rot_mat(1, 2) = 1.0;
341 rot_mat(2, 1) = -1.0;
342 }
343 return rot_mat;
344 }
345
346 double const h1(1 / n.norm());
347
348 // general case: calculate entries of rotation matrix
349 rot_mat(0, 0) = n[2] / h0;
350 rot_mat(0, 1) = 0;
351 rot_mat(0, 2) = -n[0] / h0;
352 rot_mat(1, 0) = -n[1] * n[0] / h0 * h1;
353 rot_mat(1, 1) = h0 * h1;
354 rot_mat(1, 2) = -n[1] * n[2] / h0 * h1;
355 rot_mat(2, 0) = n[0] * h1;
356 rot_mat(2, 1) = n[1] * h1;
357 rot_mat(2, 2) = n[2] * h1;
358
359 return rot_mat;
360}

Referenced by detail::getRotationMatrixToGlobal(), MeshGeoToolsLib::markNodesOutSideOfPolygon(), rotateGeometryToXY(), rotatePointsToXY(), and rotatePolygonPointsToXY().

◆ containsEdge()

bool GeoLib::containsEdge ( const Polyline & ply,
std::size_t id0,
std::size_t id1 )

Definition at line 505 of file Polyline.cpp.

506{
507 if (id0 == id1)
508 {
509 ERR("no valid edge id0 == id1 == {:d}.", id0);
510 return false;
511 }
512 if (id0 > id1)
513 {
514 std::swap(id0, id1);
515 }
516 const std::size_t n(ply.getNumberOfPoints() - 1);
517 for (std::size_t k(0); k < n; k++)
518 {
519 std::size_t ply_pnt0(ply.getPointID(k));
520 std::size_t ply_pnt1(ply.getPointID(k + 1));
521 if (ply_pnt0 > ply_pnt1)
522 {
523 std::swap(ply_pnt0, ply_pnt1);
524 }
525 if (ply_pnt0 == id0 && ply_pnt1 == id1)
526 {
527 return true;
528 }
529 }
530 return false;
531}
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:45
std::size_t getPointID(std::size_t const i) const
Definition Polyline.cpp:160
std::size_t getNumberOfPoints() const
Definition Polyline.cpp:109

References ERR(), GeoLib::Polyline::getNumberOfPoints(), and GeoLib::Polyline::getPointID().

Referenced by FileIO::GMSH::GMSHPolygonTree::markSharedSegments(), and FileIO::GMSH::GMSHPolygonTree::writeLineConstraints().

◆ convertGeoTypeToString()

std::string GeoLib::convertGeoTypeToString ( GEOTYPE geo_type)

Definition at line 23 of file GeoType.cpp.

24{
25 switch (geo_type)
26 {
27 case GEOTYPE::POINT:
28 return "POINT";
29 case GEOTYPE::POLYLINE:
30 return "POLYLINE";
31 case GEOTYPE::SURFACE:
32 return "SURFACE";
33 }
34
35 // Cannot happen, because switch covers all cases.
36 // Used to silence compiler warning.
37 OGS_FATAL("convertGeoTypeToString(): Given geo type is not supported");
38}
#define OGS_FATAL(...)
Definition Error.h:26

References OGS_FATAL, POINT, POLYLINE, and SURFACE.

Referenced by GEOModels::addNameForElement(), GEOModels::addNameForObjectPoints(), GeoLib::GEOObjects::getGeoObject(), and MainWindow::showGeoNameDialog().

◆ createPolygonTrees()

template<typename POLYGONTREETYPE >
void GeoLib::createPolygonTrees ( std::list< POLYGONTREETYPE * > & list_of_simple_polygon_hierarchies)

creates from a list of simple polygons a list of trees (SimplePolygonTrees)

Definition at line 90 of file SimplePolygonTree.h.

92{
93 for (auto it0 = list_of_simple_polygon_hierarchies.begin();
94 it0 != list_of_simple_polygon_hierarchies.end();
95 ++it0)
96 {
97 auto it1 = list_of_simple_polygon_hierarchies.begin();
98 while (it1 != list_of_simple_polygon_hierarchies.end())
99 {
100 if (it0 == it1)
101 { // don't check same polygons
102 ++it1;
103 // skip test if it1 points to the end after increment
104 if (it1 == list_of_simple_polygon_hierarchies.end())
105 {
106 break;
107 }
108 }
109 if ((*it0)->isPolygonInside(*it1))
110 {
111 (*it0)->insertSimplePolygonTree(*it1);
112 it1 = list_of_simple_polygon_hierarchies.erase(it1);
113 }
114 else
115 {
116 ++it1;
117 }
118 }
119 }
120}

◆ createPolyline()

std::unique_ptr< Polyline > GeoLib::createPolyline ( GeoLib::PointVec const & points_vec,
std::vector< std::size_t > && point_ids )

Create a polyline from given point ids.

Definition at line 564 of file Polyline.cpp.

566{
567 auto const& point_id_map = points_vec.getIDMap();
568 auto polyline = std::make_unique<Polyline>(points_vec.getVector());
569 for (auto point_id : point_ids)
570 {
571 if (point_id >= point_id_map.size())
572 {
573 WARN("The point id {} doesn't exist in the underlying PointVec.",
574 point_id);
575 continue;
576 }
577 polyline->addPoint(point_id_map[point_id]);
578 }
579 return polyline;
580}
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40

References GeoLib::PointVec::getIDMap(), GeoLib::TemplateVec< T >::getVector(), and WARN().

Referenced by generatePolylineGeometry(), and generateQuadGeometry().

◆ findVectorByName()

template<typename Container >
auto GeoLib::findVectorByName ( Container const & container,
std::string const & name )

Function to find PointVec, PolylineVec, or SurfaceVec pointers that are stored in the container

Definition at line 28 of file GEOObjects.cpp.

29{
30 return std::find_if(container.begin(), container.end(),
31 [&name](auto const* vector)
32 { return vector->getName() == name; });
33}

Referenced by GeoLib::GEOObjects::appendPolylineVec(), GeoLib::GEOObjects::appendSurfaceVec(), GeoLib::GEOObjects::exists(), GeoLib::GEOObjects::getSurfaceVec(), GeoLib::GEOObjects::getSurfaceVecObj(), GeoLib::GEOObjects::isPntVecUsed(), GeoLib::GEOObjects::removeSurfaceVec(), and GeoLib::GEOObjects::renameGeometry().

◆ generateEquidistantPoints()

std::vector< GeoLib::Point * > GeoLib::generateEquidistantPoints ( MathLib::Point3d const & begin,
MathLib::Point3d const & end,
int const number_of_subdivisions )

Function generates equidistant points in the interval [begin, end] according to the given number of subdivisions. In case of zero subdivisions a vector containing the begin and the end point is returned.

Definition at line 18 of file Utils.cpp.

21{
22 if (number_of_subdivisions < 0)
23 {
25 "generateEquidistantPoints: number of subdivisions is required to "
26 "be non-negative.");
27 }
28
29 auto const& start = begin.asEigenVector3d();
30 auto const& stop = end.asEigenVector3d();
31 auto const delta = (stop - start) / (number_of_subdivisions + 1);
32
33 std::vector<GeoLib::Point*> points;
34
35 for (int i = 0; i <= number_of_subdivisions; ++i)
36 {
37 auto const p = start + i * delta;
38 points.push_back(new GeoLib::Point{p[0], p[1], p[2]});
39 }
40 points.push_back(new GeoLib::Point{stop[0], stop[1], stop[2]});
41
42 return points;
43}

References MathLib::Point3d::asEigenVector3d(), and OGS_FATAL.

Referenced by generatePolylineGeometry(), and generateQuadPoints().

◆ geoPointsToStations()

int GeoLib::geoPointsToStations ( GEOObjects & geo_objects,
std::string const & geo_name,
std::string & stn_name,
bool const only_unused_pnts )

Constructs a station-vector based on the points of a given geometry.

Definition at line 611 of file GEOObjects.cpp.

613{
614 GeoLib::PointVec const* const pnt_obj(geo_objects.getPointVecObj(geo_name));
615 if (pnt_obj == nullptr)
616 {
617 ERR("Point vector {:s} not found.", geo_name);
618 return -1;
619 }
620 auto const& pnts = pnt_obj->getVector();
621 if (pnts.empty())
622 {
623 ERR("Point vector {:s} is empty.", geo_name);
624 return -1;
625 }
626 std::size_t const n_pnts(pnts.size());
627 std::vector<bool> transfer_pnts(n_pnts, true);
628 if (only_unused_pnts)
629 {
630 markUnusedPoints(geo_objects, geo_name, transfer_pnts);
631 }
632
633 std::vector<GeoLib::Point*> stations;
634 for (std::size_t i = 0; i < n_pnts; ++i)
635 {
636 if (!transfer_pnts[i])
637 {
638 continue;
639 }
640 std::string name = pnt_obj->getItemNameByID(i);
641 if (name.empty())
642 {
643 name = "Station " + std::to_string(i);
644 }
645 stations.push_back(new GeoLib::Station(pnts[i], name));
646 }
647 if (!stations.empty())
648 {
649 geo_objects.addStationVec(std::move(stations), stn_name);
650 }
651 else
652 {
653 WARN("No points found to convert.");
654 return 1;
655 }
656 return 0;
657}
const PointVec * getPointVecObj(const std::string &name) const
void addStationVec(std::vector< Point * > &&stations, std::string &name)
Adds a vector of stations with the given name and colour to GEOObjects.
This class manages pointers to Points in a std::vector along with a name. It also handles the deletio...
Definition PointVec.h:36
A Station (observation site) is basically a Point with some additional information.
Definition Station.h:37
void markUnusedPoints(GEOObjects const &geo_objects, std::string const &geo_name, std::vector< bool > &transfer_pnts)

References GeoLib::GEOObjects::addStationVec(), ERR(), GeoLib::PointVec::getItemNameByID(), GeoLib::GEOObjects::getPointVecObj(), GeoLib::TemplateVec< T >::getVector(), markUnusedPoints(), and WARN().

Referenced by MainWindow::convertPointsToStations().

◆ getAllIntersectionPoints()

std::vector< GeoLib::Point > GeoLib::getAllIntersectionPoints ( Polygon const & polygon,
GeoLib::LineSegment const & segment )

Computes all intersections of the straight line segment and the polyline boundary

Parameters
polygonthe polygon the segment line segment that will be processed
segmentthe line segment that will be processed
Returns
a possible empty vector containing the intersection points

Definition at line 190 of file Polygon.cpp.

192{
193 std::vector<GeoLib::Point> intersections;
195 for (auto&& seg_it : polygon)
196 {
197 if (GeoLib::lineSegmentIntersect(seg_it, segment, s))
198 {
199 intersections.push_back(s);
200 }
201 }
202
203 return intersections;
204}

References lineSegmentIntersect().

Referenced by GeoLib::Polygon::containsSegment().

◆ getEdgeType()

EdgeType GeoLib::getEdgeType ( MathLib::Point3d const & a,
MathLib::Point3d const & b,
MathLib::Point3d const & pnt )

from book: Computational Geometry and Computer Graphics in C++, page 119 get the type of edge with respect to the given point (2d method!)

Parameters
afirst point of line segment
blast point of line segment
pntpoint that is edge type computed for
Returns
a value of enum EdgeType

Definition at line 103 of file Polygon.cpp.

106{
107 switch (getLocationOfPoint(a, b, pnt))
108 {
109 case Location::LEFT:
110 {
111 if (a[1] < pnt[1] && pnt[1] <= b[1])
112 {
113 return EdgeType::CROSSING;
114 }
115
116 return EdgeType::INESSENTIAL;
117 }
118 case Location::RIGHT:
119 {
120 if (b[1] < pnt[1] && pnt[1] <= a[1])
121 {
122 return EdgeType::CROSSING;
123 }
124
125 return EdgeType::INESSENTIAL;
126 }
127 case Location::BETWEEN:
128 case Location::SOURCE:
129 case Location::DESTINATION:
130 return EdgeType::TOUCHING;
131 default:
132 return EdgeType::INESSENTIAL;
133 }
134}
Location getLocationOfPoint(MathLib::Point3d const &source, MathLib::Point3d const &destination, MathLib::Point3d const &pnt)
Definition Polygon.cpp:56

References BETWEEN, CROSSING, DESTINATION, getLocationOfPoint(), INESSENTIAL, LEFT, RIGHT, SOURCE, and TOUCHING.

Referenced by GeoLib::Polygon::isPntInPolygon().

◆ getLocationOfPoint()

Location GeoLib::getLocationOfPoint ( MathLib::Point3d const & source,
MathLib::Point3d const & destination,
MathLib::Point3d const & pnt )

2D method - ignores z coordinate. It calculates the location of the point relative to the line segment specified by the points source and destination. (literature reference: Computational Geometry and Computer Graphics in C++; Michael J. Laszlo)

Parameters
sourcethe first point of the line segment
destinationthe end point of the line segment
pntthe test point
Returns
a value of enum Location

Definition at line 56 of file Polygon.cpp.

59{
60 long double const a[2] = {destination[0] - source[0],
61 destination[1] - source[1]}; // vector
62 long double const b[2] = {pnt[0] - source[0],
63 pnt[1] - source[1]}; // vector
64
65 long double const det_2x2(a[0] * b[1] - a[1] * b[0]);
66 constexpr double eps = std::numeric_limits<double>::epsilon();
67
68 if (det_2x2 > eps)
69 {
70 return Location::LEFT;
71 }
72 if (eps < std::abs(det_2x2))
73 {
74 return Location::RIGHT;
75 }
76 if (a[0] * b[0] < 0.0 || a[1] * b[1] < 0.0)
77 {
78 return Location::BEHIND;
79 }
80 if (a[0] * a[0] + a[1] * a[1] < b[0] * b[0] + b[1] * b[1])
81 {
82 return Location::BEYOND;
83 }
84 if (MathLib::sqrDist(pnt, source) < pow(eps, 2))
85 {
86 return Location::SOURCE;
87 }
88 if (MathLib::sqrDist(pnt, destination) < std::sqrt(eps))
89 {
90 return Location::DESTINATION;
91 }
92 return Location::BETWEEN;
93}
double sqrDist(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.cpp:26

References BEHIND, BETWEEN, BEYOND, DESTINATION, LEFT, RIGHT, SOURCE, and MathLib::sqrDist().

Referenced by getEdgeType().

◆ getNewellPlane() [1/3]

template<class T_POINT >
std::pair< Eigen::Vector3d, double > GeoLib::getNewellPlane ( const std::vector< T_POINT * > & pnts)

Compute a supporting plane (represented by plane_normal and the value d) for the polygon. Let \(n\) be the plane normal and \(d\) a parameter. Then for all points \(p \in R^3\) of the plane it holds \( n \cdot p + d = 0\). The Newell algorithm is described in [14] .

Parameters
pntspoints of a closed polyline describing a polygon
Returns
pair of plane_normal and the parameter d: the normal of the plane the polygon is located in, parameter d from the plane equation

Definition at line 46 of file AnalyticalGeometry-impl.h.

48{
49 return getNewellPlane(pnts.begin(), pnts.end());
50}
std::pair< Eigen::Vector3d, double > getNewellPlane(InputIterator pnts_begin, InputIterator pnts_end)

References getNewellPlane().

◆ getNewellPlane() [2/3]

template<class T_POINT >
std::pair< Eigen::Vector3d, double > GeoLib::getNewellPlane ( const std::vector< T_POINT > & pnts)

Same as getNewellPlane(pnts).

Definition at line 53 of file AnalyticalGeometry-impl.h.

55{
56 Eigen::Vector3d plane_normal({0, 0, 0});
57 Eigen::Vector3d centroid({0, 0, 0});
58 std::size_t n_pnts(pnts.size());
59 for (std::size_t i = n_pnts - 1, j = 0; j < n_pnts; i = j, j++)
60 {
61 plane_normal[0] += (pnts[i][1] - pnts[j][1]) *
62 (pnts[i][2] + pnts[j][2]); // projection on yz
63 plane_normal[1] += (pnts[i][2] - pnts[j][2]) *
64 (pnts[i][0] + pnts[j][0]); // projection on xz
65 plane_normal[2] += (pnts[i][0] - pnts[j][0]) *
66 (pnts[i][1] + pnts[j][1]); // projection on xy
67
68 centroid += pnts[j].asEigenVector3d();
69 }
70
71 plane_normal.normalize();
72 double const d = centroid.dot(plane_normal) / n_pnts;
73 return std::make_pair(plane_normal, d);
74}

◆ getNewellPlane() [3/3]

template<typename InputIterator >
std::pair< Eigen::Vector3d, double > GeoLib::getNewellPlane ( InputIterator pnts_begin,
InputIterator pnts_end )

Compute a supporting plane (represented by plane_normal and the value d) for the polygon. Let \(n\) be the plane normal and \(d\) a parameter. Then for all points \(p \in R^3\) of the plane it holds \( n \cdot p + d = 0\). The Newell algorithm is described in [14] .

Parameters
pnts_beginIterator pointing to the initial point of a closed polyline describing a polygon
pnts_endIterator pointing to the element following the last point of a closed polyline describing a polygon
Returns
pair of plane_normal and the parameter d: the normal of the plane the polygon is located in, d parameter from the plane equation

Definition at line 14 of file AnalyticalGeometry-impl.h.

16{
17 Eigen::Vector3d plane_normal({0, 0, 0});
18 Eigen::Vector3d centroid({0, 0, 0});
19 for (auto i = std::prev(pnts_end), j = pnts_begin; j != pnts_end;
20 i = j, ++j)
21 {
22 auto const& pt_i = *(*i);
23 auto const& pt_j = *(*j);
24 plane_normal[0] +=
25 (pt_i[1] - pt_j[1]) * (pt_i[2] + pt_j[2]); // projection on yz
26 plane_normal[1] +=
27 (pt_i[2] - pt_j[2]) * (pt_i[0] + pt_j[0]); // projection on xz
28 plane_normal[2] +=
29 (pt_i[0] - pt_j[0]) * (pt_i[1] + pt_j[1]); // projection on xy
30
31 centroid += pt_j.asEigenVector3d();
32 }
33
34 plane_normal.normalize();
35 auto n_pnts(std::distance(pnts_begin, pnts_end));
36 assert(n_pnts > 2);
37 double d = 0.0;
38 if (n_pnts > 0)
39 {
40 d = centroid.dot(plane_normal) / n_pnts;
41 }
42 return std::make_pair(plane_normal, d);
43}

Referenced by getNewellPlane(), detail::getRotationMatrixToGlobal(), rotateGeometryToXY(), rotatePointsToXY(), and rotatePolygonPointsToXY().

◆ getOrientation()

Orientation GeoLib::getOrientation ( MathLib::Point3d const & p0,
MathLib::Point3d const & p1,
MathLib::Point3d const & p2 )

Computes the orientation of the three 2D-Points. This is a robust method.

Returns
CW (clockwise), CCW (counterclockwise) or COLLINEAR (points are on a line)

Definition at line 52 of file AnalyticalGeometry.cpp.

55{
56 double const orientation = ExactPredicates::getOrientation2d(p0, p1, p2);
57 if (orientation > 0)
58 {
59 return CCW;
60 }
61 if (orientation < 0)
62 {
63 return CW;
64 }
65 return COLLINEAR;
66}
double getOrientation2d(MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &c)

References CCW, COLLINEAR, CW, and ExactPredicates::getOrientation2d().

Referenced by GeoLib::EarClippingTriangulation::addLastTriangle(), GeoLib::EarClippingTriangulation::clipEars(), GeoLib::Polygon::ensureCCWOrientation(), GeoLib::EarClippingTriangulation::ensureCWOrientation(), MeshToolsLib::ProjectPointOnMesh::getProjectedElement(), GeoLib::EarClippingTriangulation::initLists(), and lineSegmentIntersect2d().

◆ getOrientationFast()

Orientation GeoLib::getOrientationFast ( MathLib::Point3d const & p0,
MathLib::Point3d const & p1,
MathLib::Point3d const & p2 )

Computes the orientation of the three 2D-Points. This is a non-robust method.

Returns
CW (clockwise), CCW (counterclockwise) or COLLINEAR (points are on a line)

Definition at line 68 of file AnalyticalGeometry.cpp.

71{
72 double const orientation =
74 if (orientation > 0)
75 {
76 return CCW;
77 }
78 if (orientation < 0)
79 {
80 return CW;
81 }
82 return COLLINEAR;
83}
double getOrientation2dFast(MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &c)

References CCW, COLLINEAR, CW, and ExactPredicates::getOrientation2dFast().

◆ isBorehole()

bool GeoLib::isBorehole ( GeoLib::Point const * pnt)

Definition at line 106 of file StationBorehole.cpp.

107{
108 auto const* bh(dynamic_cast<GeoLib::StationBorehole const*>(pnt));
109 return bh != nullptr;
110}
A borehole as a geometric object.

Referenced by MeshGeoToolsLib::GeoMapper::mapStationData().

◆ isStation()

bool GeoLib::isStation ( GeoLib::Point const * pnt)

Definition at line 77 of file Station.cpp.

78{
79 auto const* bh(dynamic_cast<GeoLib::Station const*>(pnt));
80 return bh != nullptr;
81}

Referenced by MeshGeoToolsLib::GeoMapper::mapOnDEM(), and MeshGeoToolsLib::GeoMapper::mapOnMesh().

◆ lineSegmentIntersect()

bool GeoLib::lineSegmentIntersect ( LineSegment const & s0,
LineSegment const & s1,
Point & s )

A line segment is given by its two end-points. The function checks, if the two line segments (ab) and (cd) intersects.

Parameters
s0the first line segment.
s1the second line segment.
sthe intersection point if the segments do intersect
Returns
true, if the line segments intersect, else false

Definition at line 141 of file AnalyticalGeometry.cpp.

144{
145 GeoLib::Point const& pa{s0.getBeginPoint()};
146 GeoLib::Point const& pb{s0.getEndPoint()};
147 GeoLib::Point const& pc{s1.getBeginPoint()};
148 GeoLib::Point const& pd{s1.getEndPoint()};
149
150 if (!isCoplanar(pa, pb, pc, pd))
151 {
152 return false;
153 }
154
155 auto const& a = s0.getBeginPoint().asEigenVector3d();
156 auto const& b = s0.getEndPoint().asEigenVector3d();
157 auto const& c = s1.getBeginPoint().asEigenVector3d();
158 auto const& d = s1.getEndPoint().asEigenVector3d();
159
160 Eigen::Vector3d const v = b - a;
161 Eigen::Vector3d const w = d - c;
162 Eigen::Vector3d const qp = c - a;
163 Eigen::Vector3d const pq = a - c;
164
165 double const eps = std::numeric_limits<double>::epsilon();
166 double const squared_eps = eps * eps;
167 // handle special cases here to avoid computing intersection numerical
168 if (qp.squaredNorm() < squared_eps || (d - a).squaredNorm() < squared_eps)
169 {
170 s = pa;
171 return true;
172 }
173 if ((c - b).squaredNorm() < squared_eps ||
174 (d - b).squaredNorm() < squared_eps)
175 {
176 s = pb;
177 return true;
178 }
179
180 auto isLineSegmentIntersectingAB =
181 [&v](Eigen::Vector3d const& ap, std::size_t i)
182 {
183 // check if p is located at v=(a,b): (ap = t*v, t in [0,1])
184 return 0.0 <= ap[i] / v[i] && ap[i] / v[i] <= 1.0;
185 };
186
187 if (parallel(v, w))
188 { // original line segments (a,b) and (c,d) are parallel
189 if (parallel(pq, v))
190 { // line segment (a,b) and (a,c) are also parallel
191 // Here it is already checked that the line segments (a,b) and (c,d)
192 // are parallel. At this point it is also known that the line
193 // segment (a,c) is also parallel to (a,b). In that case it is
194 // possible to express c as c(t) = a + t * (b-a) (analog for the
195 // point d). Since the evaluation of all three coordinate equations
196 // (x,y,z) have to lead to the same solution for the parameter t it
197 // is sufficient to evaluate t only once.
198
199 // Search id of coordinate with largest absolute value which is will
200 // be used in the subsequent computations. This prevents division by
201 // zero in case the line segments are parallel to one of the
202 // coordinate axis.
203 std::size_t i_max(std::abs(v[0]) <= std::abs(v[1]) ? 1 : 0);
204 i_max = std::abs(v[i_max]) <= std::abs(v[2]) ? 2 : i_max;
205 if (isLineSegmentIntersectingAB(qp, i_max))
206 {
207 s = pc;
208 return true;
209 }
210 Eigen::Vector3d const ad = d - a;
211 if (isLineSegmentIntersectingAB(ad, i_max))
212 {
213 s = pd;
214 return true;
215 }
216 return false;
217 }
218 return false;
219 }
220
221 // general case
222 const double sqr_len_v(v.squaredNorm());
223 const double sqr_len_w(w.squaredNorm());
224
225 Eigen::Matrix2d mat;
226 mat(0, 0) = sqr_len_v;
227 mat(0, 1) = -v.dot(w);
228 mat(1, 1) = sqr_len_w;
229 mat(1, 0) = mat(0, 1);
230
231 Eigen::Vector2d rhs{v.dot(qp), w.dot(pq)};
232
233 rhs = mat.partialPivLu().solve(rhs);
234
235 // no theory for the following tolerances, determined by testing
236 // lower tolerance: little bit smaller than zero
237 const double l(-1.0 * std::numeric_limits<float>::epsilon());
238 // upper tolerance a little bit greater than one
239 const double u(1.0 + std::numeric_limits<float>::epsilon());
240 if (rhs[0] < l || u < rhs[0] || rhs[1] < l || u < rhs[1])
241 {
242 return false;
243 }
244
245 // compute points along line segments with minimal distance
246 GeoLib::Point const p0(a[0] + rhs[0] * v[0], a[1] + rhs[0] * v[1],
247 a[2] + rhs[0] * v[2]);
248 GeoLib::Point const p1(c[0] + rhs[1] * w[0], c[1] + rhs[1] * w[1],
249 c[2] + rhs[1] * w[2]);
250
251 double const min_dist(std::sqrt(MathLib::sqrDist(p0, p1)));
252 double const min_seg_len(
253 std::min(std::sqrt(sqr_len_v), std::sqrt(sqr_len_w)));
254 if (min_dist < min_seg_len * 1e-6)
255 {
256 s[0] = 0.5 * (p0[0] + p1[0]);
257 s[1] = 0.5 * (p0[1] + p1[1]);
258 s[2] = 0.5 * (p0[2] + p1[2]);
259 return true;
260 }
261
262 return false;
263}
Eigen::Vector3d const & asEigenVector3d() const
Definition Point3d.h:63
bool parallel(Eigen::Vector3d v, Eigen::Vector3d w)
bool isCoplanar(const MathLib::Point3d &a, const MathLib::Point3d &b, const MathLib::Point3d &c, const MathLib::Point3d &d)
Checks if the four given points are located on a plane.

References MathLib::Point3d::asEigenVector3d(), GeoLib::LineSegment::getBeginPoint(), GeoLib::LineSegment::getEndPoint(), parallel(), and MathLib::sqrDist().

Referenced by FileIO::GMSH::GMSHPolygonTree::checkIntersectionsSegmentExistingPolylines(), computeAndInsertAllIntersectionPoints(), getAllIntersectionPoints(), GeoLib::Polygon::getNextIntersectionPointPolygonLine(), and lineSegmentsIntersect().

◆ lineSegmentIntersect2d()

std::vector< MathLib::Point3d > GeoLib::lineSegmentIntersect2d ( LineSegment const & ab,
LineSegment const & cd )

A line segment is given by its two end-points. The function checks, if the two line segments (ab) and (cd) intersects. This method checks the intersection only in 2d.

Parameters
abfirst line segment
cdsecond line segment
Returns
empty vector in case there isn't an intersection point, a vector containing one point if the line segments intersect in a single point, a vector containing two points describing the line segment the original line segments are interfering.

Definition at line 459 of file AnalyticalGeometry.cpp.

461{
462 GeoLib::Point const& a{ab.getBeginPoint()};
463 GeoLib::Point const& b{ab.getEndPoint()};
464 GeoLib::Point const& c{cd.getBeginPoint()};
465 GeoLib::Point const& d{cd.getEndPoint()};
466
467 double const orient_abc(getOrientation(a, b, c));
468 double const orient_abd(getOrientation(a, b, d));
469
470 // check if the segment (cd) lies on the left or on the right of (ab)
471 if ((orient_abc > 0 && orient_abd > 0) ||
472 (orient_abc < 0 && orient_abd < 0))
473 {
474 return std::vector<MathLib::Point3d>();
475 }
476
477 // check: (cd) and (ab) are on the same line
478 if (orient_abc == 0.0 && orient_abd == 0.0)
479 {
480 double const eps(std::numeric_limits<double>::epsilon());
481 if (MathLib::sqrDist2d(a, c) < eps && MathLib::sqrDist2d(b, d) < eps)
482 {
483 return {{a, b}};
484 }
485 if (MathLib::sqrDist2d(a, d) < eps && MathLib::sqrDist2d(b, c) < eps)
486 {
487 return {{a, b}};
488 }
489
490 // Since orient_ab and orient_abd vanish, a, b, c, d are on the same
491 // line and for this reason it is enough to check the x-component.
492 auto isPointOnSegment = [](double q, double p0, double p1)
493 {
494 double const t((q - p0) / (p1 - p0));
495 return 0 <= t && t <= 1;
496 };
497
498 // check if c in (ab)
499 if (isPointOnSegment(c[0], a[0], b[0]))
500 {
501 // check if a in (cd)
502 if (isPointOnSegment(a[0], c[0], d[0]))
503 {
504 return {{a, c}};
505 }
506 // check b == c
507 if (MathLib::sqrDist2d(b, c) < eps)
508 {
509 return {{b}};
510 }
511 // check if b in (cd)
512 if (isPointOnSegment(b[0], c[0], d[0]))
513 {
514 return {{b, c}};
515 }
516 // check d in (ab)
517 if (isPointOnSegment(d[0], a[0], b[0]))
518 {
519 return {{c, d}};
520 }
521 std::stringstream err;
522 err.precision(std::numeric_limits<double>::digits10);
523 err << ab << " x " << cd;
524 OGS_FATAL(
525 "The case of parallel line segments ({:s}) is not handled yet. "
526 "Aborting.",
527 err.str());
528 }
529
530 // check if d in (ab)
531 if (isPointOnSegment(d[0], a[0], b[0]))
532 {
533 // check if a in (cd)
534 if (isPointOnSegment(a[0], c[0], d[0]))
535 {
536 return {{a, d}};
537 }
538 // check if b==d
539 if (MathLib::sqrDist2d(b, d) < eps)
540 {
541 return {{b}};
542 }
543 // check if b in (cd)
544 if (isPointOnSegment(b[0], c[0], d[0]))
545 {
546 return {{b, d}};
547 }
548 // d in (ab), b not in (cd): check c in (ab)
549 if (isPointOnSegment(c[0], a[0], b[0]))
550 {
551 return {{c, d}};
552 }
553
554 std::stringstream err;
555 err.precision(std::numeric_limits<double>::digits10);
556 err << ab << " x " << cd;
557 OGS_FATAL(
558 "The case of parallel line segments ({:s}) is not handled yet. "
559 "Aborting.",
560 err.str());
561 }
562 return std::vector<MathLib::Point3d>();
563 }
564
565 // precondition: points a, b, c are collinear
566 // the function checks if the point c is onto the line segment (a,b)
567 auto isCollinearPointOntoLineSegment = [](MathLib::Point3d const& a,
568 MathLib::Point3d const& b,
569 MathLib::Point3d const& c)
570 {
571 if (b[0] - a[0] != 0)
572 {
573 double const t = (c[0] - a[0]) / (b[0] - a[0]);
574 return 0.0 <= t && t <= 1.0;
575 }
576 if (b[1] - a[1] != 0)
577 {
578 double const t = (c[1] - a[1]) / (b[1] - a[1]);
579 return 0.0 <= t && t <= 1.0;
580 }
581 if (b[2] - a[2] != 0)
582 {
583 double const t = (c[2] - a[2]) / (b[2] - a[2]);
584 return 0.0 <= t && t <= 1.0;
585 }
586 return false;
587 };
588
589 if (orient_abc == 0.0)
590 {
591 if (isCollinearPointOntoLineSegment(a, b, c))
592 {
593 return {{c}};
594 }
595 return std::vector<MathLib::Point3d>();
596 }
597
598 if (orient_abd == 0.0)
599 {
600 if (isCollinearPointOntoLineSegment(a, b, d))
601 {
602 return {{d}};
603 }
604 return std::vector<MathLib::Point3d>();
605 }
606
607 // check if the segment (ab) lies on the left or on the right of (cd)
608 double const orient_cda(getOrientation(c, d, a));
609 double const orient_cdb(getOrientation(c, d, b));
610 if ((orient_cda > 0 && orient_cdb > 0) ||
611 (orient_cda < 0 && orient_cdb < 0))
612 {
613 return std::vector<MathLib::Point3d>();
614 }
615
616 // at this point it is sure that there is an intersection and the system of
617 // linear equations will be invertible
618 // solve the two linear equations (b-a, c-d) (t, s)^T = (c-a) simultaneously
619 Eigen::Matrix2d mat;
620 mat(0, 0) = b[0] - a[0];
621 mat(0, 1) = c[0] - d[0];
622 mat(1, 0) = b[1] - a[1];
623 mat(1, 1) = c[1] - d[1];
624 Eigen::Vector2d rhs{c[0] - a[0], c[1] - a[1]};
625
626 rhs = mat.partialPivLu().solve(rhs);
627 if (0 <= rhs[1] && rhs[1] <= 1.0)
628 {
629 return {MathLib::Point3d{std::array<double, 3>{
630 {c[0] + rhs[1] * (d[0] - c[0]), c[1] + rhs[1] * (d[1] - c[1]),
631 c[2] + rhs[1] * (d[2] - c[2])}}}};
632 }
633 return std::vector<MathLib::Point3d>(); // parameter s not in the valid
634 // range
635}
Orientation getOrientation(MathLib::Point3d const &p0, MathLib::Point3d const &p1, MathLib::Point3d const &p2)
double sqrDist2d(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.h:122

References GeoLib::LineSegment::getBeginPoint(), GeoLib::LineSegment::getEndPoint(), getOrientation(), OGS_FATAL, and MathLib::sqrDist2d().

Referenced by MeshGeoToolsLib::computeElementSegmentIntersections().

◆ lineSegmentsIntersect()

bool GeoLib::lineSegmentsIntersect ( const Polyline * ply,
Polyline::SegmentIterator & seg_it0,
Polyline::SegmentIterator & seg_it1,
Point & intersection_pnt )

test for intersections of the line segments of the Polyline

Parameters
plythe polyline
seg_it0iterator pointing to the first segment that has an intersection
seg_it1iterator pointing to the second segment that has an intersection
intersection_pntthe intersection point if the segments intersect
Returns
true, if the polyline contains intersections

Definition at line 265 of file AnalyticalGeometry.cpp.

269{
270 std::size_t const n_segs(ply->getNumberOfSegments());
271 // Neighbouring segments always intersects at a common vertex. The algorithm
272 // checks for intersections of non-neighbouring segments.
273 for (seg_it0 = ply->begin(); seg_it0 != ply->end() - 2; ++seg_it0)
274 {
275 seg_it1 = seg_it0 + 2;
276 std::size_t const seg_num_0 = seg_it0.getSegmentNumber();
277 for (; seg_it1 != ply->end(); ++seg_it1)
278 {
279 // Do not check first and last segment, because they are
280 // neighboured.
281 if (!(seg_num_0 == 0 && seg_it1.getSegmentNumber() == n_segs - 1))
282 {
283 if (lineSegmentIntersect(*seg_it0, *seg_it1, intersection_pnt))
284 {
285 return true;
286 }
287 }
288 }
289 }
290 return false;
291}
std::size_t getSegmentNumber() const
Definition Polyline.cpp:387
std::size_t getNumberOfSegments() const
Definition Polyline.cpp:114

References GeoLib::Polyline::begin(), GeoLib::Polyline::end(), GeoLib::Polyline::getNumberOfSegments(), GeoLib::Polyline::SegmentIterator::getSegmentNumber(), and lineSegmentIntersect().

Referenced by GeoLib::Polygon::splitPolygonAtIntersection().

◆ markUnusedPoints()

void GeoLib::markUnusedPoints ( GEOObjects const & geo_objects,
std::string const & geo_name,
std::vector< bool > & transfer_pnts )

Definition at line 573 of file GEOObjects.cpp.

576{
577 GeoLib::PolylineVec const* const ply_obj(
578 geo_objects.getPolylineVecObj(geo_name));
579 if (ply_obj)
580 {
581 std::vector<GeoLib::Polyline*> const& lines(ply_obj->getVector());
582 for (auto* line : lines)
583 {
584 std::size_t const n_pnts(line->getNumberOfPoints());
585 for (std::size_t i = 0; i < n_pnts; ++i)
586 {
587 transfer_pnts[line->getPointID(i)] = false;
588 }
589 }
590 }
591
592 GeoLib::SurfaceVec const* const sfc_obj(
593 geo_objects.getSurfaceVecObj(geo_name));
594 if (sfc_obj)
595 {
596 std::vector<GeoLib::Surface*> const& surfaces = sfc_obj->getVector();
597 for (auto* sfc : surfaces)
598 {
599 std::size_t const n_tri(sfc->getNumberOfTriangles());
600 for (std::size_t i = 0; i < n_tri; ++i)
601 {
602 GeoLib::Triangle const& t = *(*sfc)[i];
603 transfer_pnts[t[0]] = false;
604 transfer_pnts[t[1]] = false;
605 transfer_pnts[t[2]] = false;
606 }
607 }
608 }
609}
The class TemplateVec takes a unique name and manages a std::vector of pointers to data elements of t...
Definition TemplateVec.h:38
Class Triangle consists of a reference to a point vector and a vector that stores the indices in the ...
Definition Triangle.h:27

References GeoLib::GEOObjects::getPolylineVecObj(), GeoLib::GEOObjects::getSurfaceVecObj(), and GeoLib::TemplateVec< T >::getVector().

Referenced by geoPointsToStations().

◆ markUsedPoints() [1/2]

void GeoLib::markUsedPoints ( Polyline const & polyline,
std::vector< bool > & used_points )

Resets the point IDs of the polyline corresponding to the mapping.

Definition at line 490 of file Polyline.cpp.

491{
492 if (polyline.getPointsVec().size() != used_points.size())
493 {
494 OGS_FATAL(
495 "internal error in markUsedPoints(): polyline based on point "
496 "vector of size {}, given used_points has size {}",
497 polyline.getPointsVec().size(), used_points.size());
498 }
499 for (std::size_t i = 0; i < polyline.getNumberOfPoints(); ++i)
500 {
501 used_points[polyline.getPointID(i)] = true;
502 }
503}

References GeoLib::Polyline::getNumberOfPoints(), GeoLib::Polyline::getPointID(), GeoLib::Polyline::getPointsVec(), and OGS_FATAL.

Referenced by main().

◆ markUsedPoints() [2/2]

void GeoLib::markUsedPoints ( Surface const & surface,
std::vector< bool > & used_points )

Definition at line 132 of file Surface.cpp.

133{
134 if (surface.getPointVec()->size() != used_points.size())
135 {
136 OGS_FATAL(
137 "internal error in markUsedPoints(): surface based on point vector "
138 "of size {}, given used_points has size {}",
139 surface.getPointVec()->size(), used_points.size());
140 }
141 for (std::size_t i = 0; i < surface.getNumberOfTriangles(); ++i)
142 {
143 auto const& triangle = *surface[i];
144 for (std::size_t k = 0; k < 3; ++k)
145 {
146 used_points[triangle[k]] = true;
147 }
148 }
149}

References GeoLib::Surface::getNumberOfTriangles(), GeoLib::Surface::getPointVec(), and OGS_FATAL.

◆ operator<<() [1/2]

std::ostream & GeoLib::operator<< ( std::ostream & os,
LineSegment const & s )

Definition at line 86 of file LineSegment.cpp.

87{
88 os << "{(" << s.getBeginPoint() << "), (" << s.getEndPoint() << ")}";
89 return os;
90}

References GeoLib::LineSegment::getBeginPoint(), and GeoLib::LineSegment::getEndPoint().

◆ operator<<() [2/2]

std::ostream & GeoLib::operator<< ( std::ostream & os,
std::pair< GeoLib::LineSegment const &, GeoLib::LineSegment const & > const & seg_pair )

Definition at line 92 of file LineSegment.cpp.

95{
96 os << seg_pair.first << " x " << seg_pair.second;
97 return os;
98}

◆ operator==() [1/4]

bool GeoLib::operator== ( LineSegment const & s0,
LineSegment const & s1 )

Compares two objects of type LineSegment.

Note
The comparison is not strict. Two line segments \(s_0 = (b_0, e_0)\) and \(s_1 = (b_1, e_1)\) are equal, if \(\|b_0-b_1\|^2 < \epsilon\) and \(\|e_0-e_1\|^2 < \epsilon\) or \(\|b_0-e_1\|^2 < \epsilon\) and \(\|e_0-b_1\|^2 < \epsilon\) where \(\epsilon\) is the machine precision of double.

Definition at line 100 of file LineSegment.cpp.

101{
102 double const tol(std::numeric_limits<double>::epsilon());
103 return (MathLib::sqrDist(s0.getBeginPoint(), s1.getBeginPoint()) < tol &&
104 MathLib::sqrDist(s0.getEndPoint(), s1.getEndPoint()) < tol) ||
105 (MathLib::sqrDist(s0.getBeginPoint(), s1.getEndPoint()) < tol &&
106 MathLib::sqrDist(s0.getEndPoint(), s1.getBeginPoint()) < tol);
107}

References GeoLib::LineSegment::getBeginPoint(), GeoLib::LineSegment::getEndPoint(), and MathLib::sqrDist().

◆ operator==() [2/4]

bool GeoLib::operator== ( Polygon const & lhs,
Polygon const & rhs )

comparison operator for polygons

Parameters
lhsthe first polygon
rhsthe second polygon
Returns
true, if the polygons describe the same geometrical object

Definition at line 597 of file Polygon.cpp.

598{
599 if (lhs.getNumberOfPoints() != rhs.getNumberOfPoints())
600 {
601 return false;
602 }
603
604 const std::size_t n(lhs.getNumberOfPoints());
605 const std::size_t start_pnt(lhs.getPointID(0));
606
607 // search start point of first polygon in second polygon
608 bool nfound(true);
609 std::size_t k(0);
610 for (; k < n - 1 && nfound; k++)
611 {
612 if (start_pnt == rhs.getPointID(k))
613 {
614 nfound = false;
615 break;
616 }
617 }
618
619 // case: start point not found in second polygon
620 if (nfound)
621 {
622 return false;
623 }
624
625 // *** determine direction
626 // opposite direction
627 if (k == n - 2)
628 {
629 for (k = 1; k < n - 1; k++)
630 {
631 if (lhs.getPointID(k) != rhs.getPointID(n - 1 - k))
632 {
633 return false;
634 }
635 }
636 return true;
637 }
638
639 // same direction - start point of first polygon at arbitrary position in
640 // second polygon
641 if (lhs.getPointID(1) == rhs.getPointID(k + 1))
642 {
643 std::size_t j(k + 2);
644 for (; j < n - 1; j++)
645 {
646 if (lhs.getPointID(j - k) != rhs.getPointID(j))
647 {
648 return false;
649 }
650 }
651 j = 0; // new start point at second polygon
652 for (; j < k + 1; j++)
653 {
654 if (lhs.getPointID(n - (k + 2) + j + 1) != rhs.getPointID(j))
655 {
656 return false;
657 }
658 }
659 return true;
660 }
661 // opposite direction with start point of first polygon at arbitrary
662 // position
663 // *** ATTENTION
664 WARN(
665 "operator==(Polygon const& lhs, Polygon const& rhs) - not tested case "
666 "(implementation is probably buggy) - please contact "
667 "thomas.fischer@ufz.de mentioning the problem.");
668 // in second polygon
669 if (lhs.getPointID(1) == rhs.getPointID(k - 1))
670 {
671 std::size_t j(k - 2);
672 for (; j > 0; j--)
673 {
674 if (lhs.getPointID(k - 2 - j) != rhs.getPointID(j))
675 {
676 return false;
677 }
678 }
679 // new start point at second polygon - the point n-1 of a polygon is
680 // equal to the first point of the polygon (for this reason: n-2)
681 j = n - 2;
682 for (; j > k - 1; j--)
683 {
684 if (lhs.getPointID(n - 2 + j + k - 2) != rhs.getPointID(j))
685 {
686 return false;
687 }
688 }
689 return true;
690 }
691 return false;
692}

◆ operator==() [3/4]

bool GeoLib::operator== ( Polyline const & lhs,
Polyline const & rhs )

comparison operator

Parameters
lhsfirst polyline
rhssecond polyline
Returns
true, if the polylines consists of the same sequence of line segments

Definition at line 533 of file Polyline.cpp.

534{
535 if (lhs.getNumberOfPoints() != rhs.getNumberOfPoints())
536 {
537 return false;
538 }
539
540 const std::size_t n(lhs.getNumberOfPoints());
541 for (std::size_t k(0); k < n; k++)
542 {
543 if (lhs.getPointID(k) != rhs.getPointID(k))
544 {
545 return false;
546 }
547 }
548
549 return true;
550}

References GeoLib::Polyline::getNumberOfPoints(), and GeoLib::Polyline::getPointID().

◆ operator==() [4/4]

bool GeoLib::operator== ( Surface const & lhs,
Surface const & rhs )

Definition at line 109 of file Surface.cpp.

110{
111 return &lhs == &rhs;
112}

◆ parallel()

bool GeoLib::parallel ( Eigen::Vector3d v,
Eigen::Vector3d w )

Check if the two vectors \(v, w \in R^3\) are in parallel

Parameters
vfirst vector
wsecond vector
Returns
true if the vectors are in parallel, else false

Definition at line 85 of file AnalyticalGeometry.cpp.

86{
87 const double eps(std::numeric_limits<double>::epsilon());
88 double const eps_squared = eps * eps;
89
90 // check degenerated cases
91 if (v.squaredNorm() < eps_squared)
92 {
93 return false;
94 }
95
96 if (w.squaredNorm() < eps_squared)
97 {
98 return false;
99 }
100
101 v.normalize();
102 w.normalize();
103
104 bool parallel(true);
105 if (std::abs(v[0] - w[0]) > eps)
106 {
107 parallel = false;
108 }
109 if (std::abs(v[1] - w[1]) > eps)
110 {
111 parallel = false;
112 }
113 if (std::abs(v[2] - w[2]) > eps)
114 {
115 parallel = false;
116 }
117
118 if (!parallel)
119 {
120 parallel = true;
121 // change sense of direction of v_normalised
122 v *= -1.0;
123 // check again
124 if (std::abs(v[0] - w[0]) > eps)
125 {
126 parallel = false;
127 }
128 if (std::abs(v[1] - w[1]) > eps)
129 {
130 parallel = false;
131 }
132 if (std::abs(v[2] - w[2]) > eps)
133 {
134 parallel = false;
135 }
136 }
137
138 return parallel;
139}

References parallel().

Referenced by lineSegmentIntersect(), and parallel().

◆ pointsAreIdentical()

bool GeoLib::pointsAreIdentical ( const std::vector< Point * > & pnt_vec,
std::size_t i,
std::size_t j,
double prox )

Definition at line 552 of file Polyline.cpp.

556{
557 if (i == j)
558 {
559 return true;
560 }
561 return MathLib::sqrDist(*pnt_vec[i], *pnt_vec[j]) < prox;
562}

References MathLib::sqrDist().

Referenced by GeoLib::Polyline::constructPolylineFromSegments().

◆ resetPointIDs() [1/2]

void GeoLib::resetPointIDs ( Polyline & polyline,
std::vector< std::size_t > const & mapping )

Resets the point IDs of the polyline corresponding to the mapping.

Definition at line 475 of file Polyline.cpp.

476{
477 if (polyline.getPointsVec().size() != mapping.size())
478 {
479 OGS_FATAL(
480 "internal error in resetPointIDs(): polyline based on point vector "
481 "of size {}, given mapping has size {}",
482 polyline.getPointsVec().size(), mapping.size());
483 }
484 for (std::size_t i = 0; i < polyline.getNumberOfPoints(); ++i)
485 {
486 polyline.setPointID(i, mapping[polyline.getPointID(i)]);
487 }
488}
void setPointID(std::size_t idx, std::size_t id)
Definition Polyline.cpp:173
std::vector< Point * > const & getPointsVec() const
Definition Polyline.cpp:185

References GeoLib::Polyline::getNumberOfPoints(), GeoLib::Polyline::getPointID(), GeoLib::Polyline::getPointsVec(), OGS_FATAL, and GeoLib::Polyline::setPointID().

Referenced by main(), and FileIO::GMSH::GMSHPolygonTree::writeAdditionalPointData().

◆ resetPointIDs() [2/2]

void GeoLib::resetPointIDs ( Surface & surface,
std::vector< std::size_t > const & mapping )

Resets the point IDs of the surface corresponding to the mapping.

Definition at line 114 of file Surface.cpp.

115{
116 if (surface.getPointVec()->size() != mapping.size())
117 {
118 OGS_FATAL(
119 "internal error in resetPointIDs(): surface based on point vector "
120 "of size {}, given mapping vector has size {}",
121 surface.getPointVec()->size(), mapping.size());
122 }
123 for (std::size_t i = 0; i < surface.getNumberOfTriangles(); ++i)
124 {
125 auto& triangle = *surface[i];
126 const_cast<std::size_t&>(triangle[0]) = mapping[triangle[0]];
127 const_cast<std::size_t&>(triangle[1]) = mapping[triangle[1]];
128 const_cast<std::size_t&>(triangle[2]) = mapping[triangle[2]];
129 }
130}
std::size_t getNumberOfTriangles() const
Definition Surface.cpp:82
const std::vector< Point * > * getPointVec() const
Definition Surface.h:73

References GeoLib::Surface::getNumberOfTriangles(), GeoLib::Surface::getPointVec(), and OGS_FATAL.

◆ rotatePoints() [1/3]

template<typename InputIterator >
void GeoLib::rotatePoints ( Eigen::Matrix3d const & rot_mat,
InputIterator pnts_begin,
InputIterator pnts_end )

rotate points according to the rotation matrix

Parameters
rot_mat3x3 dimensional rotation matrix
pnts_beginIterator pointing to the initial element in a vector of points to be rotated
pnts_endIterator pointing to the element following the last element in a vector of points to be rotated

Definition at line 77 of file AnalyticalGeometry-impl.h.

79{
80 for (auto it = pnts_begin; it != pnts_end; ++it)
81 {
82 (*it)->asEigenVector3d() = rot_mat * (*it)->asEigenVector3d();
83 }
84}

Referenced by MeshGeoToolsLib::markNodesOutSideOfPolygon(), rotateGeometryToXY(), rotateMesh(), rotatePoints(), rotatePoints(), rotatePointsToXY(), rotatePolygonPointsToXY(), and FileIO::GMSH::GMSHInterface::writeGMSHInputFile().

◆ rotatePoints() [2/3]

void GeoLib::rotatePoints ( Eigen::Matrix3d const & rot_mat,
std::vector< GeoLib::Point * > & pnts )

Definition at line 293 of file AnalyticalGeometry.cpp.

295{
296 rotatePoints(rot_mat, pnts.begin(), pnts.end());
297}
void rotatePoints(Eigen::Matrix3d const &rot_mat, InputIterator pnts_begin, InputIterator pnts_end)

References rotatePoints().

◆ rotatePoints() [3/3]

template<typename P >
void GeoLib::rotatePoints ( Eigen::Matrix3d const & rot_mat,
std::vector< P * > const & pnts )

rotate points according to the rotation matrix

Parameters
rot_mat3x3 dimensional rotation matrix
pntsvector of points

Definition at line 111 of file AnalyticalGeometry-impl.h.

112{
113 rotatePoints(rot_mat, pnts.begin(), pnts.end());
114}

References rotatePoints().

◆ rotatePointsToXY() [1/3]

template<typename InputIterator1 , typename InputIterator2 >
Eigen::Matrix3d GeoLib::rotatePointsToXY ( InputIterator1 p_pnts_begin,
InputIterator1 p_pnts_end,
InputIterator2 r_pnts_begin,
InputIterator2 r_pnts_end )

rotate points to X-Y plane

Parameters
p_pnts_beginIterator pointing to the initial element in a vector of points used for computing a rotation matrix
p_pnts_endIterator pointing to the element following the last point in a vector of points used for computing a rotation matrix
r_pnts_beginIterator pointing to the initial element in a vector of points to be rotated
r_pnts_endIterator pointing to the element following the last point in a vector of points to be rotated Points are rotated using a rotation matrix computed from the first three points in the vector. Point coordinates are modified as a result of the rotation.

Definition at line 87 of file AnalyticalGeometry-impl.h.

91{
92 assert(std::distance(p_pnts_begin, p_pnts_end) > 2);
93
94 // compute the plane normal
95 auto const [plane_normal, d] =
96 GeoLib::getNewellPlane(p_pnts_begin, p_pnts_end);
97
98 // rotate points into x-y-plane
99 Eigen::Matrix3d const rot_mat = computeRotationMatrixToXY(plane_normal);
100 rotatePoints(rot_mat, r_pnts_begin, r_pnts_end);
101
102 for (auto it = r_pnts_begin; it != r_pnts_end; ++it)
103 {
104 (*(*it))[2] = 0.0; // should be -= d but there are numerical errors
105 }
106
107 return rot_mat;
108}
Eigen::Matrix3d computeRotationMatrixToXY(Eigen::Vector3d const &n)

References computeRotationMatrixToXY(), getNewellPlane(), and rotatePoints().

Referenced by GeoLib::EarClippingTriangulation::EarClippingTriangulation(), GeoLib::Polygon::ensureCCWOrientation(), rotatePointsToXY(), and FileIO::GMSH::GMSHInterface::writeGMSHInputFile().

◆ rotatePointsToXY() [2/3]

Eigen::Matrix3d GeoLib::rotatePointsToXY ( std::vector< Point * > & pnts)

rotate points to X-Y plane

Parameters
pntsa vector of points with a minimum length of three. Points are rotated using a rotation matrix computed from the first three points in the vector. Point coordinates are modified as a result of the rotation.

Definition at line 362 of file AnalyticalGeometry.cpp.

363{
364 return rotatePointsToXY(pnts.begin(), pnts.end(), pnts.begin(), pnts.end());
365}
Eigen::Matrix3d rotatePointsToXY(InputIterator1 p_pnts_begin, InputIterator1 p_pnts_end, InputIterator2 r_pnts_begin, InputIterator2 r_pnts_end)

References rotatePointsToXY().

◆ rotatePointsToXY() [3/3]

Eigen::Matrix3d GeoLib::rotatePointsToXY ( std::vector< Point * > & pnts)

rotate points to X-Y plane

Parameters
pntsa vector of points with a minimum length of three. Points are rotated using a rotation matrix computed from the first three points in the vector. Point coordinates are modified as a result of the rotation.

Definition at line 362 of file AnalyticalGeometry.cpp.

363{
364 return rotatePointsToXY(pnts.begin(), pnts.end(), pnts.begin(), pnts.end());
365}

References rotatePointsToXY().

◆ rotatePolygonPointsToXY()

std::tuple< std::vector< GeoLib::Point * >, Eigen::Vector3d > GeoLib::rotatePolygonPointsToXY ( GeoLib::Polygon const & polygon_in)

Function rotates a polygon to the xy plane. For this reason, (1) the points of the given polygon are copied, (2) a so called Newell plane is computed (getNewellPlane()) and the points are rotated, (3) for accuracy reasons the \(z\) coordinates of the rotated points are set to zero

See also
getNewellPlane()
Parameters
polygon_ina copy of the polygon_in polygon will be rotated
Returns
vector of rotated points and normal based on the original Newell plane

Definition at line 436 of file AnalyticalGeometry.cpp.

437{
438 // 1 copy all points
439 std::vector<GeoLib::Point*> polygon_points;
440 polygon_points.reserve(polygon_in.getNumberOfPoints());
441 for (std::size_t k(0); k < polygon_in.getNumberOfPoints(); k++)
442 {
443 polygon_points.push_back(new GeoLib::Point(*(polygon_in.getPoint(k))));
444 }
445
446 // 2 rotate points
447 auto [plane_normal, d_polygon] = GeoLib::getNewellPlane(polygon_points);
448 Eigen::Matrix3d const rot_mat =
450 GeoLib::rotatePoints(rot_mat, polygon_points);
451
452 // 3 set z coord to zero
453 std::for_each(polygon_points.begin(), polygon_points.end(),
454 [](GeoLib::Point* p) { (*p)[2] = 0.0; });
455
456 return {polygon_points, plane_normal};
457}

References computeRotationMatrixToXY(), getNewellPlane(), GeoLib::Polyline::getNumberOfPoints(), GeoLib::Polyline::getPoint(), and rotatePoints().

Referenced by MeshGeoToolsLib::markNodesOutSideOfPolygon().

◆ sortSegments() [1/2]

void GeoLib::sortSegments ( MathLib::Point3d const & seg_beg_pnt,
std::vector< LineSegment > & sub_segments )

Sorts the vector of segments such that the \(i\)-th segment is connected with the \(i+1\)st segment, i.e. the end point of the \(i\)-th segment is the start point of the \(i+1\)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 seg_beg_pnt.

Definition at line 637 of file AnalyticalGeometry.cpp.

639{
640 double const eps(std::numeric_limits<double>::epsilon());
641
642 auto findNextSegment =
643 [&eps](MathLib::Point3d const& seg_beg_pnt,
644 std::vector<GeoLib::LineSegment>& sub_segments,
645 std::vector<GeoLib::LineSegment>::iterator& sub_seg_it)
646 {
647 if (sub_seg_it == sub_segments.end())
648 {
649 return;
650 }
651 // find appropriate segment for the given segment begin point
652 auto act_beg_seg_it = std::find_if(
653 sub_seg_it, sub_segments.end(),
654 [&seg_beg_pnt, &eps](GeoLib::LineSegment const& seg)
655 {
656 return MathLib::sqrDist(seg_beg_pnt, seg.getBeginPoint()) <
657 eps ||
658 MathLib::sqrDist(seg_beg_pnt, seg.getEndPoint()) < eps;
659 });
660 if (act_beg_seg_it == sub_segments.end())
661 {
662 return;
663 }
664 // if necessary correct orientation of segment, i.e. swap beg and
665 // end
666 if (MathLib::sqrDist(seg_beg_pnt, act_beg_seg_it->getEndPoint()) <
667 MathLib::sqrDist(seg_beg_pnt, act_beg_seg_it->getBeginPoint()))
668 {
669 std::swap(act_beg_seg_it->getBeginPoint(),
670 act_beg_seg_it->getEndPoint());
671 }
672 assert(sub_seg_it != sub_segments.end());
673 // exchange segments within the container
674 if (sub_seg_it != act_beg_seg_it)
675 {
676 std::swap(*sub_seg_it, *act_beg_seg_it);
677 }
678 };
679
680 // find start segment
681 auto seg_it = sub_segments.begin();
682 findNextSegment(seg_beg_pnt, sub_segments, seg_it);
683
684 while (seg_it != sub_segments.end())
685 {
686 MathLib::Point3d& new_seg_beg_pnt(seg_it->getEndPoint());
687 seg_it++;
688 if (seg_it != sub_segments.end())
689 {
690 findNextSegment(new_seg_beg_pnt, sub_segments, seg_it);
691 }
692 }
693}

References MathLib::sqrDist().

Referenced by MeshGeoToolsLib::mapLineSegment().

◆ sortSegments() [2/2]

void GeoLib::sortSegments ( MathLib::Point3d const & seg_beg_pnt,
std::vector< LineSegment > & sub_segments )

Sorts the vector of segments such that the \(i\)-th segment is connected with the \(i+1\)st segment, i.e. the end point of the \(i\)-th segment is the start point of the \(i+1\)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 seg_beg_pnt.

Definition at line 637 of file AnalyticalGeometry.cpp.

639{
640 double const eps(std::numeric_limits<double>::epsilon());
641
642 auto findNextSegment =
643 [&eps](MathLib::Point3d const& seg_beg_pnt,
644 std::vector<GeoLib::LineSegment>& sub_segments,
645 std::vector<GeoLib::LineSegment>::iterator& sub_seg_it)
646 {
647 if (sub_seg_it == sub_segments.end())
648 {
649 return;
650 }
651 // find appropriate segment for the given segment begin point
652 auto act_beg_seg_it = std::find_if(
653 sub_seg_it, sub_segments.end(),
654 [&seg_beg_pnt, &eps](GeoLib::LineSegment const& seg)
655 {
656 return MathLib::sqrDist(seg_beg_pnt, seg.getBeginPoint()) <
657 eps ||
658 MathLib::sqrDist(seg_beg_pnt, seg.getEndPoint()) < eps;
659 });
660 if (act_beg_seg_it == sub_segments.end())
661 {
662 return;
663 }
664 // if necessary correct orientation of segment, i.e. swap beg and
665 // end
666 if (MathLib::sqrDist(seg_beg_pnt, act_beg_seg_it->getEndPoint()) <
667 MathLib::sqrDist(seg_beg_pnt, act_beg_seg_it->getBeginPoint()))
668 {
669 std::swap(act_beg_seg_it->getBeginPoint(),
670 act_beg_seg_it->getEndPoint());
671 }
672 assert(sub_seg_it != sub_segments.end());
673 // exchange segments within the container
674 if (sub_seg_it != act_beg_seg_it)
675 {
676 std::swap(*sub_seg_it, *act_beg_seg_it);
677 }
678 };
679
680 // find start segment
681 auto seg_it = sub_segments.begin();
682 findNextSegment(seg_beg_pnt, sub_segments, seg_it);
683
684 while (seg_it != sub_segments.end())
685 {
686 MathLib::Point3d& new_seg_beg_pnt(seg_it->getEndPoint());
687 seg_it++;
688 if (seg_it != sub_segments.end())
689 {
690 findNextSegment(new_seg_beg_pnt, sub_segments, seg_it);
691 }
692 }
693}

References MathLib::sqrDist().

Referenced by MeshGeoToolsLib::mapLineSegment().

◆ triangleLineIntersection()

std::unique_ptr< Point > GeoLib::triangleLineIntersection ( MathLib::Point3d const & a,
MathLib::Point3d const & b,
MathLib::Point3d const & c,
MathLib::Point3d const & p,
MathLib::Point3d const & q )

Calculates the intersection points of a line PQ and a triangle ABC. This method requires ABC to be counterclockwise and PQ to point downward.

Returns
Intersection point or nullptr if there is no intersection.

Definition at line 367 of file AnalyticalGeometry.cpp.

371{
372 Eigen::Vector3d const pq = q.asEigenVector3d() - p.asEigenVector3d();
373 Eigen::Vector3d const pa = a.asEigenVector3d() - p.asEigenVector3d();
374 Eigen::Vector3d const pb = b.asEigenVector3d() - p.asEigenVector3d();
375 Eigen::Vector3d const pc = c.asEigenVector3d() - p.asEigenVector3d();
376
377 double u = pq.cross(pc).dot(pb);
378 if (u < 0)
379 {
380 return nullptr;
381 }
382 double v = pq.cross(pa).dot(pc);
383 if (v < 0)
384 {
385 return nullptr;
386 }
387 double w = pq.cross(pb).dot(pa);
388 if (w < 0)
389 {
390 return nullptr;
391 }
392
393 const double denom(1.0 / (u + v + w));
394 u *= denom;
395 v *= denom;
396 w *= denom;
397 return std::make_unique<GeoLib::Point>(u * a[0] + v * b[0] + w * c[0],
398 u * a[1] + v * b[1] + w * c[1],
399 u * a[2] + v * b[2] + w * c[2]);
400}

References MathLib::Point3d::asEigenVector3d().

Referenced by MeshGeoToolsLib::GeoMapper::getMeshElevation().