OGS
AnalyticalGeometry.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
5
6#include <Eigen/Geometry>
7#include <algorithm>
8#include <cmath>
9#include <limits>
10
11#include "BaseLib/StringTools.h"
13#include "PointVec.h"
14#include "Polyline.h"
15#include "predicates.h"
16
18{
20 MathLib::Point3d const& c)
21{
22 return orient2d(const_cast<double*>(a.data()),
23 const_cast<double*>(b.data()),
24 const_cast<double*>(c.data()));
25}
26
28 MathLib::Point3d const& b,
29 MathLib::Point3d const& c)
30{
31 return orient2dfast(const_cast<double*>(a.data()),
32 const_cast<double*>(b.data()),
33 const_cast<double*>(c.data()));
34}
35} // namespace ExactPredicates
36
37namespace GeoLib
38{
40 MathLib::Point3d const& p1,
41 MathLib::Point3d const& p2)
42{
43 double const orientation = ExactPredicates::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}
54
56 MathLib::Point3d const& p1,
57 MathLib::Point3d const& p2)
58{
59 double const orientation =
61 if (orientation > 0)
62 {
63 return CCW;
64 }
65 if (orientation < 0)
66 {
67 return CW;
68 }
69 return COLLINEAR;
70}
71
72bool parallel(Eigen::Vector3d v, Eigen::Vector3d w)
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}
127
129 GeoLib::LineSegment const& s1,
130 GeoLib::Point& s)
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}
251
255 GeoLib::Point& intersection_pnt)
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 != ply->end() - 2; ++seg_it0)
261 {
262 seg_it1 = seg_it0 + 2;
263 std::size_t const seg_num_0 = seg_it0.getSegmentNumber();
264 for (; seg_it1 != ply->end(); ++seg_it1)
265 {
266 // Do not check first and last segment, because they are
267 // neighboured.
268 if (!(seg_num_0 == 0 && seg_it1.getSegmentNumber() == n_segs - 1))
269 {
270 if (lineSegmentIntersect(*seg_it0, *seg_it1, intersection_pnt))
271 {
272 return true;
273 }
274 }
275 }
276 }
277 return false;
278}
279
280void rotatePoints(Eigen::Matrix3d const& rot_mat,
281 std::vector<GeoLib::Point*>& pnts)
282{
283 rotatePoints(rot_mat, pnts.begin(), pnts.end());
284}
285
286Eigen::Matrix3d computeRotationMatrixToXY(Eigen::Vector3d const& n)
287{
288 Eigen::Matrix3d rot_mat = Eigen::Matrix3d::Zero();
289 // check if normal points already in the right direction
290 if (n[0] == 0 && n[1] == 0)
291 {
292 rot_mat(1, 1) = 1.0;
293
294 if (n[2] > 0)
295 {
296 // identity matrix
297 rot_mat(0, 0) = 1.0;
298 rot_mat(2, 2) = 1.0;
299 }
300 else
301 {
302 // rotate by pi about the y-axis
303 rot_mat(0, 0) = -1.0;
304 rot_mat(2, 2) = -1.0;
305 }
306
307 return rot_mat;
308 }
309
310 // sqrt (n_1^2 + n_3^2)
311 double const h0(std::sqrt(n[0] * n[0] + n[2] * n[2]));
312
313 // In case the x and z components of the normal are both zero the rotation
314 // to the x-z-plane is not required, i.e. only the rotation in the z-axis is
315 // required. The angle is either pi/2 or 3/2*pi. Thus the components of
316 // rot_mat are as follows.
317 if (h0 < std::numeric_limits<double>::epsilon())
318 {
319 rot_mat(0, 0) = 1.0;
320 if (n[1] > 0)
321 {
322 rot_mat(1, 2) = -1.0;
323 rot_mat(2, 1) = 1.0;
324 }
325 else
326 {
327 rot_mat(1, 2) = 1.0;
328 rot_mat(2, 1) = -1.0;
329 }
330 return rot_mat;
331 }
332
333 double const h1(1 / n.norm());
334
335 // general case: calculate entries of rotation matrix
336 rot_mat(0, 0) = n[2] / h0;
337 rot_mat(0, 1) = 0;
338 rot_mat(0, 2) = -n[0] / h0;
339 rot_mat(1, 0) = -n[1] * n[0] / h0 * h1;
340 rot_mat(1, 1) = h0 * h1;
341 rot_mat(1, 2) = -n[1] * n[2] / h0 * h1;
342 rot_mat(2, 0) = n[0] * h1;
343 rot_mat(2, 1) = n[1] * h1;
344 rot_mat(2, 2) = n[2] * h1;
345
346 return rot_mat;
347}
348
349Eigen::Matrix3d rotatePointsToXY(std::vector<GeoLib::Point*>& pnts)
350{
351 return rotatePointsToXY(pnts.begin(), pnts.end(), pnts.begin(), pnts.end());
352}
353
354std::unique_ptr<GeoLib::Point> triangleLineIntersection(
355 MathLib::Point3d const& a, MathLib::Point3d const& b,
356 MathLib::Point3d const& c, MathLib::Point3d const& p,
357 MathLib::Point3d const& q)
358{
359 Eigen::Vector3d const pq = q.asEigenVector3d() - p.asEigenVector3d();
360 Eigen::Vector3d const pa = a.asEigenVector3d() - p.asEigenVector3d();
361 Eigen::Vector3d const pb = b.asEigenVector3d() - p.asEigenVector3d();
362 Eigen::Vector3d const pc = c.asEigenVector3d() - p.asEigenVector3d();
363
364 double u = pq.cross(pc).dot(pb);
365 if (u < 0)
366 {
367 return nullptr;
368 }
369 double v = pq.cross(pa).dot(pc);
370 if (v < 0)
371 {
372 return nullptr;
373 }
374 double w = pq.cross(pb).dot(pa);
375 if (w < 0)
376 {
377 return nullptr;
378 }
379
380 const double denom(1.0 / (u + v + w));
381 u *= denom;
382 v *= denom;
383 w *= denom;
384 return std::make_unique<GeoLib::Point>(u * a[0] + v * b[0] + w * c[0],
385 u * a[1] + v * b[1] + w * c[1],
386 u * a[2] + v * b[2] + w * c[2]);
387}
388
390 std::vector<GeoLib::Polyline*>& plys)
391{
392 auto computeSegmentIntersections =
393 [&pnt_vec](GeoLib::Polyline& poly0, GeoLib::Polyline& poly1)
394 {
395 for (auto seg0_it(poly0.begin()); seg0_it != poly0.end(); ++seg0_it)
396 {
397 for (auto seg1_it(poly1.begin()); seg1_it != poly1.end(); ++seg1_it)
398 {
399 GeoLib::Point s(0.0, 0.0, 0.0, pnt_vec.size());
400 if (lineSegmentIntersect(*seg0_it, *seg1_it, s))
401 {
402 std::size_t const id(
403 pnt_vec.push_back(new GeoLib::Point(s)));
404 poly0.insertPoint(seg0_it.getSegmentNumber() + 1, id);
405 poly1.insertPoint(seg1_it.getSegmentNumber() + 1, id);
406 }
407 }
408 }
409 };
410
411 for (auto it0(plys.begin()); it0 != plys.end(); ++it0)
412 {
413 auto it1(it0);
414 ++it1;
415 for (; it1 != plys.end(); ++it1)
416 {
417 computeSegmentIntersections(*(*it0), *(*it1));
418 }
419 }
420}
421
422std::tuple<std::vector<GeoLib::Point*>, Eigen::Vector3d>
424{
425 // 1 copy all points
426 std::vector<GeoLib::Point*> polygon_points;
427 polygon_points.reserve(polygon_in.getNumberOfPoints());
428 for (std::size_t k(0); k < polygon_in.getNumberOfPoints(); k++)
429 {
430 polygon_points.push_back(new GeoLib::Point(*(polygon_in.getPoint(k))));
431 }
432
433 // 2 rotate points
434 auto [plane_normal, d_polygon] = GeoLib::getNewellPlane(polygon_points);
435 Eigen::Matrix3d const rot_mat =
437 GeoLib::rotatePoints(rot_mat, polygon_points);
438
439 // 3 set z coord to zero
440 std::for_each(polygon_points.begin(), polygon_points.end(),
441 [](GeoLib::Point* p) { (*p)[2] = 0.0; });
442
443 return {polygon_points, plane_normal};
444}
445
446std::vector<MathLib::Point3d> lineSegmentIntersect2d(
447 GeoLib::LineSegment const& ab, GeoLib::LineSegment const& cd)
448{
449 GeoLib::Point const& a{ab.getBeginPoint()};
450 GeoLib::Point const& b{ab.getEndPoint()};
451 GeoLib::Point const& c{cd.getBeginPoint()};
452 GeoLib::Point const& d{cd.getEndPoint()};
453
454 double const orient_abc(getOrientation(a, b, c));
455 double const orient_abd(getOrientation(a, b, d));
456
457 // check if the segment (cd) lies on the left or on the right of (ab)
458 if ((orient_abc > 0 && orient_abd > 0) ||
459 (orient_abc < 0 && orient_abd < 0))
460 {
461 return std::vector<MathLib::Point3d>();
462 }
463
464 // check: (cd) and (ab) are on the same line
465 if (orient_abc == 0.0 && orient_abd == 0.0)
466 {
467 double const eps(std::numeric_limits<double>::epsilon());
468 if (MathLib::sqrDist2d(a, c) < eps && MathLib::sqrDist2d(b, d) < eps)
469 {
470 return {{a, b}};
471 }
472 if (MathLib::sqrDist2d(a, d) < eps && MathLib::sqrDist2d(b, c) < eps)
473 {
474 return {{a, b}};
475 }
476
477 // Since orient_ab and orient_abd vanish, a, b, c, d are on the same
478 // line and for this reason it is enough to check the x-component.
479 auto isPointOnSegment = [](double q, double p0, double p1)
480 {
481 double const t((q - p0) / (p1 - p0));
482 return 0 <= t && t <= 1;
483 };
484
485 // check if c in (ab)
486 if (isPointOnSegment(c[0], a[0], b[0]))
487 {
488 // check if a in (cd)
489 if (isPointOnSegment(a[0], c[0], d[0]))
490 {
491 return {{a, c}};
492 }
493 // check b == c
494 if (MathLib::sqrDist2d(b, c) < eps)
495 {
496 return {{b}};
497 }
498 // check if b in (cd)
499 if (isPointOnSegment(b[0], c[0], d[0]))
500 {
501 return {{b, c}};
502 }
503 // check d in (ab)
504 if (isPointOnSegment(d[0], a[0], b[0]))
505 {
506 return {{c, d}};
507 }
508 std::stringstream err;
509 err.precision(std::numeric_limits<double>::max_digits10);
510 err << ab << " x " << cd;
511 OGS_FATAL(
512 "The case of parallel line segments ({:s}) is not handled yet. "
513 "Aborting.",
514 err.str());
515 }
516
517 // check if d in (ab)
518 if (isPointOnSegment(d[0], a[0], b[0]))
519 {
520 // check if a in (cd)
521 if (isPointOnSegment(a[0], c[0], d[0]))
522 {
523 return {{a, d}};
524 }
525 // check if b==d
526 if (MathLib::sqrDist2d(b, d) < eps)
527 {
528 return {{b}};
529 }
530 // check if b in (cd)
531 if (isPointOnSegment(b[0], c[0], d[0]))
532 {
533 return {{b, d}};
534 }
535 // d in (ab), b not in (cd): check c in (ab)
536 if (isPointOnSegment(c[0], a[0], b[0]))
537 {
538 return {{c, d}};
539 }
540
541 std::stringstream err;
542 err.precision(std::numeric_limits<double>::max_digits10);
543 err << ab << " x " << cd;
544 OGS_FATAL(
545 "The case of parallel line segments ({:s}) is not handled yet. "
546 "Aborting.",
547 err.str());
548 }
549 return std::vector<MathLib::Point3d>();
550 }
551
552 // precondition: points a, b, c are collinear
553 // the function checks if the point c is onto the line segment (a,b)
554 auto isCollinearPointOntoLineSegment = [](MathLib::Point3d const& a,
555 MathLib::Point3d const& b,
556 MathLib::Point3d const& c)
557 {
558 if (b[0] - a[0] != 0)
559 {
560 double const t = (c[0] - a[0]) / (b[0] - a[0]);
561 return 0.0 <= t && t <= 1.0;
562 }
563 if (b[1] - a[1] != 0)
564 {
565 double const t = (c[1] - a[1]) / (b[1] - a[1]);
566 return 0.0 <= t && t <= 1.0;
567 }
568 if (b[2] - a[2] != 0)
569 {
570 double const t = (c[2] - a[2]) / (b[2] - a[2]);
571 return 0.0 <= t && t <= 1.0;
572 }
573 return false;
574 };
575
576 if (orient_abc == 0.0)
577 {
578 if (isCollinearPointOntoLineSegment(a, b, c))
579 {
580 return {{c}};
581 }
582 return std::vector<MathLib::Point3d>();
583 }
584
585 if (orient_abd == 0.0)
586 {
587 if (isCollinearPointOntoLineSegment(a, b, d))
588 {
589 return {{d}};
590 }
591 return std::vector<MathLib::Point3d>();
592 }
593
594 // check if the segment (ab) lies on the left or on the right of (cd)
595 double const orient_cda(getOrientation(c, d, a));
596 double const orient_cdb(getOrientation(c, d, b));
597 if ((orient_cda > 0 && orient_cdb > 0) ||
598 (orient_cda < 0 && orient_cdb < 0))
599 {
600 return std::vector<MathLib::Point3d>();
601 }
602
603 // at this point it is sure that there is an intersection and the system of
604 // linear equations will be invertible
605 // solve the two linear equations (b-a, c-d) (t, s)^T = (c-a) simultaneously
606 Eigen::Matrix2d mat;
607 mat(0, 0) = b[0] - a[0];
608 mat(0, 1) = c[0] - d[0];
609 mat(1, 0) = b[1] - a[1];
610 mat(1, 1) = c[1] - d[1];
611 Eigen::Vector2d rhs{c[0] - a[0], c[1] - a[1]};
612
613 rhs = mat.partialPivLu().solve(rhs);
614 if (0 <= rhs[1] && rhs[1] <= 1.0)
615 {
616 return {MathLib::Point3d{std::array<double, 3>{
617 {c[0] + rhs[1] * (d[0] - c[0]), c[1] + rhs[1] * (d[1] - c[1]),
618 c[2] + rhs[1] * (d[2] - c[2])}}}};
619 }
620 return std::vector<MathLib::Point3d>(); // parameter s not in the valid
621 // range
622}
623
624void sortSegments(MathLib::Point3d const& seg_beg_pnt,
625 std::vector<GeoLib::LineSegment>& sub_segments)
626{
627 double const eps(std::numeric_limits<double>::epsilon());
628
629 auto findNextSegment =
630 [&eps](MathLib::Point3d const& seg_beg_pnt,
631 std::vector<GeoLib::LineSegment>& sub_segments,
632 std::vector<GeoLib::LineSegment>::iterator& sub_seg_it)
633 {
634 if (sub_seg_it == sub_segments.end())
635 {
636 return;
637 }
638 // find appropriate segment for the given segment begin point
639 auto act_beg_seg_it = std::find_if(
640 sub_seg_it, sub_segments.end(),
641 [&seg_beg_pnt, &eps](GeoLib::LineSegment const& seg)
642 {
643 return MathLib::sqrDist(seg_beg_pnt, seg.getBeginPoint()) <
644 eps ||
645 MathLib::sqrDist(seg_beg_pnt, seg.getEndPoint()) < eps;
646 });
647 if (act_beg_seg_it == sub_segments.end())
648 {
649 return;
650 }
651 // if necessary correct orientation of segment, i.e. swap beg and
652 // end
653 if (MathLib::sqrDist(seg_beg_pnt, act_beg_seg_it->getEndPoint()) <
654 MathLib::sqrDist(seg_beg_pnt, act_beg_seg_it->getBeginPoint()))
655 {
656 std::swap(act_beg_seg_it->getBeginPoint(),
657 act_beg_seg_it->getEndPoint());
658 }
659 assert(sub_seg_it != sub_segments.end());
660 // exchange segments within the container
661 if (sub_seg_it != act_beg_seg_it)
662 {
663 std::swap(*sub_seg_it, *act_beg_seg_it);
664 }
665 };
666
667 // find start segment
668 auto seg_it = sub_segments.begin();
669 findNextSegment(seg_beg_pnt, sub_segments, seg_it);
670
671 while (seg_it != sub_segments.end())
672 {
673 MathLib::Point3d& new_seg_beg_pnt(seg_it->getEndPoint());
674 seg_it++;
675 if (seg_it != sub_segments.end())
676 {
677 findNextSegment(new_seg_beg_pnt, sub_segments, seg_it);
678 }
679 }
680}
681
682Eigen::Matrix3d compute2DRotationMatrixToX(Eigen::Vector3d const& v)
683{
684 Eigen::Matrix3d rot_mat = Eigen::Matrix3d::Zero();
685 const double cos_theta = v[0];
686 const double sin_theta = v[1];
687 rot_mat(0, 0) = rot_mat(1, 1) = cos_theta;
688 rot_mat(0, 1) = sin_theta;
689 rot_mat(1, 0) = -sin_theta;
690 rot_mat(2, 2) = 1.0;
691 return rot_mat;
692}
693
694Eigen::Matrix3d compute3DRotationMatrixToX(Eigen::Vector3d const& v)
695{
696 // a vector on the plane
697 Eigen::Vector3d yy = Eigen::Vector3d::Zero();
698 auto const eps = std::numeric_limits<double>::epsilon();
699 if (std::abs(v[0]) > 0.0 && std::abs(v[1]) + std::abs(v[2]) < eps)
700 {
701 yy[2] = 1.0;
702 }
703 else if (std::abs(v[1]) > 0.0 && std::abs(v[0]) + std::abs(v[2]) < eps)
704 {
705 yy[0] = 1.0;
706 }
707 else if (std::abs(v[2]) > 0.0 && std::abs(v[0]) + std::abs(v[1]) < eps)
708 {
709 yy[1] = 1.0;
710 }
711 else
712 {
713 for (unsigned i = 0; i < 3; i++)
714 {
715 if (std::abs(v[i]) > 0.0)
716 {
717 yy[i] = -v[i];
718 break;
719 }
720 }
721 }
722 // z"_vec
723 Eigen::Vector3d const zz = v.cross(yy).normalized();
724 // y"_vec
725 yy = zz.cross(v).normalized();
726
727 Eigen::Matrix3d rot_mat;
728 rot_mat.row(0) = v;
729 rot_mat.row(1) = yy;
730 rot_mat.row(2) = zz;
731 return rot_mat;
732}
733
734} // end namespace GeoLib
#define OGS_FATAL(...)
Definition Error.h:19
GeoLib::Point const & getBeginPoint() const
GeoLib::Point const & getEndPoint() const
This class manages pointers to Points in a std::vector along with a name. It also handles the deletio...
Definition PointVec.h:25
std::size_t push_back(Point *pnt)
Definition PointVec.cpp:124
std::size_t getSegmentNumber() const
Definition Polyline.cpp:376
Class Polyline consists mainly of a reference to a point vector and a vector that stores the indices ...
Definition Polyline.h:29
std::size_t getNumberOfSegments() const
Definition Polyline.cpp:103
std::size_t getNumberOfPoints() const
Definition Polyline.cpp:98
const Point * getPoint(std::size_t i) const
returns the i-th point contained in the polyline
Definition Polyline.cpp:168
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
Eigen::Vector3d const & asEigenVector3d() const
Definition Point3d.h:55
const double * data() const
Definition Point3d.h:51
double getOrientation2d(MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &c)
double getOrientation2dFast(MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &c)
Orientation getOrientationFast(MathLib::Point3d const &p0, MathLib::Point3d const &p1, MathLib::Point3d const &p2)
Eigen::Matrix3d compute3DRotationMatrixToX(Eigen::Vector3d const &v)
bool lineSegmentsIntersect(const GeoLib::Polyline *ply, GeoLib::Polyline::SegmentIterator &seg_it0, GeoLib::Polyline::SegmentIterator &seg_it1, GeoLib::Point &intersection_pnt)
void computeAndInsertAllIntersectionPoints(GeoLib::PointVec &pnt_vec, std::vector< GeoLib::Polyline * > &plys)
void rotatePoints(Eigen::Matrix3d const &rot_mat, InputIterator pnts_begin, InputIterator pnts_end)
bool parallel(Eigen::Vector3d v, Eigen::Vector3d w)
std::tuple< std::vector< GeoLib::Point * >, Eigen::Vector3d > rotatePolygonPointsToXY(GeoLib::Polygon const &polygon_in)
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)
void sortSegments(MathLib::Point3d const &seg_beg_pnt, std::vector< GeoLib::LineSegment > &sub_segments)
std::vector< MathLib::Point3d > lineSegmentIntersect2d(GeoLib::LineSegment const &ab, GeoLib::LineSegment const &cd)
std::unique_ptr< GeoLib::Point > triangleLineIntersection(MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &c, MathLib::Point3d const &p, MathLib::Point3d const &q)
std::pair< Eigen::Vector3d, double > getNewellPlane(InputIterator pnts_begin, InputIterator pnts_end)
Eigen::Matrix3d compute2DRotationMatrixToX(Eigen::Vector3d const &v)
bool lineSegmentIntersect(GeoLib::LineSegment const &s0, GeoLib::LineSegment const &s1, GeoLib::Point &s)
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
double sqrDist(MathLib::Point3d const &p0, MathLib::Point3d const &p1)
Definition Point3d.cpp:19
double orient2dfast(double *, double *, double *)
double orient2d(double *, double *, double *)