23 const Point
zero(0.0, 0.0, 0.0);
24 return pt.absolute_fuzzy_equals(
zero);
38 const std::vector<Point> & candidates,
39 const unsigned int axis)
44 for (
const auto & c : candidates)
47 const Real dy = c(
idx.second) - pt(
idx.second);
56 projectPoint(
const Real x0,
const Real x1,
const unsigned int axis)
77 return (pt1(i.first) - pt3(i.first)) * (pt2(i.second) - pt3(i.second)) -
78 (pt2(i.first) - pt3(i.first)) * (pt1(i.second) - pt3(i.second));
84 const auto n_pts = corners.size();
86 std::vector<bool> negative_half_space;
87 std::vector<bool> positive_half_space;
90 const int next = (i == n_pts - 1) ? 0 : i + 1;
92 negative_half_space.push_back(half < 0);
93 positive_half_space.push_back(half > 0);
96 const bool negative =
std::find(negative_half_space.begin(), negative_half_space.end(),
true) !=
97 negative_half_space.end();
98 const bool positive =
std::find(positive_half_space.begin(), positive_half_space.end(),
true) !=
99 positive_half_space.end();
101 const bool in_polygon = !(negative && positive);
112 pointOnEdge(
const Point &
point,
const std::vector<Point> & corners,
const unsigned int axis)
114 const auto n_pts = corners.size();
117 constexpr
Real tol = 1e-8;
120 const int next = (i == n_pts - 1) ? 0 : i + 1;
121 const auto & pt1 = corners[i];
122 const auto & pt2 = corners[next];
137 if (close_to_line && between_points)
144 std::pair<unsigned int, unsigned int>
147 std::pair<unsigned int, unsigned int> indices;
177 const Real dx = pt2(i.first) - pt1(i.first);
178 const Real dy = pt2(i.second) - pt1(i.second);
181 const Point gap_line = pt2 - pt1;
183 const auto cross_product = gap_line.cross(normal);
185 if (cross_product(axis) > 0)
186 return normal.unit();
194 const Point a = pt - line0;
195 const Point b = pt - line1;
196 const Point c = line1 - line0;
198 return (a.cross(b).norm()) / c.norm();
213 polygonCorners(
const unsigned int num_sides,
const Real radius,
const unsigned int axis)
215 std::vector<Point> corners;
216 const Real theta = 2.0 * M_PI / num_sides;
217 const Real first_angle = M_PI / 2.0 - theta / 2.0;
221 const Real angle = first_angle + i * theta;
234 const Real cos_theta =
cos(angle);
235 const Real sin_theta =
sin(angle);
238 const Real xy = axis(0) * axis(1);
239 const Real xz = axis(0) * axis(2);
240 const Real yz = axis(1) * axis(2);
242 const Point x_op(cos_theta + axis(0) * axis(0) * (1.0 - cos_theta),
243 xy * (1.0 - cos_theta) - axis(2) * sin_theta,
244 xz * (1.0 - cos_theta) + axis(1) * sin_theta);
246 const Point y_op(xy * (1.0 - cos_theta) + axis(2) * sin_theta,
247 cos_theta + axis(1) * axis(1) * (1.0 - cos_theta),
248 yz * (1.0 - cos_theta) - axis(0) * sin_theta);
250 const Point z_op(xz * (1.0 - cos_theta) - axis(1) * sin_theta,
251 yz * (1.0 - cos_theta) + axis(0) * sin_theta,
252 cos_theta + axis(2) * axis(2) * (1.0 - cos_theta));
263 Point diff = (box.
max() - box.
min()) / 2.0;
264 const Point origin = box.
min() + diff;
270 const Point dx(2.0 * diff(0), 0.0, 0.0);
271 const Point dy(0.0, 2.0 * diff(1), 0.0);
272 const Point dz(0.0, 0.0, 2.0 * diff(2));
274 std::vector<Point> verts(8, origin - diff);
275 const unsigned int pts_per_dim = 2;
279 verts[pts_per_dim * pts_per_dim * z + pts_per_dim * y + x] += x * dx + y * dy + z * dz;
287 const Point v1 = p2 - p1;
288 const Point v2 = p3 - p1;
289 const Point cross_prod = v1.cross(v2);
291 return MooseUtils::absoluteFuzzyEqual(cross_prod.norm(), 0.0);
298 MooseUtils::absoluteFuzzyEqual(p1(2), 0.0) && MooseUtils::absoluteFuzzyEqual(p2(2), 0.0) &&
299 MooseUtils::absoluteFuzzyEqual(p3(2), 0.0) && MooseUtils::absoluteFuzzyEqual(p4(2), 0.0),
300 "segmentsIntersect only works in 2D (x-y plane)");
302 mooseAssert(MooseUtils::absoluteFuzzyGreaterThan((p1 - p2).
norm(), 0.0) &&
303 MooseUtils::absoluteFuzzyGreaterThan((p3 - p4).
norm(), 0.0),
304 "Zero length segments are not allowed in segmentsIntersect");
306 const Real a1 = p2(1) - p1(1);
307 const Real b1 = p1(0) - p2(0);
308 const Real c1 = p2(0) * p1(1) - p1(0) * p2(1);
310 const Real a2 = p4(1) - p3(1);
311 const Real b2 = p3(0) - p4(0);
312 const Real c2 = p4(0) * p3(1) - p3(0) * p4(1);
314 const Real denom = a1 * b2 - a2 * b1;
315 Point intersection_pt;
317 if (MooseUtils::absoluteFuzzyEqual(denom, 0.0))
324 const Point p12 = (p1 + p2) / 2.0;
325 const Point p34 = (p3 + p4) / 2.0;
326 const Real dist12 = (p1 - p2).
norm();
327 const Real dist34 = (p3 - p4).
norm();
328 intersection_pt = p12 + (p34 - p12) * (dist12 / (dist12 + dist34));
335 intersection_pt = Point((b1 * c2 - b2 * c1) / denom, (a2 * c1 - a1 * c2) / denom, 0.0);
338 const Real ratio_p1p2 = (intersection_pt - p1) * (p2 - p1) / ((p2 - p1).
norm_sq());
339 const Real ratio_p3p4 = (intersection_pt - p3) * (p4 - p3) / ((p4 - p3).
norm_sq());
341 if (MooseUtils::absoluteFuzzyGreaterEqual(ratio_p1p2, 0.0) &&
342 MooseUtils::absoluteFuzzyLessEqual(ratio_p1p2, 1.0) &&
343 MooseUtils::absoluteFuzzyGreaterEqual(ratio_p3p4, 0.0) &&
344 MooseUtils::absoluteFuzzyLessEqual(ratio_p3p4, 1.0))
353 const Point ab = b - a;
354 const auto length_sq = ab.norm_sq();
355 if (length_sq <= std::numeric_limits<Real>::epsilon())
356 return (
point - a).norm_sq();
359 const Point projection = a + t * ab;
360 return (
point - projection).norm_sq();
366 const Point ab = v1 - v0;
367 const Point ac = v2 - v0;
368 const Point ap =
point - v0;
369 const Real d1 = ab * ap;
370 const Real d2 = ac * ap;
371 if (d1 <= 0.0 && d2 <= 0.0)
372 return (
point - v0).norm_sq();
374 const Point bp =
point - v1;
375 const Real d3 = ab * bp;
376 const Real d4 = ac * bp;
377 if (d3 >= 0.0 && d4 <= d3)
378 return (
point - v1).norm_sq();
380 const Real vc = d1 * d4 - d3 * d2;
381 if (vc <= 0.0 && d1 >= 0.0 && d3 <= 0.0)
383 const Real v = d1 / (d1 - d3);
384 const Point projection = v0 + v * ab;
385 return (
point - projection).norm_sq();
388 const Point cp =
point - v2;
389 const Real d5 = ab * cp;
390 const Real d6 = ac * cp;
391 if (d6 >= 0.0 && d5 <= d6)
392 return (
point - v2).norm_sq();
394 const Real vb = d5 * d2 - d1 * d6;
395 if (vb <= 0.0 && d2 >= 0.0 && d6 <= 0.0)
397 const Real w = d2 / (d2 - d6);
398 const Point projection = v0 + w * ac;
399 return (
point - projection).norm_sq();
402 const Real va = d3 * d6 - d5 * d4;
403 if (va <= 0.0 && (d4 - d3) >= 0.0 && (d5 - d6) >= 0.0)
405 const Point bc = v2 - v1;
406 const Real w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
407 const Point projection = v1 + w * bc;
408 return (
point - projection).norm_sq();
411 const Real denom = 1.0 / (va + vb + vc);
412 const Real v = vb * denom;
413 const Real w = vc * denom;
414 const Point projection = v0 + ab * v + ac * w;
415 return (
point - projection).norm_sq();
421 const Point a = v0 -
point;
422 const Point b = v1 -
point;
423 const Point c = v2 -
point;
425 const Real la = a.norm();
426 const Real lb = b.norm();
427 const Real lc = c.norm();
429 const Real numerator = a * (b.cross(c));
430 const Real denominator = la * lb * lc + (a * b) * lc + (b * c) * la + (c * a) * lb;
432 return 2.0 * std::atan2(numerator, denominator);
std::string name(const ElemQuality q)
Real pointTriangleDistanceSq(const Point &point, const Point &v0, const Point &v1, const Point &v2)
Compute the squared distance from a point to a 3-D triangle.
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sin(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tan
libMesh::Point projectPoint(const libMesh::Real x0, const libMesh::Real x1, const unsigned int axis)
Given two coordinates, construct a point in the 2-D plane perpendicular to the specified axis...
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
libMesh::Real projectedDistanceFromLine(libMesh::Point pt, libMesh::Point line0, libMesh::Point line1, const unsigned int axis)
Compute the distance from a 3-D line, provided in terms of two points on the line.
Real solidAngle(const Point &point, const Point &v0, const Point &v1, const Point &v2)
Compute the signed solid angle subtended by one oriented triangle at the query point.
libMesh::Real projectedLineHalfSpace(libMesh::Point pt1, libMesh::Point pt2, libMesh::Point pt3, const unsigned int axis)
If positive, point is on the positive side of the half space (and vice versa).
libMesh::Point projectedUnitNormal(libMesh::Point pt1, libMesh::Point pt2, const unsigned int axis)
Get the unit normal vector between two points (which are first projected onto the plane perpendicular...
libMesh::Point rotatePointAboutAxis(const libMesh::Point &p, const libMesh::Real angle, const libMesh::Point &axis)
Rotate point about an axis.
std::vector< libMesh::Point > polygonCorners(const unsigned int num_sides, const libMesh::Real radius, const unsigned int axis)
Get the corner coordinates of a regular 2-D polygon, assuming a face of the polygon is parallel to th...
Real distance(const Point &p)
auto max(const L &left, const R &right)
TypeVector< Real > unit() const
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template cos(_arg) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(cos
bool pointOnEdge(const libMesh::Point &point, const std::vector< libMesh::Point > &corners, const unsigned int axis)
Whether a point is on the edge of a 2-D polygon in the plane perpendicular to the specified axis...
const Point & min() const
libMesh::Point unitVector(const libMesh::Point &pt, const std::string &name)
Get the unit vector for a point parameter.
bool isPointZero(const libMesh::Point &pt)
Check whether a point is equal to zero.
std::pair< unsigned int, unsigned int > projectedIndices(const unsigned int axis)
Get the indices of the plane perpendicular to the specified axis.
bool segmentsIntersect(const Point &p1, const Point &p2, const Point &p3, const Point &p4)
Check if the line segment p1-p2 intersects with line segment p3-p4 (only working in 2D (x-y plane))...
libMesh::Real distanceFromLine(const libMesh::Point &pt, const libMesh::Point &line0, const libMesh::Point &line1)
Compute the distance from a 3-D line, provided in terms of two points on the line.
libMesh::Real minDistanceToPoints(const libMesh::Point &pt, const std::vector< libMesh::Point > &candidates, const unsigned int axis)
Get the minimum distance from a point to another set of points, in the plane perpendicular to the spe...
std::vector< libMesh::Point > boxCorners(const libMesh::BoundingBox &box, const libMesh::Real factor)
Get corner points of a bounding box, with side length re-scaled.
Real pointSegmentDistanceSq(const Point &point, const Point &a, const Point &b)
Compute the squared distance from a point to a 3-D line segment.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool pointInPolygon(const libMesh::Point &point, const std::vector< libMesh::Point > &corners, const unsigned int axis)
Whether a point is in 2-D a polygon in the plane perpendicular to the specified axis, given by corner points.
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
IntRange< T > make_range(T beg, T end)
bool arePointsColinear(const Point &p1, const Point &p2, const Point &p3)
Check if three points are colinear.
T clamp(const T &x, T2 lowerlimit, T2 upperlimit)
const Point & max() const
auto min(const L &left, const R &right)
auto index_range(const T &sizable)