99// • return true if the initial distance is less than the minimum distance
1010// • add an explicit tmax parameter rather than relying on the initial value of
1111// toi
12+ // • add a maximum number of iterations to limit the computation time
1213//
1314// NOTE: These methods are provided for reference comparison with [Li et al.
1415// 2021] and is not utilized by the high-level functionality. In compairson to
@@ -60,8 +61,10 @@ namespace {
6061 }
6162} // namespace
6263
63- AdditiveCCD::AdditiveCCD (const double _conservative_rescaling)
64- : conservative_rescaling(_conservative_rescaling)
64+ AdditiveCCD::AdditiveCCD (
65+ const long _max_iterations, const double _conservative_rescaling)
66+ : max_iterations(_max_iterations)
67+ , conservative_rescaling(_conservative_rescaling)
6568{
6669}
6770
@@ -72,8 +75,7 @@ bool AdditiveCCD::additive_ccd(
7275 const double max_disp_mag,
7376 double& toi,
7477 const double min_distance,
75- const double tmax,
76- const double conservative_rescaling)
78+ const double tmax) const
7779{
7880 assert (conservative_rescaling > 0 && conservative_rescaling <= 1 );
7981
@@ -87,9 +89,14 @@ bool AdditiveCCD::additive_ccd(
8789 assert (d_func > 0 );
8890 const double gap = // (d - ξ) = (d² - ξ²) / (d + ξ)
8991 (1 - conservative_rescaling) * d_func / (d + min_distance);
92+ if (gap < std::numeric_limits<double >::epsilon ()) {
93+ logger ().warn (
94+ " Small gap {:g} ≤ ε in Additive CCD can lead to missed collisions" ,
95+ gap);
96+ }
9097
9198 toi = 0 ;
92- while ( true ) {
99+ for ( long i = 0 ; max_iterations < 0 || i < max_iterations; ++i ) {
93100 // tₗ = η ⋅ (d - ξ) / lₚ = η ⋅ (d² - ξ²) / (lₚ ⋅ (d + ξ))
94101 const double toi_lower_bound = conservative_rescaling * d_func
95102 / ((d + min_distance) * max_disp_mag);
@@ -108,6 +115,12 @@ bool AdditiveCCD::additive_ccd(
108115 if (toi > tmax) {
109116 return false ; // collision occurs after tmax
110117 }
118+
119+ if (max_iterations < 0 && i == DEFAULT_MAX_ITERATIONS) {
120+ logger ().warn (
121+ " Slow convergence in Additive CCD. Perhaps the gap is too small (gap={:g})?" ,
122+ gap);
123+ }
111124 }
112125
113126 return true ;
@@ -151,8 +164,7 @@ bool AdditiveCCD::point_point_ccd(
151164 const VectorMax12d dx = stack (dp0, dp1);
152165
153166 return additive_ccd (
154- x, dx, distance_squared, max_disp_mag, toi, min_distance, tmax,
155- conservative_rescaling);
167+ x, dx, distance_squared, max_disp_mag, toi, min_distance, tmax);
156168}
157169
158170bool AdditiveCCD::point_edge_ccd (
@@ -199,8 +211,7 @@ bool AdditiveCCD::point_edge_ccd(
199211 const VectorMax12d dx = stack (dp, de0, de1);
200212
201213 return additive_ccd (
202- x, dx, distance_squared, max_disp_mag, toi, min_distance, tmax,
203- conservative_rescaling);
214+ x, dx, distance_squared, max_disp_mag, toi, min_distance, tmax);
204215}
205216
206217bool AdditiveCCD::point_triangle_ccd (
@@ -248,8 +259,7 @@ bool AdditiveCCD::point_triangle_ccd(
248259 const VectorMax12d dx = stack (dp, dt0, dt1, dt2);
249260
250261 return additive_ccd (
251- x, dx, distance_squared, max_disp_mag, toi, min_distance, tmax,
252- conservative_rescaling);
262+ x, dx, distance_squared, max_disp_mag, toi, min_distance, tmax);
253263}
254264
255265bool AdditiveCCD::edge_edge_ccd (
@@ -310,8 +320,7 @@ bool AdditiveCCD::edge_edge_ccd(
310320 const VectorMax12d dx = stack (dea0, dea1, deb0, deb1);
311321
312322 return additive_ccd (
313- x, dx, distance_squared, max_disp_mag, toi, min_distance, tmax,
314- conservative_rescaling);
323+ x, dx, distance_squared, max_disp_mag, toi, min_distance, tmax);
315324}
316325
317326} // namespace ipc
0 commit comments