From f223374831123e4aa31fb2f7997ce1c5e97f4327 Mon Sep 17 00:00:00 2001 From: Hongkai Dai Date: Fri, 28 Feb 2025 10:08:18 -0800 Subject: [PATCH] Use relative ratio less than epsilon to check zero. In ccdVec3PointTriDist2, instead of checking if the triangle area is less than epsilon, we use the ratio (which measures the sine angle) less than epsilon to determine if the triangle area can be used as a denominator. This avoids the problem when CCD incorrectly doesn't trust the projection onto the interior of the triangle, and instead project to the edges of the triangle, causing bad witness point. --- src/vec3.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/vec3.c b/src/vec3.c index 003c946..854a00d 100644 --- a/src/vec3.c +++ b/src/vec3.c @@ -165,9 +165,12 @@ ccd_real_t ccdVec3PointTriDist2(const ccd_vec3_t *P, r = ccdVec3Dot(&d1, &d2); d = w * v - r * r; - if (ccdIsZero(d)){ - // To avoid division by zero for zero (or near zero) area triangles - s = t = -1.; + if (ccdIsZero(d / (w * v))){ + // To avoid division by zero for zero (or near zero) area triangles. The + // numerical error can be caused by subtracting two large numbers, and the + // ratio (d/ (w * v) in this case) between their difference to one of the + // large number is smaller than numerical epsilon. + s = t = -1.; }else{ s = (q * r - w * p) / d; t = (-s * r - q) / w;