Skip to content

Commit 8e43202

Browse files
committed
Add gradient magnitude safety check to prevent overshooting in ApplyConstraints
When gradient magnitude is very weak (< 0.5), cap the step size by the distance value to prevent taking unreasonably large steps. This handles pathological cases in smoothed distance fields where weak gradients can cause steps orders of magnitude larger than the distance to the surface and exceed the narrow band.
1 parent b351dea commit 8e43202

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

Libs/Optimize/Domain/ImplicitSurfaceDomain.h

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,23 @@ class ImplicitSurfaceDomain : public ImageDomainWithCurvature<T> {
8181
// Normalize gradient to get direction
8282
vnl_vector_fixed<double, DIMENSION> direction = grad / gradient_magnitude;
8383

84-
// KEY INSIGHT: Use a damped step that accounts for the fact that
85-
// the gradient magnitude may not be 1.0
86-
// For smoothed distance fields, we take a more conservative step
87-
double step_size = double(value) / gradient_magnitude;
88-
89-
// Damping factor to prevent overshooting (especially important for smoothed fields)
90-
const double DAMPING = 0.75;
91-
step_size *= DAMPING;
84+
// For smoothed distance fields:
85+
// - Neither value nor gradient_magnitude are exactly correct
86+
// - But their RATIO is approximately correct (within ~20%)
87+
// - Use damping to handle the residual error
88+
89+
const double DAMPING = 0.7; // Conservative for ~20% overshoot
90+
double step_size = (double(value) / gradient_magnitude) * DAMPING;
91+
92+
// Safety check: if gradient is very weak, cap step by distance value
93+
// This handles pathological cases (critical points, field edges)
94+
if (gradient_magnitude < 0.5) {
95+
double max_step = fabs(double(value)) * DAMPING;
96+
if (fabs(step_size) > max_step) {
97+
step_size = (step_size > 0 ? max_step : -max_step);
98+
}
99+
}
92100

93-
// Update position
94101
for (unsigned int i = 0; i < DIMENSION; i++) {
95102
p[i] -= step_size * direction[i];
96103
}

0 commit comments

Comments
 (0)