OGS
AnalyticalGeometry-impl.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4namespace GeoLib
5{
6template <typename InputIterator>
7std::pair<Eigen::Vector3d, double> getNewellPlane(InputIterator pnts_begin,
8 InputIterator pnts_end)
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}
37
38template <class T_POINT>
39std::pair<Eigen::Vector3d, double> getNewellPlane(
40 const std::vector<T_POINT*>& pnts)
41{
42 return getNewellPlane(pnts.begin(), pnts.end());
43}
44
45template <class T_POINT>
46std::pair<Eigen::Vector3d, double> getNewellPlane(
47 const std::vector<T_POINT>& pnts)
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}
68
69template <typename InputIterator>
70void rotatePoints(Eigen::Matrix3d const& rot_mat, InputIterator pnts_begin,
71 InputIterator pnts_end)
72{
73 for (auto it = pnts_begin; it != pnts_end; ++it)
74 {
75 (*it)->asEigenVector3d() = rot_mat * (*it)->asEigenVector3d();
76 }
77}
78
79template <typename InputIterator1, typename InputIterator2>
80Eigen::Matrix3d rotatePointsToXY(InputIterator1 p_pnts_begin,
81 InputIterator1 p_pnts_end,
82 InputIterator2 r_pnts_begin,
83 InputIterator2 r_pnts_end)
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}
102
103template <typename P>
104void rotatePoints(Eigen::Matrix3d const& rot_mat, std::vector<P*> const& pnts)
105{
106 rotatePoints(rot_mat, pnts.begin(), pnts.end());
107}
108
109} // end namespace GeoLib
void rotatePoints(Eigen::Matrix3d const &rot_mat, InputIterator pnts_begin, InputIterator pnts_end)
Eigen::Matrix3d computeRotationMatrixToXY(Eigen::Vector3d const &n)
Eigen::Matrix3d rotatePointsToXY(InputIterator1 p_pnts_begin, InputIterator1 p_pnts_end, InputIterator2 r_pnts_begin, InputIterator2 r_pnts_end)
std::pair< Eigen::Vector3d, double > getNewellPlane(InputIterator pnts_begin, InputIterator pnts_end)