29#ifndef NAVMAP_CORE__GEOMETRY_HPP
30#define NAVMAP_CORE__GEOMETRY_HPP
33#include <Eigen/Geometry>
45using Vec3 = Eigen::Vector3f;
63 return 0.5f * ((b - a).cross(c - a)).norm();
79 Vec3 n = (b - a).cross(c - a);
81 return len > 1e-12f ? n / len :
Vec3(0.0f, 0.0f, 1.0f);
115 const float kEps = 1e-8f;
118 Vec3 pvec = dir.cross(e2);
119 float det = e1.dot(pvec);
120 if (std::fabs(det) < kEps) {
123 float inv_det = 1.0f / det;
124 Vec3 tvec = orig - v0;
125 u = tvec.dot(pvec) * inv_det;
126 if (u < -kEps || u > 1.0f + kEps) {
129 Vec3 qvec = tvec.cross(e1);
130 v = dir.dot(qvec) * inv_det;
131 if (v < -kEps || (u + v) > 1.0f + kEps) {
134 t = e2.dot(qvec) * inv_det;
156 Vec3 min{std::numeric_limits<float>::infinity(),
157 std::numeric_limits<float>::infinity(),
158 std::numeric_limits<float>::infinity()};
162 Vec3 max{-std::numeric_limits<float>::infinity(),
163 -std::numeric_limits<float>::infinity(),
164 -std::numeric_limits<float>::infinity()};
193 if (d.x() >= d.y() && d.x() >= d.z()) {
return 0;}
194 if (d.y() >= d.x() && d.y() >= d.z()) {
return 1;}
212 float tmax = 1e30f)
const
214 const float kEps = 1e-12f;
215 float tmin_local = 0.0f;
217 for (
int i = 0; i < 3; ++i) {
218 const float di = d[i];
219 const float oi = o[i];
220 const float min_i =
min[i];
221 const float max_i =
max[i];
223 if (std::fabs(di) < kEps) {
225 if (oi < min_i || oi > max_i) {
return false;}
229 float inv = 1.0f / di;
230 float t0 = (min_i - oi) * inv;
231 float t1 = (max_i - oi) * inv;
232 if (t0 > t1) {std::swap(t0, t1);}
234 if (t0 > tmin_local) {tmin_local = t0;}
235 if (t1 < tmax) {tmax = t1;}
237 if (tmax < tmin_local) {
return false;}
239 return tmax >= tmin_local && tmax > 0.0f;
254 return p.x() >=
min.x() && p.x() <=
max.x() &&
255 p.y() >=
min.y() && p.y() <=
max.y() &&
256 p.z() >=
min.z() - z_eps && p.z() <=
max.z() + z_eps;
267 return p.x() >=
min.x() && p.x() <=
max.x() &&
268 p.y() >=
min.y() && p.y() <=
max.y();
294 const Vec3 ab = b - a;
295 const Vec3 ac = c - a;
296 const Vec3 ap = p - a;
298 float d1 = ab.dot(ap);
299 float d2 = ac.dot(ap);
300 if (d1 <= 0.0f && d2 <= 0.0f) {
304 const Vec3 bp = p - b;
305 float d3 = ab.dot(bp);
306 float d4 = ac.dot(bp);
307 if (d3 >= 0.0f && d4 <= d3) {
311 float vc = d1 * d4 - d3 * d2;
312 if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) {
313 float v = d1 / (d1 - d3);
317 const Vec3 cp = p - c;
318 float d5 = ab.dot(cp);
319 float d6 = ac.dot(cp);
320 if (d6 >= 0.0f && d5 <= d6) {
324 float vb = d5 * d2 - d1 * d6;
325 if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) {
326 float w = d2 / (d2 - d6);
330 float va = d3 * d6 - d5 * d4;
331 if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) {
332 float w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
333 return b + w * (c - b);
336 float ab2 = ab.dot(ab);
337 float ac2 = ac.dot(ac);
338 float abac = ab.dot(ac);
339 float denom = (ab2 * ac2 - abac * abac);
340 if (std::fabs(denom) < 1e-20f) {
341 float da = (p - a).squaredNorm();
342 float db = (p - b).squaredNorm();
343 float dc = (p - c).squaredNorm();
344 if (da <= db && da <= dc) {
return a;}
345 if (db <= dc) {
return b;}
348 float v = (ac2 * d1 - abac * d2) / denom;
349 float w = (ab2 * d2 - abac * d1) / denom;
350 return a + v * ab + w * ac;
371 Vec3 * closest =
nullptr)
374 if (closest) {*closest = q;}
375 return (q - p).squaredNorm();
Definition Geometry.hpp:40
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:366
Eigen::Vector3f Vec3
3D vector alias used across NavMap geometry.
Definition Geometry.hpp:45
float triangle_area(const Vec3 &a, const Vec3 &b, const Vec3 &c)
Compute the area of a triangle ABC.
Definition Geometry.hpp:61
Vec3 triangle_normal(const Vec3 &a, const Vec3 &b, const Vec3 &c)
Compute a unit normal of triangle ABC.
Definition Geometry.hpp:77
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:105
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:288
Axis-aligned bounding box.
Definition Geometry.hpp:152
Vec3 max
Maximum corner (x_max, y_max, z_max).
Definition Geometry.hpp:162
bool contains_xy(const Vec3 &p, float z_eps) const
2D containment test on XY with tolerance in Z.
Definition Geometry.hpp:252
Vec3 min
Minimum corner (x_min, y_min, z_min).
Definition Geometry.hpp:156
bool contains_xy_only(const Vec3 &p) const
2D containment test on XY only (no Z check).
Definition Geometry.hpp:265
int longest_axis() const
Return the index of the longest axis (0=x, 1=y, 2=z).
Definition Geometry.hpp:190
void expand(const AABB &b)
Expand the box to include another box b (component-wise union).
Definition Geometry.hpp:180
bool intersects_ray(const Vec3 &o, const Vec3 &d, float tmax=1e30f) const
Robust ray-box intersection (slabs method).
Definition Geometry.hpp:209
void expand(const Vec3 &p)
Expand the box to include a point p.
Definition Geometry.hpp:170