40 #ifndef GEOGRAM_BASIC_GEOMETRY_ND
41 #define GEOGRAM_BASIC_GEOMETRY_ND
64 template <
class COORD_T>
83 template <
class COORD_T>
101 const VEC& p1,
const VEC& p2
121 const VEC& p1,
const VEC& p2
142 template <
class COORD_T>
152 double s = double(0.5) * (a + b + c);
153 double A2 = s * (s - a) * (s - b) * (s - c);
155 return ::sqrt(std::max(A2, 0.0));
177 template <
class COORD_T>
182 COORD_T a, COORD_T b, COORD_T c,
187 double abc = a + b + c;
189 V = area / 3.0 * abc;
193 double s = area / 12.0;
195 Vg[i] = s * (wp * p[i] + wq * q[i] + wr * r[i]);
213 const VEC& p1,
const VEC& p2,
const VEC& p3
219 double s = double(0.5) * (a + b + c);
220 return ::sqrt(s * (s - a) * (s - b) * (s - c));
238 const VEC& p,
const VEC& q,
const VEC& r,
239 double a,
double b,
double c
250 ::sqrt(::fabs(a)) + sqrt(::fabs(b)) + sqrt(::fabs(c))
266 template <
class POINT>
271 double* denom =
nullptr
273 const POINT q2 = Q2 - Q1;
274 const POINT q3 = Q3 - Q1;
276 double l2 = length2(q2);
277 double l3 = length2(q3);
279 double a12 = -2.0 * dot(q2, q2);
280 double a13 = -2.0 * dot(q3, q2);
281 double a22 = -2.0 * dot(q2, q3);
282 double a23 = -2.0 * dot(q3, q3);
284 double c31 = (a23 * a12 - a22 * a13);
287 double lambda1 = s * ((a23 - a22) * l2 + (a12 - a13) * l3 + c31);
288 double lambda2 = s * ((-a23) * l2 + (a13) * l3);
289 double lambda3 = s * ((a22) * l2 + (-a12) * l3);
290 if(denom !=
nullptr) {
293 return lambda1 * Q1 + lambda2 * Q2 + lambda3 * Q3;
312 const VEC& p,
const VEC& q,
const VEC& r,
313 double a,
double b,
double c,
316 double abc = a + b + c;
318 V = area / 3.0 * abc;
322 double s = area / 12.0;
323 Vg = s * (wp * p + wq * q + wr * r);
339 const VEC& p1,
const VEC& p2,
const VEC& p3
347 double l3 = 1.0 - l1 - l2;
348 return l1 * p1 + l2 * p2 + l3 * p3;
365 const VEC& p1,
const VEC& p2,
const VEC& p3,
const VEC& p4
378 }
else if(s + t + u > 1.0) {
383 double a = 1.0 - s - t - u;
384 return a * p1 + s * p2 + t * p3 + u * p4;
412 double t = dot(point - V0, V1 - V0);
413 if(t <= 0.0 || l2 == 0.0) {
425 lambda0 = 1.0-lambda1;
426 closest_point = lambda0 * V0 + lambda1 * V1;
450 point, V0, V1, closest_point, lambda0, lambda1
481 double& lambda0,
double& lambda1,
double& lambda2
483 VEC diff = V0 - point;
486 double a00 = length2(edge0);
487 double a01 = dot(edge0, edge1);
488 double a11 = length2(edge1);
489 double b0 = dot(diff, edge0);
490 double b1 = dot(diff, edge1);
491 double c = length2(diff);
492 double det = ::fabs(a00 * a11 - a01 * a01);
493 double s = a01 * b1 - a11 * b0;
494 double t = a01 * b0 - a00 * b1;
499 double cur_l1, cur_l2;
504 closest_point = cur_closest;
509 if(cur_dist < result) {
511 closest_point = cur_closest;
517 if(cur_dist < result) {
519 closest_point = cur_closest;
534 sqrDistance = a00 + 2.0 * b0 + c;
537 sqrDistance = b0 * s + c;
544 }
else if(-b1 >= a11) {
546 sqrDistance = a11 + 2.0 * b1 + c;
549 sqrDistance = b1 * t + c;
557 }
else if(-b1 >= a11) {
559 sqrDistance = a11 + 2.0 * b1 + c;
562 sqrDistance = b1 * t + c;
570 }
else if(-b0 >= a00) {
572 sqrDistance = a00 + 2.0 * b0 + c;
575 sqrDistance = b0 * s + c;
579 double invDet = double(1.0) /
det;
582 sqrDistance = s * (a00 * s + a01 * t + 2.0 * b0) +
583 t * (a01 * s + a11 * t + 2.0 * b1) + c;
586 double tmp0, tmp1, numer, denom;
593 denom = a00 - 2.0 * a01 + a11;
597 sqrDistance = a00 + 2.0 * b0 + c;
601 sqrDistance = s * (a00 * s + a01 * t + 2.0 * b0) +
602 t * (a01 * s + a11 * t + 2.0 * b1) + c;
608 sqrDistance = a11 + 2.0 * b1 + c;
615 sqrDistance = b1 * t + c;
623 denom = a00 - 2.0 * a01 + a11;
627 sqrDistance = a11 + 2.0 * b1 + c;
631 sqrDistance = s * (a00 * s + a01 * t + 2.0 * b0) +
632 t * (a01 * s + a11 * t + 2.0 * b1) + c;
638 sqrDistance = a00 + 2.0 * b0 + c;
639 }
else if(b0 >= 0.0) {
644 sqrDistance = b0 * s + c;
648 numer = a11 + b1 - a01 - b0;
652 sqrDistance = a11 + 2.0 * b1 + c;
654 denom = a00 - 2.0 * a01 + a11;
658 sqrDistance = a00 + 2.0 * b0 + c;
662 sqrDistance = s * (a00 * s + a01 * t + 2.0 * b0) +
663 t * (a01 * s + a11 * t + 2.0 * b1) + c;
670 if(sqrDistance < 0.0) {
674 closest_point = V0 + s * edge0 + t * edge1;
675 lambda0 = 1.0 - s - t;
697 const VEC& p,
const VEC& q1,
const VEC& q2,
const VEC& q3
700 double lambda1, lambda2, lambda3;
702 p, q1, q2, q3, closest_point, lambda1, lambda2, lambda3
725 double X = (w - U + v) * (U + v + w);
726 double x = (U - v + w) * (v - w + U);
727 double Y = (u - V + w) * (V + w + u);
728 double y = (V - w + u) * (w - u + V);
729 double Z = (v - W + u) * (W + u + v);
730 double z = (W - u + v) * (u - v + W);
731 double a = ::sqrt(::fabs(x * Y * Z));
732 double b = ::sqrt(::fabs(y * Z * X));
733 double c = ::sqrt(::fabs(z * X * Y));
734 double d = ::sqrt(::fabs(x * y * z));
735 return ::sqrt(::fabs(
740 )) / (192.0 * u * v * w);
758 const VEC& p1,
const VEC& p2,
const VEC& p3,
const VEC& p4
784 const double* p1,
const double* p2,
785 const double* p3,
const double* p4
810 const double* p1,
const double* p2,
811 const double* p3,
const double* p4
814 *
reinterpret_cast<const vec3*
>(p1),
815 *
reinterpret_cast<const vec3*
>(p2),
816 *
reinterpret_cast<const vec3*
>(p3),
817 *
reinterpret_cast<const vec3*
>(p4)
#define geo_debug_assert(x)
Verifies that a condition is met.
Common include file, providing basic definitions. Should be included before anything else by all head...
Geometric functions in 2d and 3d.
Types and functions for memory manipulation.
double point_segment_squared_distance(const VEC &point, const VEC &V0, const VEC &V1, VEC &closest_point, double &lambda0, double &lambda1)
Computes the point closest to a given point in a nd segment.
double distance(const COORD_T *p1, const COORD_T *p2, coord_index_t dim)
Computes the distance between two nd points.
double det(const vec2 &a, const vec2 &b)
Computes the determinant of two vectors.
double tetra_volume< 3 >(const double *p1, const double *p2, const double *p3, const double *p4)
Computes the volume of a 3d tetrahedron.
vec3 random_point_in_triangle(const vec3 &p1, const vec3 &p2, const vec3 &p3)
Generates a random point in a 3d triangle.
double distance2(const COORD_T *p1, const COORD_T *p2, coord_index_t dim)
Computes the squared distance between two nd points.
double tetra_volume(const vec3 &p1, const vec3 &p2, const vec3 &p3, const vec3 &p4)
Computes the volume of a 3d tetrahedron.
double triangle_mass(const vec3 &p, const vec3 &q, const vec3 &r, double a, double b, double c)
Computes the mass of a 3d triangle with weighted points.
double triangle_area(const vec3 &p1, const vec3 &p2, const vec3 &p3)
Computes the area of a 3d triangle.
void triangle_centroid(const vec3 &p, const vec3 &q, const vec3 &r, double a, double b, double c, vec3 &Vg, double &V)
Computes the centroid of a 3d triangle with weighted points.
double tetra_volume_from_edge_lengths(double u, double U, double v, double V, double w, double W)
Computes the volume of a tetrahedron from edge lengths.
double point_triangle_squared_distance(const VEC &point, const VEC &V0, const VEC &V1, const VEC &V2, VEC &closest_point, double &lambda0, double &lambda1, double &lambda2)
Computes the point closest to a given point in a nd triangle.
VEC random_point_in_tetra(const VEC &p1, const VEC &p2, const VEC &p3, const VEC &p4)
Generates a random point in a nd tetrahedron.
vec2 triangle_circumcenter(const vec2 &p1, const vec2 &p2, const vec2 &p3)
Computes the center of the circumscribed circle of a 2d triangle.
float64 random_float64()
Returns a 64 bits float between 0 and 1.
Global Vorpaline namespace.
T geo_sqr(T x)
Gets the square value of a value.
geo_coord_index_t coord_index_t
The type for storing coordinate indices, and iterating on the coordinates of a point.