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 16 of file PolylineVec.h.

◆ SurfaceVec

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

Definition at line 17 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 27 of file Polygon.cpp.

28{
29 TOUCHING,
30 CROSSING,
32};
@ INESSENTIAL
INESSENTIAL.
Definition Polygon.cpp:31
@ CROSSING
CROSSING.
Definition Polygon.cpp:30
@ TOUCHING
TOUCHING.
Definition Polygon.cpp:29

◆ GEOTYPE

enum class GeoLib::GEOTYPE
strong
Enumerator
POINT 
POLYLINE 
SURFACE 

Definition at line 11 of file GeoType.h.

◆ Location

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

Definition at line 13 of file Polygon.cpp.

◆ Orientation

Enumerator
CW 
COLLINEAR 
CCW 

Definition at line 13 of file AnalyticalGeometry.h.

14{
15 CW = -1,
16 COLLINEAR = 0,
17 CCW = 1
18};

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 681 of file AnalyticalGeometry.cpp.

682{
683 Eigen::Matrix3d rot_mat = Eigen::Matrix3d::Zero();
684 const double cos_theta = v[0];
685 const double sin_theta = v[1];
686 rot_mat(0, 0) = rot_mat(1, 1) = cos_theta;
687 rot_mat(0, 1) = sin_theta;
688 rot_mat(1, 0) = -sin_theta;
689 rot_mat(2, 2) = 1.0;
690 return rot_mat;
691}

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 693 of file AnalyticalGeometry.cpp.

694{
695 // a vector on the plane
696 Eigen::Vector3d yy = Eigen::Vector3d::Zero();
697 auto const eps = std::numeric_limits<double>::epsilon();
698 if (std::abs(v[0]) > 0.0 && std::abs(v[1]) + std::abs(v[2]) < eps)
699 {
700 yy[2] = 1.0;
701 }
702 else if (std::abs(v[1]) > 0.0 && std::abs(v[0]) + std::abs(v[2]) < eps)
703 {
704 yy[0] = 1.0;
705 }
706 else if (std::abs(v[2]) > 0.0 && std::abs(v[0]) + std::abs(v[1]) < eps)
707 {
708 yy[1] = 1.0;
709 }
710 else
711 {
712 for (unsigned i = 0; i < 3; i++)
713 {
714 if (std::abs(v[i]) > 0.0)
715 {
716 yy[i] = -v[i];
717 break;
718 }
719 }
720 }
721 // z"_vec
722 Eigen::Vector3d const zz = v.cross(yy).normalized();
723 // y"_vec
724 yy = zz.cross(v).normalized();
725
726 Eigen::Matrix3d rot_mat;
727 rot_mat.row(0) = v;
728 rot_mat.row(1) = yy;
729 rot_mat.row(2) = zz;
730 return rot_mat;
731}

Referenced by detail::getRotationMatrixToGlobal().

◆ computeAndInsertAllIntersectionPoints() [1/2]

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

Definition at line 388 of file AnalyticalGeometry.cpp.

390{
391 auto computeSegmentIntersections =
392 [&pnt_vec](GeoLib::Polyline& poly0, GeoLib::Polyline& poly1)
393 {
394 for (auto seg0_it(poly0.begin()); seg0_it != poly0.end(); ++seg0_it)
395 {
396 for (auto seg1_it(poly1.begin()); seg1_it != poly1.end(); ++seg1_it)
397 {
398 GeoLib::Point s(0.0, 0.0, 0.0, pnt_vec.size());
399 if (lineSegmentIntersect(*seg0_it, *seg1_it, s))
400 {
401 std::size_t const id(
402 pnt_vec.push_back(new GeoLib::Point(s)));
403 poly0.insertPoint(seg0_it.getSegmentNumber() + 1, id);
404 poly1.insertPoint(seg1_it.getSegmentNumber() + 1, id);
405 }
406 }
407 }
408 };
409
410 for (auto it0(plys.begin()); it0 != plys.end(); ++it0)
411 {
412 auto it1(it0);
413 ++it1;
414 for (; it1 != plys.end(); ++it1)
415 {
416 computeSegmentIntersections(*(*it0), *(*it1));
417 }
418 }
419}
std::size_t push_back(Point *pnt)
Definition PointVec.cpp:124
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition Polyline.h:29
virtual bool insertPoint(std::size_t pos, std::size_t pnt_id)
Definition Polyline.cpp:44
SegmentIterator begin() const
Definition Polyline.h:177
SegmentIterator end() const
Definition Polyline.h:179
std::size_t size() const
Definition TemplateVec.h:88
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.

