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

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

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

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

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

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

Referenced by detail::getRotationMatrixToGlobal().

◆ computeAndInsertAllIntersectionPoints() [1/2]

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

Definition at line 390 of file AnalyticalGeometry.cpp.

392{
393 auto computeSegmentIntersections =
394 [&pnt_vec](GeoLib::Polyline& poly0, GeoLib::Polyline& poly1)
395 {
396 for (auto seg0_it(poly0.begin()); seg0_it != poly0.end(); ++seg0_it)
397 {
398 for (auto seg1_it(poly1.begin()); seg1_it != poly1.end(); ++seg1_it)
399 {
400 GeoLib::Point s(0.0, 0.0, 0.0, pnt_vec.size());
401 if (lineSegmentIntersect(*seg0_it, *seg1_it, s))
402 {
403 std::size_t const id(
404 pnt_vec.push_back(new GeoLib::Point(s)));
405 poly0.insertPoint(seg0_it.getSegmentNumber() + 1, id);
406 poly1.insertPoint(seg1_it.getSegmentNumber() + 1, id);
407 }
408 }
409 }
410 };
411
412 for (auto it0(plys.begin()); it0 != plys.end(); ++it0)
413 {
414 auto it1(it0);
415 ++it1;
416 for (; it1 != plys.end(); ++it1)
417 {
418 computeSegmentIntersections(*(*it0), *(*it1));
419 }
420 }
421}
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:165
SegmentIterator end() const
Definition Polyline.h:167
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 287 of file AnalyticalGeometry.cpp.

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

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

439{
440 if (id0 == id1)
441 {
442 ERR("no valid edge id0 == id1 == {:d}.", id0);
443 return false;
444 }
445 if (id0 > id1)
446 {
447 std::swap(id0, id1);
448 }
449 const std::size_t n(ply.getNumberOfPoints() - 1);
450 for (std::size_t k(0); k < n; k++)
451 {
452 std::size_t ply_pnt0(ply.getPointID(k));
453 std::size_t ply_pnt1(ply.getPointID(k + 1));
454 if (ply_pnt0 > ply_pnt1)
455 {
456 std::swap(ply_pnt0, ply_pnt1);
457 }
458 if (ply_pnt0 == id0 && ply_pnt1 == id1)
459 {
460 return true;
461 }
462 }
463 return false;
464}
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:10

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

499{
500 auto const& point_id_map = points_vec.getIDMap();
501 auto polyline = std::make_unique<Polyline>(points_vec.getVector());
502 for (auto point_id : point_ids)
503 {
504 if (point_id >= point_id_map.size())
505 {
506 WARN("The point id {} doesn't exist in the underlying PointVec.",
507 point_id);
508 continue;
509 }
510 polyline->addPoint(point_id_map[point_id]);
511 }
512 return polyline;
513}
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 179 of file Polygon.cpp.

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

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

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

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

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

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

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

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

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

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

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

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

424{
425 if (polyline.getPointsVec().size() != used_points.size())
426 {
427 OGS_FATAL(
428 "internal error in markUsedPoints(): polyline based on point "
429 "vector of size {}, given used_points has size {}",
430 polyline.getPointsVec().size(), used_points.size());
431 }
432 for (std::size_t i = 0; i < polyline.getNumberOfPoints(); ++i)
433 {
434 used_points[polyline.getPointID(i)] = true;
435 }
436}

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

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

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

467{
468 if (lhs.getNumberOfPoints() != rhs.getNumberOfPoints())
469 {
470 return false;
471 }
472
473 const std::size_t n(lhs.getNumberOfPoints());
474 for (std::size_t k(0); k < n; k++)
475 {
476 if (lhs.getPointID(k) != rhs.getPointID(k))
477 {
478 return false;
479 }
480 }
481
482 return true;
483}

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

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

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

489{
490 if (i == j)
491 {
492 return true;
493 }
494 return MathLib::sqrDist(*pnt_vec[i], *pnt_vec[j]) < prox;
495}

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

409{
410 if (polyline.getPointsVec().size() != mapping.size())
411 {
412 OGS_FATAL(
413 "internal error in resetPointIDs(): polyline based on point vector "
414 "of size {}, given mapping has size {}",
415 polyline.getPointsVec().size(), mapping.size());
416 }
417 for (std::size_t i = 0; i < polyline.getNumberOfPoints(); ++i)
418 {
419 polyline.setPointID(i, mapping[polyline.getPointID(i)]);
420 }
421}
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 281 of file AnalyticalGeometry.cpp.

283{
284 rotatePoints(rot_mat, pnts.begin(), pnts.end());
285}
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 350 of file AnalyticalGeometry.cpp.

351{
352 return rotatePointsToXY(pnts.begin(), pnts.end(), pnts.begin(), pnts.end());
353}
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 424 of file AnalyticalGeometry.cpp.

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

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

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

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

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

References MathLib::Point3d::asEigenVector3d().

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