PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
geomUtilFunctions.cpp
Go to the documentation of this file.
1/*
2 * -------------------------------------------
3 * Copyright (c) 2021 - 2026 Prashant K. Jha
4 * -------------------------------------------
5 * PeriDEM https://github.com/prashjha/PeriDEM
6 *
7 * Distributed under the Boost Software License, Version 1.0. (See accompanying
8 * file LICENSE)
9 */
10
11#include "geomUtilFunctions.h"
12#include <stdexcept>
13#include "geomObjects.h"
14#include "util/function.h"
15#include <cmath>
16#include "util/io.h"
18#include "nsearch/nsearch.h"
19#include <format>
20#include <iostream>
21
23
24namespace geom {
25
26std::vector<util::Point> getCornerPoints(
27 size_t dim, const std::pair<util::Point, util::Point> &box) {
28
29 if (dim == 1)
30 return {box.first, box.second};
31 else if (dim == 2)
32 return {box.first,
33 util::Point(box.second.d_x, box.first.d_y, 0.),
34 box.second,
35 util::Point(box.first.d_x, box.second.d_y, 0.)};
36 else if (dim == 3) {
37 double a = box.second.d_x - box.first.d_x;
38 double b = box.second.d_y - box.first.d_y;
39 double c = box.second.d_z - box.first.d_z;
40 return {box.first,
41 box.first + util::Point(a, 0., 0.),
42 box.first + util::Point(a, b, 0.),
43 box.first + util::Point(0., b, 0.),
44 box.first + util::Point(0., 0., c),
45 box.first + util::Point(a, 0., c),
46 box.first + util::Point(a, b, c),
47 box.first + util::Point(0., b, c)};
48 }
49 else {
50 throw std::invalid_argument(
52 << "Error: Check dimension = " << dim << ".\n");
53 }
54}
55
56std::vector<std::pair<util::Point, util::Point>> getEdges(size_t dim, const
57std::pair<util::Point, util::Point> &box) {
58
59 std::vector<std::pair<util::Point, util::Point>> data;
60 if (dim == 1) {
61 data.emplace_back(box);
62 return data;
63 } else if (dim == 2) {
64
65 // points returned by below function is in anti-clockwise order
66 auto corner_pts = getCornerPoints(dim, box);
67
68 data.emplace_back(corner_pts[0], corner_pts[1]);
69 data.emplace_back(corner_pts[1], corner_pts[2]);
70 data.emplace_back(corner_pts[2], corner_pts[3]);
71 data.emplace_back(corner_pts[3], corner_pts[0]);
72 return data;
73 } else if (dim == 3) {
74
75 // points returned by below function is in anti-clockwise order
76 // first 4 points are on lower z-plane, and remaining are in upper z-plane
77 auto corner_pts = getCornerPoints(dim, box);
78
79 // edges in lower plane
80 data.emplace_back(corner_pts[0], corner_pts[1]);
81 data.emplace_back(corner_pts[1], corner_pts[2]);
82 data.emplace_back(corner_pts[2], corner_pts[3]);
83 data.emplace_back(corner_pts[3], corner_pts[0]);
84
85 // edges in upper plane
86 data.emplace_back(corner_pts[4], corner_pts[5]);
87 data.emplace_back(corner_pts[5], corner_pts[6]);
88 data.emplace_back(corner_pts[6], corner_pts[7]);
89 data.emplace_back(corner_pts[7], corner_pts[4]);
90
91 // edges parrallel to z-axis
92 data.emplace_back(corner_pts[0], corner_pts[4]);
93 data.emplace_back(corner_pts[1], corner_pts[5]);
94 data.emplace_back(corner_pts[2], corner_pts[6]);
95 data.emplace_back(corner_pts[3], corner_pts[7]);
96
97 return data;
98 } else {
99 throw std::invalid_argument(
101 << "getEdges(): Function implemented for dim = 1,2,3 only.\n");
102 }
103}
104
106 const std::pair<util::Point, util::Point> &box) {
107
108 if (dim == 1)
109 return {0.5 * box.second.d_x + 0.5 * box.first.d_x, 0., 0.};
110 else if (dim == 2)
111 return {0.5 * box.second.d_x + 0.5 * box.first.d_x,
112 0.5 * box.second.d_y + 0.5 * box.first.d_y, 0.};
113 else if (dim == 3)
114 return {0.5 * box.second.d_x + 0.5 * box.first.d_x,
115 0.5 * box.second.d_y + 0.5 * box.first.d_y,
116 0.5 * box.second.d_z + 0.5 * box.first.d_z};
117 else {
118 throw std::invalid_argument(
120 << "Error: Check dimension = " << dim << ".\n");
121 }
122}
123
124bool areBoxesNear(const std::pair<util::Point, util::Point>
125 &b1,
126 const std::pair<util::Point, util::Point> &b2,
127 const double &tol,
128 size_t dim) {
129
130 auto cp1 = getCornerPoints(dim, b1);
131 auto cp2 = getCornerPoints(dim, b2);
132
133 for (auto p : cp1) {
134
135 // check 1: If any of the corner points of box 1 are inside box 2
136 if (isPointInsideBox(p, dim, b2))
137 return true;
138
139 // check 2: If any pair of corner points of box 1 and box 2 are at
140 // distance smaller than the tolerance
141 for (auto pp : cp2) {
142 auto dx = pp - p;
143 if (util::isLess(dx.length(), tol))
144 return true;
145 }
146 }
147
148 // check 3: Check if distance between centers of box 1 and box 2 are below
149 // sum of tolerance, radius of circle inscribed in box 1, and radius of
150 // circle inscribed in box 2
151 auto dxc = getCenter(dim, b2) - getCenter(dim, b1);
152 auto dist = tol + inscribedRadiusInBox(dim, b1) + inscribedRadiusInBox(dim,
153 b2);
154
155 if (util::isLess(dxc.length(), dist))
156 return true;
157
158 // check 4: Check if distance between centers of box 1 and box 2 are below
159 // sum of tolerance, radius of circle inscribed in box 1, and radius of
160 // circle circumscribed in box 2
161 dist = tol + inscribedRadiusInBox(dim, b1) + circumscribedRadiusInBox(dim,
162 b2);
163 if (util::isLess(dxc.length(), dist))
164 return true;
165
166 dist = tol + circumscribedRadiusInBox(dim, b1) + inscribedRadiusInBox(dim,
167 b2);
168 if (util::isLess(dxc.length(), dist))
169 return true;
170
171 return false;
172}
173
174bool isPointInsideBox(util::Point x, size_t dim,
175 const std::pair<util::Point, util::Point> &box) {
176
177 if (dim == 1)
178 return !(util::isLess(x.d_x, box.first.d_x - 1.0E-12) or
179 util::isGreater(x.d_x, box.second.d_x + 1.0E-12));
180 else if (dim == 2)
181 return !(util::isLess(x.d_x, box.first.d_x - 1.0E-12) or
182 util::isLess(x.d_y, box.first.d_y - 1.0E-12) or
183 util::isGreater(x.d_x, box.second.d_x + 1.0E-12) or
184 util::isGreater(x.d_y, box.second.d_y + 1.0E-12));
185 else if (dim == 3)
186 return !(util::isLess(x.d_x, box.first.d_x - 1.0E-12) or
187 util::isLess(x.d_y, box.first.d_y - 1.0E-12) or
188 util::isLess(x.d_z, box.first.d_z - 1.0E-12) or
189 util::isGreater(x.d_x, box.second.d_x + 1.0E-12) or
190 util::isGreater(x.d_y, box.second.d_y + 1.0E-12) or
191 util::isGreater(x.d_z, box.second.d_z + 1.0E-12));
192 else {
193 throw std::invalid_argument(
195 << "isPointInsideBox(): Function implemented for dim = 1,2,3 only.\n");
196 }
197}
198
199double inscribedRadiusInBox(size_t dim,
200 const std::pair<util::Point, util::Point> &box) {
201
202 double r = 0.5 * std::abs(box.second.d_x - box.first.d_x);
203 if (dim == 1)
204 return r;
205 else if (dim == 2) {
206 if (util::isGreater(r, 0.5 * std::abs(box.second.d_y - box.first.d_y)))
207 return 0.5 * std::abs(box.second.d_y - box.first.d_y);
208 else
209 return r;
210 } else if (dim == 3) {
211 if (util::isGreater(r, 0.5 * std::abs(box.second.d_y - box.first.d_y)))
212 r = 0.5 * std::abs(box.second.d_y - box.first.d_y);
213
214 if (util::isGreater(r, 0.5 * std::abs(box.second.d_z - box.first.d_z)))
215 return 0.5 * std::abs(box.second.d_z - box.first.d_z);
216 else
217 return r;
218 } else {
219 throw std::invalid_argument(
221 << "inscribedRadiusInBox(): Function implemented for dim = 1,2,3 only.\n");
222 }
223}
224
225double circumscribedRadiusInBox(size_t dim,
226 const std::pair<util::Point, util::Point> &box) {
227
228 auto xc = getCenter(dim, box);
229 auto cp = getCornerPoints(dim, box);
230
231 auto dx = cp[0] - xc;
232 auto r = dx.length();
233
234 if (dim == 1)
235 return r;
236 else {
237 for (auto p : cp) {
238 dx = p - xc;
239 if (util::isGreater(dx.length(), r))
240 r = dx.length();
241 }
242
243 return r;
244 }
245}
246
247
249 double x_max, double y_min,
250 double y_max) {
251
252 return !(util::isLess(x.d_x, x_min - 1.0E-12) or
253 util::isLess(x.d_y, y_min - 1.0E-12) or
254 util::isGreater(x.d_x, x_max + 1.0E-12) or
255 util::isGreater(x.d_y, y_max + 1.0E-12));
256}
257
259 util::Point x_rt) {
260 return !(util::isLess(x.d_x, x_lb.d_x - 1.0E-12) or
261 util::isLess(x.d_y, x_lb.d_y - 1.0E-12) or
262 util::isGreater(x.d_x, x_rt.d_x + 1.0E-12) or
263 util::isGreater(x.d_y, x_rt.d_y + 1.0E-12));
264}
265
267 double x2, double y1,
268 double y2, double theta) {
269 // we assume that the rectangle has passed the test
270
271 //
272 // (x2,y2)
273 // o
274 //
275 //
276 //
277 //
278 //
279 // o
280 // (x1,y1)
281
282 // get divisors
284 util::Point(x2 - x1, y2 - y1, 0.0), theta);
285
286 // double lam1 = (x2-x1) * std::cos(theta) + (y2-y1) * std::sin(theta);
287 // double lam2 = -(x2-x1) * std::sin(theta) + (y2-y1) * std::cos(theta);
288
289 // get mapped coordinate of x
291 util::Point(x[0] - x1, x[1] - y1, 0.0), theta);
292
293 // double xmap = (x[0]-x1) * std::cos(theta) + (x[1]-y1) * std::sin(theta);
294 // double ymap = -(x[0]-x1) * std::sin(theta) + (x[1]-y1) * std::cos(theta);
295
296 // check if mapped coordinate are out of range [0, lam1] and [0, lam2]
297 return !(util::isLess(xmap[0], -1.0E-12) or
298 util::isLess(xmap[1], -1.0E-12) or
299 util::isGreater(xmap[0], lam[0] + 1.0E-12) or
300 util::isGreater(xmap[1], lam[1] + 1.0E-12));
301}
302
304 util::Point x_rtf) {
305 return !(util::isLess(x.d_x, x_lbb.d_x - 1.0E-12) or
306 util::isLess(x.d_y, x_lbb.d_y - 1.0E-12) or
307 util::isLess(x.d_z, x_lbb.d_z - 1.0E-12) or
308 util::isGreater(x.d_x, x_rtf.d_x + 1.0E-12) or
309 util::isGreater(x.d_y, x_rtf.d_y + 1.0E-12) or
310 util::isGreater(x.d_z, x_rtf.d_z + 1.0E-12));
311}
312
313bool isPointInsideCylinder(const util::Point &p, const double &length, const double
314&radius, const util::Point &axis) {
315
316 double p_dot_a = p * axis;
317 if (p_dot_a > length or p_dot_a < 0.)
318 return false;
319 else {
320
321 auto p_parallel = p - p_dot_a * axis;
322
323 return p_parallel.lengthSq() < radius * radius;
324 }
325}
326
327bool isPointInsideCylinder(const util::Point &p, const double &radius,
328 const util::Point &x1, const util::Point &x2) {
329
330 auto p_new = p - x1;
331 auto a = x2 - x1;
332 double p_dot_a = p_new * a;
333
334 // note here we should 1 if a is not normalized
335 if (p_dot_a > 1. or p_dot_a < 0.)
336 return false;
337 else {
338
339 auto p_parallel = p_new - p_dot_a * a;
340
341 return p_parallel.lengthSq() < radius * radius;
342 }
343}
344
345bool isPointInsideEllipse(const util::Point &p, const util::Point &center, const
346std::vector<double> &radius_vec, unsigned int dim) {
347
348 double d = 0.;
349 auto x = p - center;
350 for (unsigned int i=0; i<dim; i++)
351 d += x[i] * x[i] / (radius_vec[i] * radius_vec[i]);
352
353 return d < 1.;
354}
355
356bool isPointInsideEllipse(const util::Point &p, const util::Point &center, const
357std::vector<double> &radius_vec, unsigned int dim, double &d) {
358
359 d = 0.;
360 auto x = p - center;
361 for (unsigned int i=0; i<dim; i++)
362 d += x[i] * x[i] / (radius_vec[i] * radius_vec[i]);
363
364 return d < 1.;
365}
366
368util::Point &p2,
369 const double &s) {
370 return (1. - s) * p1 + s * p2;
371}
372
373bool doLinesIntersect(const std::pair<util::Point, util::Point> &line_1,
374 const std::pair<util::Point, util::Point> &line_2) {
375
376 // change of variable so that first point of line_1 is at origin
377 // After change of variables:
378 // a is the second point of line_1
379 // b is the first point of line_2
380 // c is the difference of second and first point of line_2
381 auto a = line_1.second - line_1.first;
382 auto b = line_2.first - line_1.first;
383 auto c = line_2.second - line_2.first;
384
385 // check if the two lines are parallel
386 if (util::angle(a / a.length(), c / c.length()) < 1.0E-8)
387 return false;
388
389 double a_dot_a = a.lengthSq();
390 double a_dot_b = a * b;
391 double a_dot_c = a * c;
392 double b_dot_c = b * c;
393 double c_dot_c = c.lengthSq();
394
395 double r = (a_dot_a * b_dot_c - a_dot_b * a_dot_c) /
396 (a_dot_c * a_dot_c - c_dot_c * a_dot_a);
397
398 // if r is in (0,1) then this gives the intersection point
399 // otherwise b + r c gives the point where two vectors originating from
400 // a and originating from b would intersect
401 return r > 0. and r < 1.;
402}
403
404double distanceBetweenLines(const std::pair<util::Point, util::Point> &line_1,
405 const std::pair<util::Point, util::Point>
406 &line_2) {
407
408 // let line 1 is l1(s) = p + s u
409 // and line 2 is l2(r) = q + r v
410 // and let normal to the plane containing line 1 and 2 is
411 // n = u x v / |u x v|
412
413 auto u = line_1.second - line_1.first;
414 auto v = line_2.second - line_2.first;
415 auto w0 = line_1.first - line_2.first;
416
417 double a = u * u;
418 double b = u * v;
419 double c = v * v;
420 double d = u * w0;
421 double e = v * w0;
422
423 auto dp = w0 + ((b * e - c * d) * u + (a * e - b * d) * v) / (a * c - b * b);
424
425 return dp.length();
426}
427
428double
429distanceBetweenSegments(const std::pair<util::Point, util::Point> &line_1,
430 const std::pair<util::Point, util::Point> &line_2) {
431
432 // let line 1 is l1(s) = p + s u
433 // and line 2 is l2(r) = q + r v
434 // and let normal to the plane containing line 1 and 2 is
435 // n = u x v / |u x v|
436
437 auto u = line_1.second - line_1.first;
438 auto v = line_2.second - line_2.first;
439 auto w0 = line_1.first - line_2.first;
440
441 double a = u * u;
442 double b = u * v;
443 double c = v * v;
444 double d = u * w0;
445 double e = v * w0;
446 double D = a * c - b * b;
447 double sc, sN, sD = D;
448 double tc, tN, tD = D;
449
450 // compute line parameters of two closest points
451 if (D < 1.0E-12) {
452
453 sN = 0.;
454 sD = 1.;
455 tN = e;
456 tD = c;
457 } else {
458
459 sN = b * e - c * d;
460 tN = a * e - b * d;
461
462 if (sN < 0.) {
463 sN = 0.;
464 tN = e;
465 tD = c;
466 } else if (sN > sD) {
467 sN = sD;
468 tN = e + b;
469 tD = c;
470 }
471 }
472
473 if (tN < 0.) {
474
475 tN = 0.;
476
477 if (-d < 0.)
478 sN = 0.;
479 else if (-d > a)
480 sN = sD;
481 else {
482 sN = -d;
483 sD = a;
484 }
485 } else if (tN > tD) {
486
487 tN = tD;
488
489 if (-d + b < 0.)
490 sN = 0.;
491 else if (-d + b > a)
492 sN = sD;
493 else {
494 sN = -d + b;
495 sD = a;
496 }
497 }
498
499 sc = std::abs(sN) < 1.0E-12 ? 0. : sN / sD;
500 tc = std::abs(tN) < 1.0E-12 ? 0. : tN / tD;
501
502 auto dp = w0 + sc * u - tc * v;
503
504 return dp.length();
505}
506
507double distanceBetweenPlanes(const std::pair<util::Point, util::Point> &plane_1,
508 const std::pair<util::Point, util::Point>
509 &plane_2) {
510
511 // check if planes are parallel
512 if (util::angle(plane_1.first, plane_2.first) < 1.0E-8)
513 return 0.;
514
515 return std::abs(plane_1.first * (plane_1.second - plane_2.second)) /
516 plane_1.first.length();
517}
518
520 const std::pair<util::Point, util::Point> &line) {
521
522 // line vector
523 auto v = line.second - line.first;
524
525 // vector from 1st point of line to p
526 auto w = p - line.first;
527
528 // project w onto v and add 1st point to get projected point's location
529 auto w_on_line = line.first + (w * v) * v / v.lengthSq();
530
531 return (p - w_on_line).length();
532}
533
535 const std::pair<util::Point, util::Point> &line) {
536
537 // line vector
538 auto v = line.second - line.first;
539
540 // vector from 1st point of line to p
541 auto w = p - line.first;
542
543 // determine if w is on left side or right side of line
544 double w_dot_v = w * v;
545 if (w_dot_v < 1.0E-12)
546 return (p - line.first).length();
547
548 if (w_dot_v > v.lengthSq() - 1.0E-12)
549 return (p - line.second).length();
550
551 // project w onto v and add 1st point to get projected point's location
552 auto w_on_line = line.first + w_dot_v * v / v.lengthSq();
553
554 return (p - w_on_line).length();
555}
556
558 const std::pair<util::Point, util::Point> &plane) {
559
560 // if plane is given by unit normal n and a point a which is contained in it
561 // then the distance of point p from plane is
562 // |(p - a) dot n| / |n|
563
564 auto pa = p - plane.second;
565 return std::abs(pa * plane.first) / plane.first.length();
566}
567
568double computeMeshSize(const std::vector<util::Point> &nodes) {
569
570 double guess = 0.;
571 if (nodes.size() < 2)
572 return guess;
573
574 guess = (nodes[0] - nodes[1]).length();
575 for (size_t i = 0; i < nodes.size(); i++)
576 for (size_t j = 0; j < nodes.size(); j++)
577 if (i != j) {
578 double val = nodes[i].dist(nodes[j]);
579
580 if (util::isLess(val, 1.0E-12)) {
581
582 std::cout << "Check nodes are too close = "
583 << util::io::printStr<util::Point>({nodes[i],
584 nodes[j]})
585 << "\n";
586 std::cout << "Distance = " << val << ", guess = " << guess << "\n";
587 }
588 if (util::isLess(val, guess))
589 guess = val;
590 }
591
592 return guess;
593}
594
595double computeMeshSize(const std::vector<util::Point> &nodes, size_t start,
596 size_t end) {
597
598 double guess = 0.;
599 if (nodes.size() < 2 or (end - start) < 2)
600 return guess;
601
602 guess = (nodes[start] - nodes[start + 1]).length();
603 for (size_t i = start; i < end; i++)
604 for (size_t j = start; j < end; j++)
605 if (i != j) {
606 double val = nodes[i].dist(nodes[j]);
607
608 if (util::isLess(val, 1.0E-12)) {
609
610 std::cout << "Check nodes are too close = "
611 << util::io::printStr<util::Point>({nodes[i],
612 nodes[j]})
613 << "\n";
614 std::cout << "Distance = " << val << ", guess = " << guess << "\n";
615 }
616 if (util::isLess(val, guess))
617 guess = val;
618 }
619
620 return guess;
621}
622
623std::pair<util::Point, util::Point> computeBBox(const std::vector<util::Point> &nodes) {
624
625 auto p1 = util::Point();
626 auto p2 = util::Point();
627 for (const auto& x : nodes) {
628 if (util::isLess(x.d_x, p1.d_x))
629 p1.d_x = x.d_x;
630 if (util::isLess(x.d_y, p1.d_y))
631 p1.d_y = x.d_y;
632 if (util::isLess(x.d_z, p1.d_z))
633 p1.d_z = x.d_z;
634 if (util::isLess(p2.d_x, x.d_x))
635 p2.d_x = x.d_x;
636 if (util::isLess(p2.d_y, x.d_y))
637 p2.d_y = x.d_y;
638 if (util::isLess(p2.d_z, x.d_z))
639 p2.d_z = x.d_z;
640 }
641
642 return {p1, p2};
643}
644
645double computeInscribedRadius(const std::pair<util::Point, util::Point>
646 &box) {
647
648 return 0.5 * (box.first - box.second).length();
649}
650
651std::pair<util::Point, util::Point> toPointBox(const std::vector<double>
652 &p1, const std::vector<double>
653 &p2) {
654 auto q1 = util::Point(p1[0], p1[1], p1[2]);
655 auto q2 = util::Point(p2[0], p2[1], p2[2]);
656 return {q1, q2};
657}
658
659double triangleArea(const util::Point &x1, const util::Point &x2,
660 const util::Point &x3) {
661 return 0.5 * ((x2.d_x - x1.d_x) * (x3.d_y - x1.d_y) -
662 (x3.d_x - x1.d_x) * (x2.d_y - x1.d_y));
663}
664
665void computeNonlocalNeighborhood(const std::vector<util::Point> &nodes,
666 double horizon,
667 std::vector<std::vector<size_t>> &nodeNeighs) {
668 nodeNeighs.resize(nodes.size());
669
670 auto nsearch_p = std::make_unique<NSearch>(nodes);
671 double set_tree_time = nsearch_p->updatePointCloud(nodes, true);
672 set_tree_time += nsearch_p->setInputCloud();
673 std::cout << std::format("Tree setup time (ms) = {}. \n", set_tree_time);
674
675 for (size_t i=0; i<nodes.size(); i++) {
676 std::vector<size_t> neighs;
677 std::vector<double> sqr_dist;
678 nodeNeighs[i].resize(0);
679
680 if (nsearch_p->radiusSearch(nodes[i], horizon, neighs, sqr_dist) > 0) {
681 for (std::size_t j = 0; j < neighs.size(); ++j)
682 if (neighs[j] != i) {
683 nodeNeighs[i].push_back(neighs[j]);
684 }
685 }
686 }
687}
688
689void ellipsoidRotationMatrix(const Ellipsoid &e, double R[9]) {
690
691 if (std::abs(e.d_theta) < 1.0e-15) {
692 R[0] = R[4] = R[8] = 1.;
693 R[1] = R[2] = R[3] = R[5] = R[6] = R[7] = 0.;
694 return;
695 }
696
697 const double kx = e.d_axis.d_x;
698 const double ky = e.d_axis.d_y;
699 const double kz = e.d_axis.d_z;
700 const double c = std::cos(e.d_theta);
701 const double s = std::sin(e.d_theta);
702 const double t = 1.0 - c;
703
704 R[0] = t * kx * kx + c;
705 R[1] = t * kx * ky - kz * s;
706 R[2] = t * kx * kz + ky * s;
707 R[3] = t * kx * ky + kz * s;
708 R[4] = t * ky * ky + c;
709 R[5] = t * ky * kz - kx * s;
710 R[6] = t * kx * kz - ky * s;
711 R[7] = t * ky * kz + kx * s;
712 R[8] = t * kz * kz + c;
713}
714
715} // namespace geom
Ellipsoid: center , semi-axes in a body frame rotated from world by axis–angle (Rodrigues)....
double d_theta
Rotation angle (radians) about d_axis.
util::Point d_axis
Unit rotation axis (axis–angle); default (0,0,1) when .
A class for nearest neighbor search using nanoflann library.
Definition nsearch.h:178
Collects a message with stream syntax for use in an exception.
Definition io.h:52
nsearch::NFlannSearchKd< 3 > NSearch
Definition contact.h:20
util::Point getCenter(size_t dim, const std::pair< util::Point, util::Point > &box)
Returns center point.
double pointDistancePlane(const util::Point &p, const std::pair< util::Point, util::Point > &plane)
Compute distance between point and plane.
double pointDistanceSegment(const util::Point &p, const std::pair< util::Point, util::Point > &line)
Compute distance between point and line.
bool isPointInsideEllipse(const util::Point &p, const util::Point &center, const std::vector< double > &radius_vec, unsigned int dim)
Returns true if point is inside the ellipsoid.
double distanceBetweenSegments(const std::pair< util::Point, util::Point > &line_1, const std::pair< util::Point, util::Point > &line_2)
Compute distance between lines.
bool isPointInsideRectangle(util::Point x, double x_min, double x_max, double y_min, double y_max)
Checks if point is inside a rectangle.
std::pair< util::Point, util::Point > toPointBox(const std::vector< double > &p1, const std::vector< double > &p2)
Create box from two coordinate data.
bool doLinesIntersect(const std::pair< util::Point, util::Point > &line_1, const std::pair< util::Point, util::Point > &line_2)
Do lines intersect.
bool isPointInsideBox(util::Point x, size_t dim, const std::pair< util::Point, util::Point > &box)
Returns true if point is inside box.
bool isPointInsideAngledRectangle(util::Point x, double x1, double x2, double y1, double y2, double theta)
Checks if point is inside an angled rectangle.
double circumscribedRadiusInBox(size_t dim, const std::pair< util::Point, util::Point > &box)
Computes the radius of smallest circle/sphere which can have the box inside.
double distanceBetweenPlanes(const std::pair< util::Point, util::Point > &plane_1, const std::pair< util::Point, util::Point > &plane_2)
Compute distance between planes.
bool isPointInsideCylinder(const util::Point &p, const double &length, const double &radius, const util::Point &axis)
Returns true if point is inside the cylinder.
std::vector< std::pair< util::Point, util::Point > > getEdges(size_t dim, const std::pair< util::Point, util::Point > &box)
Returns all corner points in the box.
bool areBoxesNear(const std::pair< util::Point, util::Point > &b1, const std::pair< util::Point, util::Point > &b2, const double &tol, size_t dim)
Checks if given two boxes are within given distance from each other.
util::Point getPointOnLine(const util::Point &p1, const util::Point &p2, const double &s)
Returns point in line formed by points p1 and p2.
std::vector< util::Point > getCornerPoints(size_t dim, const std::pair< util::Point, util::Point > &box)
Returns all corner points in the box.
double triangleArea(const util::Point &x1, const util::Point &x2, const util::Point &x3)
Compute area of triangle.
double pointDistanceLine(const util::Point &p, const std::pair< util::Point, util::Point > &line)
Compute distance between point and line.
double computeMeshSize(const std::vector< util::Point > &nodes)
Computes minimum distance between any two nodes.
void ellipsoidRotationMatrix(const Ellipsoid &e, double R[9])
Row-major 3×3 rotation from ellipsoid axis–angle (identity if ).
void computeNonlocalNeighborhood(const std::vector< util::Point > &nodes, double horizon, std::vector< std::vector< size_t > > &nodeNeighs)
Partitions the nodes based on node neighborlist supplied. Function first creates a graph with nodes a...
double inscribedRadiusInBox(size_t dim, const std::pair< util::Point, util::Point > &box)
Computes the radius of biggest circle/sphere completely within the object.
double distanceBetweenLines(const std::pair< util::Point, util::Point > &line_1, const std::pair< util::Point, util::Point > &line_2)
Compute distance between lines.
double computeInscribedRadius(const std::pair< util::Point, util::Point > &box)
Computes maximum radius of circle/sphere within a given box.
std::pair< util::Point, util::Point > computeBBox(const std::vector< util::Point > &nodes)
Computes bounding box for vector nodes.
bool isPointInsideCuboid(util::Point x, util::Point x_lbb, util::Point x_rtf)
Checks if point is inside a cuboid.
bool isGreater(const double &a, const double &b)
Returns true if a > b.
Definition function.cpp:17
double angle(util::Point a, util::Point b)
Computes angle between two vectors.
bool isLess(const double &a, const double &b)
Returns true if a < b.
Definition function.cpp:22
std::vector< double > rotateCW2D(const std::vector< double > &x, const double &theta)
Rotates a vector in xy-plane in clockwise direction.
A structure to represent 3d vectors.
Definition point.h:30
double d_y
the y coordinate
Definition point.h:36
double d_z
the z coordinate
Definition point.h:39
double length() const
Computes the Euclidean length of the vector.
Definition point.h:124
double lengthSq() const
Computes the Euclidean length of the vector.
Definition point.h:130
double d_x
the x coordinate
Definition point.h:33