◆ 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 285 of file AnalyticalGeometry.cpp.

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

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 494 of file Polyline.cpp.

495{
496 if (id0 == id1)
497 {
498 ERR("no valid edge id0 == id1 == {:d}.", id0);
499 return false;
500 }
501 if (id0 > id1)
502 {
503 std::swap(id0, id1);
504 }
505 const std::size_t n(ply.getNumberOfPoints() - 1);
506 for (std::size_t k(0); k < n; k++)
507 {
508 std::size_t ply_pnt0(ply.getPointID(k));
509 std::size_t ply_pnt1(ply.getPointID(k + 1));
510 if (ply_pnt0 > ply_pnt1)
511 {
512 std::swap(ply_pnt0, ply_pnt1);
513 }
514 if (ply_pnt0 == id0 && ply_pnt1 == id1)
515 {
516 return true;
517 }
518 }
519 return false;
520}
void ERR(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:40
std::size_t getPointID(std::size_t const i) const
Definition Polyline.cpp:149
std::size_t getNumberOfPoints() const
Definition Polyline.cpp:98

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 12 of file GeoType.cpp.

13{
14 switch (geo_type)
15 {
16 case GEOTYPE::POINT:
17 return "POINT";
19 return "POLYLINE";
21 return "SURFACE";
22 }
23
24 // Cannot happen, because switch covers all cases.
25 // Used to silence compiler warning.
26 OGS_FATAL("convertGeoTypeToString(): Given geo type is not supported");
27}
#define OGS_FATAL(...)
Definition Error.h:19

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 79 of file SimplePolygonTree.h.

81{
82 for (auto it0 = list_of_simple_polygon_hierarchies.begin();
83 it0 != list_of_simple_polygon_hierarchies.end();
84 ++it0)
85 {
86 auto it1 = list_of_simple_polygon_hierarchies.begin();
87 while (it1 != list_of_simple_polygon_hierarchies.end())
88 {
89 if (it0 == it1)
90 { // don't check same polygons
91 ++it1;
92 // skip test if it1 points to the end after increment
93 if (it1 == list_of_simple_polygon_hierarchies.end())
94 {
95 break;
96 }
97 }
98 if ((*it0)->isPolygonInside(*it1))
99 {
100 (*it0)->insertSimplePolygonTree(*it1);
101 it1 = list_of_simple_polygon_hierarchies.erase(it1);
102 }
103 else
104 {
105 ++it1;
106 }
107 }
108 }
109}

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

◆ 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 553 of file Polyline.cpp.

555{
556 auto const& point_id_map = points_vec.getIDMap();
557 auto polyline = std::make_unique<Polyline>(points_vec.getVector());
558 for (auto point_id : point_ids)
559 {
560 if (point_id >= point_id_map.size())
561 {
562 WARN("The point id {} doesn't exist in the underlying PointVec.",
563 point_id);
564 continue;
565 }
566 polyline->addPoint(point_id_map[point_id]);
567 }
568 return polyline;
569}
void WARN(fmt::format_string< Args... > fmt, Args &&... args)
Definition Logging.h:34

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 17 of file GEOObjects.cpp.

18{
19 return std::find_if(container.begin(), container.end(),
20 [&name](auto const* vector)
21 { return vector->getName() == name; });
22}

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 10 of file GeoLib/Utils.cpp.

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

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 600 of file GEOObjects.cpp.

602{
603 GeoLib::PointVec const* const pnt_obj(geo_objects.getPointVecObj(geo_name));
604 if (pnt_obj == nullptr)
605 {
606 ERR("Point vector {:s} not found.", geo_name);
607 return -1;
608 }
609 auto const& pnts = pnt_obj->getVector();
610 if (pnts.empty())
611 {
612 ERR("Point vector {:s} is empty.", geo_name);
613 return -1;
614 }
615 std::size_t const n_pnts(pnts.size());
616 std::vector<bool> transfer_pnts(n_pnts, true);
617 if (only_unused_pnts)
618 {
619 markUnusedPoints(geo_objects, geo_name, transfer_pnts);
620 }
621
622 std::vector<GeoLib::Point*> stations;
623 for (std::size_t i = 0; i < n_pnts; ++i)
624 {
625 if (!transfer_pnts[i])
626 {
627 continue;
628 }
629 std::string name = pnt_obj->getItemNameByID(i);
630 if (name.empty())
631 {
632 name = "Station " + std::to_string(i);
633 }
634 stations.push_back(new GeoLib::Station(pnts[i], name));
635 }
636 if (!stations.empty())
637 {
638 geo_objects.addStationVec(std::move(stations), stn_name);
639 }
640 else
641 {
642 WARN("No points found to convert.");
643 return 1;
644 }
645 return 0;
646}
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:25
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 178 of file Polygon.cpp.

180{
181 std::vector<GeoLib::Point> intersections;
183 for (auto&& seg_it : polygon)
184 {
185 if (GeoLib::lineSegmentIntersect(seg_it, segment, s))
186 {
187 intersections.push_back(s);
188 }
189 }
190
191 return intersections;
192}

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 91 of file Polygon.cpp.

94{
95 switch (getLocationOfPoint(a, b, pnt))
96 {
97 case Location::LEFT:
98 {
99 if (a[1] < pnt[1] && pnt[1] <= b[1])
100 {
101 return EdgeType::CROSSING;
102 }
103
105 }
106 case Location::RIGHT:
107 {
108 if (b[1] < pnt[1] && pnt[1] <= a[1])
109 {
110 return EdgeType::CROSSING;
111 }
112
114 }
116 case Location::SOURCE:
118 return EdgeType::TOUCHING;
119 default:
121 }
122}
Location getLocationOfPoint(MathLib::Point3d const &source, MathLib::Point3d const &destination, MathLib::Point3d const &pnt)
Definition Polygon.cpp:44

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 44 of file Polygon.cpp.

47{
48 long double const a[2] = {destination[0] - source[0],
49 destination[1] - source[1]}; // vector
50 long double const b[2] = {pnt[0] - source[0],
51 pnt[1] - source[1]}; // vector
52
53 long double const det_2x2(a[0] * b[1] - a[1] * b[0]);
54 constexpr double eps = std::numeric_limits<double>::epsilon();
55
56 if (det_2x2 > eps)
57 {
58 return Location::LEFT;
59 }
60 if (eps < std::abs(det_2x2))
61 {
62 return Location::RIGHT;
63 }
64 if (a[0] * b[0] < 0.0 || a[1] * b[1] < 0.0)
65 {
66 return Location::BEHIND;
67 }
68 if (a[0] * a[0] + a[1] * a[1] < b[0] * b[0] + b[1] * b[1])
69 {
70 return Location::BEYOND;
71 }
72 if (MathLib::sqrDist(pnt, source) < pow(eps, 2))
73 {
74 return Location::SOURCE;
75 }
76 if (MathLib::sqrDist(pnt, destination) < std::sqrt(eps))
77 {
79 }
80 return Location::BETWEEN;
81}
double sqrDist(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.cpp:19

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 39 of file AnalyticalGeometry-impl.h.

41{
42 return getNewellPlane(pnts.begin(), pnts.end());
43}
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 46 of file AnalyticalGeometry-impl.h.

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

◆ 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 7 of file AnalyticalGeometry-impl.h.

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

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 39 of file AnalyticalGeometry.cpp.

42{
43 double const orientation = getOrientation2d(p0, p1, p2);
44 if (orientation > 0)
45 {
46 return CCW;
47 }
48 if (orientation < 0)
49 {
50 return CW;
51 }
52 return COLLINEAR;
53}

References CCW, COLLINEAR, and CW.

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 55 of file AnalyticalGeometry.cpp.

58{
59 double const orientation = getOrientation2dFast(p0, p1, p2);
60 if (orientation > 0)
61 {
62 return CCW;
63 }
64 if (orientation < 0)
65 {
66 return CW;
67 }
68 return COLLINEAR;
69}

References CCW, COLLINEAR, and CW.

◆ isBorehole()

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

Definition at line 95 of file StationBorehole.cpp.

96{
97 auto const* bh(dynamic_cast<GeoLib::StationBorehole const*>(pnt));
98 return bh != nullptr;
99}
A borehole as a geometric object.

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

◆ isStation()

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

Definition at line 66 of file Station.cpp.

67{
68 auto const* bh(dynamic_cast<GeoLib::Station const*>(pnt));
69 return bh != nullptr;
70}
A Station (observation site) is basically a Point with some additional information.
Definition Station.h:26

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 127 of file AnalyticalGeometry.cpp.

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

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

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 251 of file AnalyticalGeometry.cpp.

255{
256 std::size_t const n_segs(ply->getNumberOfSegments());
257 // Neighbouring segments always intersects at a common vertex. The algorithm
258 // checks for intersections of non-neighbouring segments.
259 for (seg_it0 = ply->begin(); seg_it0 != ply->end() - 2; ++seg_it0)
260 {
261 seg_it1 = seg_it0 + 2;
262 std::size_t const seg_num_0 = seg_it0.getSegmentNumber();
263 for (; seg_it1 != ply->end(); ++seg_it1)
264 {
265 // Do not check first and last segment, because they are
266 // neighboured.
267 if (!(seg_num_0 == 0 && seg_it1.getSegmentNumber() == n_segs - 1))
268 {
269 if (lineSegmentIntersect(*seg_it0, *seg_it1, intersection_pnt))
270 {
271 return true;
272 }
273 }
274 }
275 }
276 return false;
277}
std::size_t getSegmentNumber() const
Definition Polyline.cpp:376
std::size_t getNumberOfSegments() const
Definition Polyline.cpp:103

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 562 of file GEOObjects.cpp.

565{
566 GeoLib::PolylineVec const* const ply_obj(
567 geo_objects.getPolylineVecObj(geo_name));
568 if (ply_obj)
569 {
570 std::vector<GeoLib::Polyline*> const& lines(ply_obj->getVector());
571 for (auto* line : lines)
572 {
573 std::size_t const n_pnts(line->getNumberOfPoints());
574 for (std::size_t i = 0; i < n_pnts; ++i)
575 {
576 transfer_pnts[line->getPointID(i)] = false;
577 }
578 }
579 }
580
581 GeoLib::SurfaceVec const* const sfc_obj(
582 geo_objects.getSurfaceVecObj(geo_name));
583 if (sfc_obj)
584 {
585 std::vector<GeoLib::Surface*> const& surfaces = sfc_obj->getVector();
586 for (auto* sfc : surfaces)
587 {
588 std::size_t const n_tri(sfc->getNumberOfTriangles());
589 for (std::size_t i = 0; i < n_tri; ++i)
590 {
591 GeoLib::Triangle const& t = *(*sfc)[i];
592 transfer_pnts[t[0]] = false;
593 transfer_pnts[t[1]] = false;
594 transfer_pnts[t[2]] = false;
595 }
596 }
597 }
598}
TemplateVec< GeoLib::Surface > SurfaceVec
Definition SurfaceVec.h:17
TemplateVec< GeoLib::Polyline > PolylineVec
class PolylineVec encapsulate a std::vector of Polylines additional one can give the vector of polyli...
Definition PolylineVec.h:16

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 479 of file Polyline.cpp.

480{
481 if (polyline.getPointsVec().size() != used_points.size())
482 {
483 OGS_FATAL(
484 "internal error in markUsedPoints(): polyline based on point "
485 "vector of size {}, given used_points has size {}",
486 polyline.getPointsVec().size(), used_points.size());
487 }
488 for (std::size_t i = 0; i < polyline.getNumberOfPoints(); ++i)
489 {
490 used_points[polyline.getPointID(i)] = true;
491 }
492}

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 126 of file Surface.cpp.

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

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 80 of file LineSegment.cpp.

81{
82 os << "{(" << s.getBeginPoint() << "), (" << s.getEndPoint() << ")}";
83 return os;
84}

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 86 of file LineSegment.cpp.

89{
90 os << seg_pair.first << " x " << seg_pair.second;
91 return os;
92}

◆ 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 94 of file LineSegment.cpp.

95{
96 double const tol(std::numeric_limits<double>::epsilon());
97 return (MathLib::sqrDist(s0.getBeginPoint(), s1.getBeginPoint()) < tol &&
98 MathLib::sqrDist(s0.getEndPoint(), s1.getEndPoint()) < tol) ||
99 (MathLib::sqrDist(s0.getBeginPoint(), s1.getEndPoint()) < tol &&
100 MathLib::sqrDist(s0.getEndPoint(), s1.getBeginPoint()) < tol);
101}

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 585 of file Polygon.cpp.

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

◆ 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 522 of file Polyline.cpp.

523{
524 if (lhs.getNumberOfPoints() != rhs.getNumberOfPoints())
525 {
526 return false;
527 }
528
529 const std::size_t n(lhs.getNumberOfPoints());
530 for (std::size_t k(0); k < n; k++)
531 {
532 if (lhs.getPointID(k) != rhs.getPointID(k))
533 {
534 return false;
535 }
536 }
537
538 return true;
539}

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

◆ operator==() [4/4]

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

Definition at line 103 of file Surface.cpp.

104{
105 return &lhs == &rhs;
106}

◆ 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 71 of file AnalyticalGeometry.cpp.

72{
73 const double eps(std::numeric_limits<double>::epsilon());
74 double const eps_squared = eps * eps;
75
76 // check degenerated cases
77 if (v.squaredNorm() < eps_squared)
78 {
79 return false;
80 }
81
82 if (w.squaredNorm() < eps_squared)
83 {
84 return false;
85 }
86
87 v.normalize();
88 w.normalize();
89
90 bool parallel(true);
91 if (std::abs(v[0] - w[0]) > eps)
92 {
93 parallel = false;
94 }
95 if (std::abs(v[1] - w[1]) > eps)
96 {
97 parallel = false;
98 }
99 if (std::abs(v[2] - w[2]) > eps)
100 {
101 parallel = false;
102 }
103
104 if (!parallel)
105 {
106 parallel = true;
107 // change sense of direction of v_normalised
108 v *= -1.0;
109 // check again
110 if (std::abs(v[0] - w[0]) > eps)
111 {
112 parallel = false;
113 }
114 if (std::abs(v[1] - w[1]) > eps)
115 {
116 parallel = false;
117 }
118 if (std::abs(v[2] - w[2]) > eps)
119 {
120 parallel = false;
121 }
122 }
123
124 return parallel;
125}

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 541 of file Polyline.cpp.

545{
546 if (i == j)
547 {
548 return true;
549 }
550 return MathLib::sqrDist(*pnt_vec[i], *pnt_vec[j]) < prox;
551}

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 464 of file Polyline.cpp.

465{
466 if (polyline.getPointsVec().size() != mapping.size())
467 {
468 OGS_FATAL(
469 "internal error in resetPointIDs(): polyline based on point vector "
470 "of size {}, given mapping has size {}",
471 polyline.getPointsVec().size(), mapping.size());
472 }
473 for (std::size_t i = 0; i < polyline.getNumberOfPoints(); ++i)
474 {
475 polyline.setPointID(i, mapping[polyline.getPointID(i)]);
476 }
477}
void setPointID(std::size_t idx, std::size_t id)
Definition Polyline.cpp:162
std::vector< Point * > const & getPointsVec() const
Definition Polyline.cpp:174

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 108 of file Surface.cpp.

109{
110 if (surface.getPointVec()->size() != mapping.size())
111 {
112 OGS_FATAL(
113 "internal error in resetPointIDs(): surface based on point vector "
114 "of size {}, given mapping vector has size {}",
115 surface.getPointVec()->size(), mapping.size());
116 }
117 for (std::size_t i = 0; i < surface.getNumberOfTriangles(); ++i)
118 {
119 auto& triangle = *surface[i];
120 const_cast<std::size_t&>(triangle[0]) = mapping[triangle[0]];
121 const_cast<std::size_t&>(triangle[1]) = mapping[triangle[1]];
122 const_cast<std::size_t&>(triangle[2]) = mapping[triangle[2]];
123 }
124}
std::size_t getNumberOfTriangles() const
Definition Surface.cpp:76
const std::vector< Point * > * getPointVec() const

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 70 of file AnalyticalGeometry-impl.h.

72{
73 for (auto it = pnts_begin; it != pnts_end; ++it)
74 {
75 (*it)->asEigenVector3d() = rot_mat * (*it)->asEigenVector3d();
76 }
77}

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 279 of file AnalyticalGeometry.cpp.

281{
282 rotatePoints(rot_mat, pnts.begin(), pnts.end());
283}
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 104 of file AnalyticalGeometry-impl.h.

105{
106 rotatePoints(rot_mat, pnts.begin(), pnts.end());
107}

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 80 of file AnalyticalGeometry-impl.h.

84{
85 assert(std::distance(p_pnts_begin, p_pnts_end) > 2);
86
87 // compute the plane normal
88 auto const [plane_normal, d] =
89 GeoLib::getNewellPlane(p_pnts_begin, p_pnts_end);
90
91 // rotate points into x-y-plane
92 Eigen::Matrix3d const rot_mat = computeRotationMatrixToXY(plane_normal);
93 rotatePoints(rot_mat, r_pnts_begin, r_pnts_end);
94
95 for (auto it = r_pnts_begin; it != r_pnts_end; ++it)
96 {
97 (*(*it))[2] = 0.0; // should be -= d but there are numerical errors
98 }
99
100 return rot_mat;
101}
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< GeoLib::Point * > & pnts)

Definition at line 348 of file AnalyticalGeometry.cpp.

349{
350 return rotatePointsToXY(pnts.begin(), pnts.end(), pnts.begin(), pnts.end());
351}
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.

◆ 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 422 of file AnalyticalGeometry.cpp.

423{
424 // 1 copy all points
425 std::vector<GeoLib::Point*> polygon_points;
426 polygon_points.reserve(polygon_in.getNumberOfPoints());
427 for (std::size_t k(0); k < polygon_in.getNumberOfPoints(); k++)
428 {
429 polygon_points.push_back(new GeoLib::Point(*(polygon_in.getPoint(k))));
430 }
431
432 // 2 rotate points
433 auto [plane_normal, d_polygon] = GeoLib::getNewellPlane(polygon_points);
434 Eigen::Matrix3d const rot_mat =
436 GeoLib::rotatePoints(rot_mat, polygon_points);
437
438 // 3 set z coord to zero
439 std::for_each(polygon_points.begin(), polygon_points.end(),
440 [](GeoLib::Point* p) { (*p)[2] = 0.0; });
441
442 return {polygon_points, plane_normal};
443}

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< GeoLib::LineSegment > & sub_segments )

