29#ifndef NAVMAP_CORE__GEOMETRY_HPP
30#define NAVMAP_CORE__GEOMETRY_HPP
33#include <Eigen/Geometry>
44using Vec3 = Eigen::Vector3f;
62 return 0.5f * ((b - a).cross(c - a)).norm();
78 Vec3 n = (b - a).cross(c - a);
80 return len > 1e-12f ? n / len :
Vec3(0.0f, 0.0f, 1.0f);
114 const float kEps = 1e-8f;
117 Vec3 pvec = dir.cross(e2);
118 float det = e1.dot(pvec);
119 if (std::fabs(det) < kEps) {
122 float inv_det = 1.0f / det;
123 Vec3 tvec = orig - v0;
124 u = tvec.dot(pvec) * inv_det;
125 if (u < -kEps || u > 1.0f + kEps) {
128 Vec3 qvec = tvec.cross(e1);
129 v = dir.dot(qvec) * inv_det;
130 if (v < -kEps || (u + v) > 1.0f + kEps) {
133 t = e2.dot(qvec) * inv_det;
155 Vec3 min{std::numeric_limits<float>::infinity(),
156 std::numeric_limits<float>::infinity(),
157 std::numeric_limits<float>::infinity()};
161 Vec3 max{-std::numeric_limits<float>::infinity(),
162 -std::numeric_limits<float>::infinity(),
163 -std::numeric_limits<float>::infinity()};
192 if (d.x() >= d.y() && d.x() >= d.z()) {
return 0;}
193 if (d.y() >= d.x() && d.y() >= d.z()) {
return 1;}
211 float tmax = 1e30f)
const
213 const float kEps = 1e-12f;
214 float tmin_local = 0.0f;
216 for (
int i = 0; i < 3; ++i) {
217 const float di = d[i];
218 const float oi = o[i];
219 const float min_i =
min[i];
220 const float max_i =
max[i];
222 if (std::fabs(di) < kEps) {
224 if (oi < min_i || oi > max_i) {
return false;}
228 float inv = 1.0f / di;
229 float t0 = (min_i - oi) * inv;
230 float t1 = (max_i - oi) * inv;
231 if (t0 > t1) {std::swap(t0, t1);}
233 if (t0 > tmin_local) {tmin_local = t0;}
234 if (t1 < tmax) {tmax = t1;}
236 if (tmax < tmin_local) {
return false;}
238 return tmax >= tmin_local && tmax > 0.0f;
253 return p.x() >=
min.x() && p.x() <=
max.x() &&
254 p.y() >=
min.y() && p.y() <=
max.y() &&
255 p.z() >=
min.z() - z_eps && p.z() <=
max.z() + z_eps;
266 return p.x() >=
min.x() && p.x() <=
max.x() &&
267 p.y() >=
min.y() && p.y() <=
max.y();
293 const Vec3 ab = b - a;
294 const Vec3 ac = c - a;
295 const Vec3 ap = p - a;
297 float d1 = ab.dot(ap);
298 float d2 = ac.dot(ap);
299 if (d1 <= 0.0f && d2 <= 0.0f) {
303 const Vec3 bp = p - b;
304 float d3 = ab.dot(bp);
305 float d4 = ac.dot(bp);
306 if (d3 >= 0.0f && d4 <= d3) {
310 float vc = d1 * d4 - d3 * d2;
311 if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) {
312 float v = d1 / (d1 - d3);
316 const Vec3 cp = p - c;
317 float d5 = ab.dot(cp);
318 float d6 = ac.dot(cp);
319 if (d6 >= 0.0f && d5 <= d6) {
323 float vb = d5 * d2 - d1 * d6;
324 if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) {
325 float w = d2 / (d2 - d6);
329 float va = d3 * d6 - d5 * d4;
330 if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) {
331 float w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
332 return b + w * (c - b);
335 float ab2 = ab.dot(ab);
336 float ac2 = ac.dot(ac);
337 float abac = ab.dot(ac);
338 float denom = (ab2 * ac2 - abac * abac);
339 if (std::fabs(denom) < 1e-20f) {
340 float da = (p - a).squaredNorm();
341 float db = (p - b).squaredNorm();
342 float dc = (p - c).squaredNorm();
343 if (da <= db && da <= dc) {
return a;}
344 if (db <= dc) {
return b;}
347 float v = (ac2 * d1 - abac * d2) / denom;
348 float w = (ab2 * d2 - abac * d1) / denom;
349 return a + v * ab + w * ac;
370 Vec3 * closest =
nullptr)
373 if (closest) {*closest = q;}
374 return (q - p).squaredNorm();
Definition Geometry.hpp:39
float point_triangle_squared_distance(const Vec3 &p, const Vec3 &a, const Vec3 &b, const Vec3 &c, Vec3 *closest=nullptr)
Squared distance between point and triangle, with optional closest pt.
Definition Geometry.hpp:365
Eigen::Vector3f Vec3
3D vector alias used across NavMap geometry.
Definition Geometry.hpp:44
float triangle_area(const Vec3 &a, const Vec3 &b, const Vec3 &c)
Compute the area of a triangle ABC.
Definition Geometry.hpp:60
Vec3 triangle_normal(const Vec3 &a, const Vec3 &b, const Vec3 &c)
Compute a unit normal of triangle ABC.
Definition Geometry.hpp:76
bool ray_triangle_intersect(const Vec3 &orig, const Vec3 &dir, const Vec3 &v0, const Vec3 &v1, const Vec3 &v2, float &t, float &u, float &v)
Möller–Trumbore ray–triangle intersection.
Definition Geometry.hpp:104
Vec3 closest_point_on_triangle(const Vec3 &p, const Vec3 &a, const Vec3 &b, const Vec3 &c)
Compute the closest point on triangle ABC to point P.
Definition Geometry.hpp:287
Axis-aligned bounding box.
Definition Geometry.hpp:151
Vec3 max
Maximum corner (x_max, y_max, z_max).
Definition Geometry.hpp:161
bool contains_xy(const Vec3 &p, float z_eps) const
2D containment test on XY with tolerance in Z.
Definition Geometry.hpp:251
Vec3 min
Minimum corner (x_min, y_min, z_min).
Definition Geometry.hpp:155
bool contains_xy_only(const Vec3 &p) const
2D containment test on XY only (no Z check).
Definition Geometry.hpp:264
int longest_axis() const
Return the index of the longest axis (0=x, 1=y, 2=z).
Definition Geometry.hpp:189
void expand(const AABB &b)
Expand the box to include another box b (component-wise union).
Definition Geometry.hpp:179
bool intersects_ray(const Vec3 &o, const Vec3 &d, float tmax=1e30f) const
Robust ray-box intersection (slabs method).
Definition Geometry.hpp:208
void expand(const Vec3 &p)
Expand the box to include a point p.
Definition Geometry.hpp:169