26 size_t dim,
const std::pair<util::Point, util::Point> &box) {
29 return {box.first, box.second};
36 double a = box.second.
d_x - box.first.d_x;
37 double b = box.second.d_y - box.first.d_y;
38 double c = box.second.d_z - box.first.d_z;
49 std::cerr <<
"Error: Check dimension = " << dim <<
".\n";
54std::vector<std::pair<util::Point, util::Point>>
getEdges(
size_t dim,
const
55std::pair<util::Point, util::Point> &box) {
57 std::vector<std::pair<util::Point, util::Point>>
data;
59 data.emplace_back(box);
61 }
else if (dim == 2) {
66 data.emplace_back(corner_pts[0], corner_pts[1]);
67 data.emplace_back(corner_pts[1], corner_pts[2]);
68 data.emplace_back(corner_pts[2], corner_pts[3]);
69 data.emplace_back(corner_pts[3], corner_pts[0]);
71 }
else if (dim == 3) {
78 data.emplace_back(corner_pts[0], corner_pts[1]);
79 data.emplace_back(corner_pts[1], corner_pts[2]);
80 data.emplace_back(corner_pts[2], corner_pts[3]);
81 data.emplace_back(corner_pts[3], corner_pts[0]);
84 data.emplace_back(corner_pts[4], corner_pts[5]);
85 data.emplace_back(corner_pts[5], corner_pts[6]);
86 data.emplace_back(corner_pts[6], corner_pts[7]);
87 data.emplace_back(corner_pts[7], corner_pts[4]);
90 data.emplace_back(corner_pts[0], corner_pts[4]);
91 data.emplace_back(corner_pts[1], corner_pts[5]);
92 data.emplace_back(corner_pts[2], corner_pts[6]);
93 data.emplace_back(corner_pts[3], corner_pts[7]);
97 std::cerr <<
"getEdges(): Function implemented for dim = 1,2,3 only.\n";
103 const std::pair<util::Point, util::Point> &box) {
106 return {0.5 * box.second.
d_x + 0.5 * box.first.d_x, 0., 0.};
108 return {0.5 * box.second.d_x + 0.5 * box.first.d_x,
109 0.5 * box.second.d_y + 0.5 * box.first.d_y, 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,
113 0.5 * box.second.d_z + 0.5 * box.first.d_z};
115 std::cerr <<
"Error: Check dimension = " << dim <<
".\n";
122 const std::pair<util::Point, util::Point> &b2,
137 for (
auto pp : cp2) {
171 const std::pair<util::Point, util::Point> &box) {
189 std::cerr <<
"isPointInsideBox(): Function implemented for dim = 1,2,3 only.\n";
195 const std::pair<util::Point, util::Point> &box) {
197 double r = 0.5 * std::abs(box.second.d_x - box.first.d_x);
201 if (
util::isGreater(r, 0.5 * std::abs(box.second.d_y - box.first.d_y)))
202 return 0.5 * std::abs(box.second.d_y - box.first.d_y);
205 }
else if (dim == 3) {
206 if (
util::isGreater(r, 0.5 * std::abs(box.second.d_y - box.first.d_y)))
207 r = 0.5 * std::abs(box.second.d_y - box.first.d_y);
209 if (
util::isGreater(r, 0.5 * std::abs(box.second.d_z - box.first.d_z)))
210 return 0.5 * std::abs(box.second.d_z - box.first.d_z);
214 std::cerr <<
"inscribedRadiusInBox(): Function implemented for dim = 1,2,3 only.\n";
220 const std::pair<util::Point, util::Point> &box) {
225 auto dx = cp[0] - xc;
226 auto r = dx.length();
243 double x_max,
double y_min,
261 double x2,
double y1,
262 double y2,
double theta) {
310 double p_dot_a = p * axis;
311 if (p_dot_a > length or p_dot_a < 0.)
315 auto p_parallel = p - p_dot_a * axis;
317 return p_parallel.
lengthSq() < radius * radius;
326 double p_dot_a = p_new * a;
329 if (p_dot_a > 1. or p_dot_a < 0.)
333 auto p_parallel = p_new - p_dot_a * a;
335 return p_parallel.
lengthSq() < radius * radius;
340std::vector<double> &radius_vec,
unsigned int dim) {
344 for (
unsigned int i=0; i<dim; i++)
345 d += x[i] * x[i] / (radius_vec[i] * radius_vec[i]);
351std::vector<double> &radius_vec,
unsigned int dim,
double &d) {
355 for (
unsigned int i=0; i<dim; i++)
356 d += x[i] * x[i] / (radius_vec[i] * radius_vec[i]);
364 return (1. - s) * p1 + s * p2;
368 const std::pair<util::Point, util::Point> &line_2) {
375 auto a = line_1.second - line_1.first;
376 auto b = line_2.first - line_1.first;
377 auto c = line_2.second - line_2.first;
380 if (
util::angle(a / a.length(), c / c.length()) < 1.0E-8)
384 double a_dot_b = a * b;
385 double a_dot_c = a * c;
386 double b_dot_c = b * c;
387 double c_dot_c = c.lengthSq();
389 double r = (a_dot_a * b_dot_c - a_dot_b * a_dot_c) /
390 (a_dot_c * a_dot_c - c_dot_c * a_dot_a);
395 return r > 0. and r < 1.;
399 const std::pair<util::Point, util::Point>
407 auto u = line_1.second - line_1.first;
408 auto v = line_2.second - line_2.first;
409 auto w0 = line_1.first - line_2.first;
417 auto dp = w0 + ((b * e - c * d) * u + (a * e - b * d) * v) / (a * c - b * b);
424 const std::pair<util::Point, util::Point> &line_2) {
431 auto u = line_1.second - line_1.first;
432 auto v = line_2.second - line_2.first;
433 auto w0 = line_1.first - line_2.first;
440 double D = a * c - b * b;
441 double sc, sN, sD = D;
442 double tc, tN, tD = D;
460 }
else if (sN > sD) {
479 }
else if (tN > tD) {
493 sc = std::abs(sN) < 1.0E-12 ? 0. : sN / sD;
494 tc = std::abs(tN) < 1.0E-12 ? 0. : tN / tD;
496 auto dp = w0 + sc * u - tc * v;
502 const std::pair<util::Point, util::Point>
506 if (
util::angle(plane_1.first, plane_2.first) < 1.0E-8)
509 return std::abs(plane_1.first * (plane_1.second - plane_2.second)) /
510 plane_1.first.length();
514 const std::pair<util::Point, util::Point> &line) {
517 auto v = line.second - line.first;
520 auto w = p - line.first;
523 auto w_on_line = line.first + (w * v) * v / v.
lengthSq();
525 return (p - w_on_line).length();
529 const std::pair<util::Point, util::Point> &line) {
532 auto v = line.second - line.first;
535 auto w = p - line.first;
538 double w_dot_v = w * v;
539 if (w_dot_v < 1.0E-12)
540 return (p - line.first).
length();
542 if (w_dot_v > v.lengthSq() - 1.0E-12)
543 return (p - line.second).length();
546 auto w_on_line = line.first + w_dot_v * v / v.lengthSq();
548 return (p - w_on_line).length();
552 const std::pair<util::Point, util::Point> &plane) {
558 auto pa = p - plane.second;
559 return std::abs(pa * plane.first) / plane.first.
length();
565 if (nodes.size() < 2)
568 guess = (nodes[0] - nodes[1]).length();
569 for (
size_t i = 0; i < nodes.size(); i++)
570 for (
size_t j = 0; j < nodes.size(); j++)
572 double val = nodes[i].dist(nodes[j]);
576 std::cout <<
"Check nodes are too close = "
577 << util::io::printStr<util::Point>({nodes[i],
580 std::cout <<
"Distance = " << val <<
", guess = " << guess <<
"\n";
593 if (nodes.size() < 2 or (end - start) < 2)
596 guess = (nodes[start] - nodes[start + 1]).length();
597 for (
size_t i = start; i < end; i++)
598 for (
size_t j = start; j < end; j++)
600 double val = nodes[i].dist(nodes[j]);
604 std::cout <<
"Check nodes are too close = "
605 << util::io::printStr<util::Point>({nodes[i],
608 std::cout <<
"Distance = " << val <<
", guess = " << guess <<
"\n";
617std::pair<util::Point, util::Point>
computeBBox(
const std::vector<util::Point> &nodes) {
621 for (
const auto& x : nodes) {
642 return 0.5 * (box.first - box.second).length();
645std::pair<util::Point, util::Point>
toPointBox(
const std::vector<double>
646 &p1,
const std::vector<double>
661 std::vector<std::vector<size_t>> &nodeNeighs) {
662 nodeNeighs.resize(nodes.size());
664 auto nsearch_p = std::make_unique<NSearch>(nodes);
665 double set_tree_time = nsearch_p->updatePointCloud(nodes,
true);
666 set_tree_time += nsearch_p->setInputCloud();
667 std::cout << std::format(
"Tree setup time (ms) = {}. \n", set_tree_time);
669 for (
size_t i=0; i<nodes.size(); i++) {
670 std::vector<size_t> neighs;
671 std::vector<double> sqr_dist;
672 nodeNeighs[i].resize(0);
674 if (nsearch_p->radiusSearch(nodes[i], horizon, neighs, sqr_dist) > 0) {
675 for (std::size_t j = 0; j < neighs.size(); ++j)
676 if (neighs[j] != i) {
677 nodeNeighs[i].push_back(neighs[j]);
685 if (std::abs(e.
d_theta) < 1.0e-15) {
686 R[0] = R[4] = R[8] = 1.;
687 R[1] = R[2] = R[3] = R[5] = R[6] = R[7] = 0.;
694 const double c = std::cos(e.
d_theta);
695 const double s = std::sin(e.
d_theta);
696 const double t = 1.0 - c;
698 R[0] = t * kx * kx + c;
699 R[1] = t * kx * ky - kz * s;
700 R[2] = t * kx * kz + ky * s;
701 R[3] = t * kx * ky + kz * s;
702 R[4] = t * ky * ky + c;
703 R[5] = t * ky * kz - kx * s;
704 R[6] = t * kx * kz - ky * s;
705 R[7] = t * ky * kz + kx * s;
706 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.
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