Definition at line 623 of file AnalyticalGeometry.cpp.

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

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.

◆ 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 353 of file AnalyticalGeometry.cpp.

357{
358 Eigen::Vector3d const pq = q.asEigenVector3d() - p.asEigenVector3d();
359 Eigen::Vector3d const pa = a.asEigenVector3d() - p.asEigenVector3d();
360 Eigen::Vector3d const pb = b.asEigenVector3d() - p.asEigenVector3d();
361 Eigen::Vector3d const pc = c.asEigenVector3d() - p.asEigenVector3d();
362
363 double u = pq.cross(pc).dot(pb);
364 if (u < 0)
365 {
366 return nullptr;
367 }
368 double v = pq.cross(pa).dot(pc);
369 if (v < 0)
370 {
371 return nullptr;
372 }
373 double w = pq.cross(pb).dot(pa);
374 if (w < 0)
375 {
376 return nullptr;
377 }
378
379 const double denom(1.0 / (u + v + w));
380 u *= denom;
381 v *= denom;
382 w *= denom;
383 return std::make_unique<GeoLib::Point>(u * a[0] + v * b[0] + w * c[0],
384 u * a[1] + v * b[1] + w * c[1],
385 u * a[2] + v * b[2] + w * c[2]);
386}

References MathLib::Point3d::asEigenVector3d().

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