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 <iterator>
10#include <limits>
11
12#include "BaseLib/StringTools.h"
14#include "PointVec.h"
15#include "Polyline.h"
16#include "predicates.h"
17
18namespace
19{
21 MathLib::Point3d const& c)
22{
23 return orient2d(const_cast<double*>(a.data()),
24 const_cast<double*>(b.data()),
25 const_cast<double*>(c.data()));
26}
27
29 MathLib::Point3d const& b,
30 MathLib::Point3d const& c)
31{
32 return orient2dfast(const_cast<double*>(a.data()),
33 const_cast<double*>(b.data()),
34 const_cast<double*>(c.data()));
35}
36} // namespace
37
38namespace GeoLib
39{
41 MathLib::Point3d const& p1,
42 MathLib::Point3d const& p2)
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}
55
57 MathLib::Point3d const& p1,
58 MathLib::Point3d const& p2)
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}
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.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}
280
281void rotatePoints(Eigen::Matrix3d const& rot_mat,
282 std::vector<GeoLib::Point*>& pnts)
283{
284 rotatePoints(rot_mat, pnts.begin(), pnts.end());
285}
286
287Eigen::Matrix3d computeRotationMatrixToXY(Eigen::Vector3d const& n)
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}
349
350Eigen::Matrix3d rotatePointsToXY(std::vector<GeoLib::Point*>& pnts)
351{
352 return rotatePointsToXY(pnts.begin(), pnts.end(), pnts.begin(), pnts.end());
353}
354
355std::unique_ptr<GeoLib::Point> triangleLineIntersection(
356 MathLib::Point3d const& a, MathLib::Point3d const& b,
357 MathLib::Point3d const& c, MathLib::Point3d const& p,
358 MathLib::Point3d const& q)
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}
389
391 std::vector<GeoLib::Polyline*>& plys)
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}
422
423std::tuple<std::vector<GeoLib::Point*>, Eigen::Vector3d>
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}
446
447std::vector<MathLib::Point3d> lineSegmentIntersect2d(
448 GeoLib::LineSegment const& ab, GeoLib::LineSegment const& cd)
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}
624
625void sortSegments(MathLib::Point3d const& seg_beg_pnt,
626 std::vector<GeoLib::LineSegment>& sub_segments)
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}
682
683Eigen::Matrix3d compute2DRotationMatrixToX(Eigen::Vector3d const& v)
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}
694
695Eigen::Matrix3d compute3DRotationMatrixToX(Eigen::Vector3d const& v)
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}
734
735} // end namespace GeoLib
#define OGS_FATAL(...)
Definition Error.h:10
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:165
SegmentIterator end() const
Definition Polyline.h:167
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
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 getOrientation2dFast(MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &c)
double getOrientation2d(MathLib::Point3d const &a, MathLib::Point3d const &b, MathLib::Point3d const &c)
double orient2dfast(double *, double *, double *)
double orient2d(double *, double *, double *)