You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
the returned distance is different when we pass the witness points, versus setting witness=null.
When we set witness to null, the returned squared distance is 0. When we ask it to compute the witness point, the returned squared distance is 0.00000000000000031080. As we can see, all three points A, B and C have negative y value, hence the point P (origin) cannot have 0 distance to the triangle. ccdVec3PointTriDist2 computes the wrong value when the witness point is not passed in.
Inside the implementation of ccdVec3PointTriDist2, it wants to compute the distance from a point P to a triangle ABC. The way it does that is first to write the projection of point P on the plane coinciding with ABC as Q = A + s * AB + t * AC. In this test example, the point Q is inside the triangle ABC, so we only need to compute |PQ|² as the distance from P to ABC. The implementation takes different cod path to compute |PQ|².
When we ask the code to compute the witness point Q, the code first compute Q as Q = A + s * AB + t * AC, and then compute the squared norm of the vector PQ, as implemented in
When we don't ask the code to compute the witness point Q, the code expands the expression |PQ|² as |PQ|² = |PA + s * AB + t * AC|² = |PA|² + s²|AB|² + t² |AC|² + 2 st AB.dot(AC) + 2s * AB.dot(PA) + 2t * AC.dot(PA), it evaluates the summation of the quantities |PA|², s²|AB|², etc, as in the code
. This summation can cause numerical errors up to epsilon, when some of the quantities (like |PA|²) could be in the order of 1. The summation result end up being inaccurate. Hence although the squared distance should be non-zero, the summation result is 0.
The code path 1 (when computing the witness point Q) is numerically more robust. I think this is a bug as the distance result should be the same, with or without computing the witness point.
The text was updated successfully, but these errors were encountered:
It's probably worth mentioning that this bug is causing a failure in FCL as reported by @wxmerkt in flexible-collision-library/fcl#390 (running in double precision). In double precision distance tolerances are around 10⁻¹⁵ so a distance of 10⁻⁸ is still significant (by 7 orders of magnitude or so!).
I'm pretty sure that has gone untouched for the last year. The best strategy may simply be to create a PR. @hongkai-dai has characterized the problem well and a code change and unit test should be pretty straightforward.
In ccdVec3PointTriDist2
libccd/src/ccd/vec3.h
Lines 193 to 202 in 7931e76
the returned distance is different when we pass the witness points, versus setting
witness=null
.When we set
witness
to null, the returned squared distance is 0. When we ask it to compute the witness point, the returned squared distance is 0.00000000000000031080. As we can see, all three pointsA
,B
andC
have negativey
value, hence the point P (origin) cannot have 0 distance to the triangle.ccdVec3PointTriDist2
computes the wrong value when the witness point is not passed in.Inside the implementation of
ccdVec3PointTriDist2
, it wants to compute the distance from a pointP
to a triangleABC
. The way it does that is first to write the projection of pointP
on the plane coinciding withABC
asQ = A + s * AB + t * AC
. In this test example, the pointQ
is inside the triangleABC
, so we only need to compute |PQ|² as the distance fromP
toABC
. The implementation takes different cod path to compute|PQ|²
.Q
, the code first computeQ
asQ = A + s * AB + t * AC
, and then compute the squared norm of the vectorPQ
, as implemented inlibccd/src/vec3.c
Lines 182 to 189 in 7931e76
Q
, the code expands the expression |PQ|² as|PQ|² = |PA + s * AB + t * AC|² = |PA|² + s²|AB|² + t² |AC|² + 2 st AB.dot(AC) + 2s * AB.dot(PA) + 2t * AC.dot(PA)
, it evaluates the summation of the quantities|PA|²
,s²|AB|²
, etc, as in the codelibccd/src/vec3.c
Lines 190 to 197 in 7931e76
The code path 1 (when computing the witness point
Q
) is numerically more robust. I think this is a bug as the distance result should be the same, with or without computing the witness point.The text was updated successfully, but these errors were encountered: