27 size_t dim,
const std::pair<util::Point, util::Point> &box) {
30 return {box.first, box.second};
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;
50 throw std::invalid_argument(
52 <<
"Error: Check dimension = " << dim <<
".\n");
56std::vector<std::pair<util::Point, util::Point>>
getEdges(
size_t dim,
const
57std::pair<util::Point, util::Point> &box) {
59 std::vector<std::pair<util::Point, util::Point>>
data;
61 data.emplace_back(box);
63 }
else if (dim == 2) {
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]);
73 }
else if (dim == 3) {
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]);
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]);
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]);
99 throw std::invalid_argument(
101 <<
"getEdges(): Function implemented for dim = 1,2,3 only.\n");
106 const std::pair<util::Point, util::Point> &box) {
109 return {0.5 * box.second.
d_x + 0.5 * box.first.d_x, 0., 0.};
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.};
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};
118 throw std::invalid_argument(
120 <<
"Error: Check dimension = " << dim <<
".\n");
126 const std::pair<util::Point, util::Point> &b2,
141 for (
auto pp : cp2) {
175 const std::pair<util::Point, util::Point> &box) {
193 throw std::invalid_argument(
195 <<
"isPointInsideBox(): Function implemented for dim = 1,2,3 only.\n");
200 const std::pair<util::Point, util::Point> &box) {
202 double r = 0.5 * std::abs(box.second.d_x - box.first.d_x);
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);
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);
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);
219 throw std::invalid_argument(
221 <<
"inscribedRadiusInBox(): Function implemented for dim = 1,2,3 only.\n");
226 const std::pair<util::Point, util::Point> &box) {
231 auto dx = cp[0] - xc;
232 auto r = dx.length();
249 double x_max,
double y_min,
267 double x2,
double y1,
268 double y2,
double theta) {
316 double p_dot_a = p * axis;
317 if (p_dot_a > length or p_dot_a < 0.)
321 auto p_parallel = p - p_dot_a * axis;
323 return p_parallel.
lengthSq() < radius * radius;
332 double p_dot_a = p_new * a;
335 if (p_dot_a > 1. or p_dot_a < 0.)
339 auto p_parallel = p_new - p_dot_a * a;
341 return p_parallel.
lengthSq() < radius * radius;
346std::vector<double> &radius_vec,
unsigned int dim) {
350 for (
unsigned int i=0; i<dim; i++)
351 d += x[i] * x[i] / (radius_vec[i] * radius_vec[i]);
357std::vector<double> &radius_vec,
unsigned int dim,
double &d) {
361 for (
unsigned int i=0; i<dim; i++)
362 d += x[i] * x[i] / (radius_vec[i] * radius_vec[i]);
370 return (1. - s) * p1 + s * p2;
374 const std::pair<util::Point, util::Point> &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;
386 if (
util::angle(a / a.length(), c / c.length()) < 1.0E-8)
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();
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);
401 return r > 0. and r < 1.;
405 const std::pair<util::Point, util::Point>
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;
423 auto dp = w0 + ((b * e - c * d) * u + (a * e - b * d) * v) / (a * c - b * b);
430 const std::pair<util::Point, util::Point> &line_2) {
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;
446 double D = a * c - b * b;
447 double sc, sN, sD = D;
448 double tc, tN, tD = D;
466 }
else if (sN > sD) {
485 }
else if (tN > tD) {
499 sc = std::abs(sN) < 1.0E-12 ? 0. : sN / sD;
500 tc = std::abs(tN) < 1.0E-12 ? 0. : tN / tD;
502 auto dp = w0 + sc * u - tc * v;
508 const std::pair<util::Point, util::Point>
512 if (
util::angle(plane_1.first, plane_2.first) < 1.0E-8)
515 return std::abs(plane_1.first * (plane_1.second - plane_2.second)) /
516 plane_1.first.length();
520 const std::pair<util::Point, util::Point> &line) {
523 auto v = line.second - line.first;
526 auto w = p - line.first;
529 auto w_on_line = line.first + (w * v) * v / v.
lengthSq();
531 return (p - w_on_line).length();
535 const std::pair<util::Point, util::Point> &line) {
538 auto v = line.second - line.first;
541 auto w = p - line.first;
544 double w_dot_v = w * v;
545 if (w_dot_v < 1.0E-12)
546 return (p - line.first).
length();
548 if (w_dot_v > v.lengthSq() - 1.0E-12)
549 return (p - line.second).length();
552 auto w_on_line = line.first + w_dot_v * v / v.lengthSq();
554 return (p - w_on_line).length();
558 const std::pair<util::Point, util::Point> &plane) {
564 auto pa = p - plane.second;
565 return std::abs(pa * plane.first) / plane.first.
length();
571 if (nodes.size() < 2)
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++)
578 double val = nodes[i].dist(nodes[j]);
582 std::cout <<
"Check nodes are too close = "
583 << util::io::printStr<util::Point>({nodes[i],
586 std::cout <<
"Distance = " << val <<
", guess = " << guess <<
"\n";
599 if (nodes.size() < 2 or (end - start) < 2)
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++)
606 double val = nodes[i].dist(nodes[j]);
610 std::cout <<
"Check nodes are too close = "
611 << util::io::printStr<util::Point>({nodes[i],
614 std::cout <<
"Distance = " << val <<
", guess = " << guess <<
"\n";
623std::pair<util::Point, util::Point>
computeBBox(
const std::vector<util::Point> &nodes) {
627 for (
const auto& x : nodes) {
648 return 0.5 * (box.first - box.second).length();
651std::pair<util::Point, util::Point>
toPointBox(
const std::vector<double>
652 &p1,
const std::vector<double>
667 std::vector<std::vector<size_t>> &nodeNeighs) {
668 nodeNeighs.resize(nodes.size());
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);
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);
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]);
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.;
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;
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;
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.
Collects a message with stream syntax for use in an exception.
nsearch::NFlannSearchKd< 3 > NSearch
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 ¢er, 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.
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.
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.
double d_y
the y coordinate
double d_z
the z coordinate
double length() const
Computes the Euclidean length of the vector.
double lengthSq() const
Computes the Euclidean length of the vector.
double d_x
the x coordinate