Fix: reject invalid inverse lens-map weights

Check spherical area weight sums against a fixed 1e-8 tolerance and normalize accepted weights before interpolation. Skip invalid images in both catalog paths.

Add a thin-triangle regression for both parities, document the measured tolerance margin, and refresh HDR fixtures with strict comparisons restored.
This commit is contained in:
wyj committed 2026-09-06 17:47:09 -04:00
1 parent 8741597d9d
commit 265d7b95d5
6 files changed
+72 -5

No files matched your search

+12 -1
View File
@@ -930,6 +930,17 @@ static int spherical_barycentric_weights(const double point[3], const double a[3
weights[0] = spherical_area(point, b, c) / area;
weights[1] = spherical_area(point, c, a) / area;
weights[2] = spherical_area(point, a, b) / area;
/* A thin source triangle can admit an exterior point through the tolerant
* edge test. Unsigned subareas then do not partition the total area, and
* interpolating with their ratios can move an image outside its triangle.
* Reject that case before normalizing roundoff in valid convex weights.
* The 1e-8 bound is dimensionless; see the inverse-map design notes. */
const double weight_sum = weights[0] + weights[1] + weights[2];
if (!isfinite(weight_sum) || weight_sum <= 0.0 ||
fabs(weight_sum - 1.0) > 1e-8)
return -1;
for (int i = 0; i < 3; ++i)
weights[i] /= weight_sum;
return 0;
}
@@ -1055,7 +1066,7 @@ static int splat_catalog_tile(const Star *stars, size_t count,
context->vertex[0]->n_infinity,
context->vertex[1]->n_infinity,
context->vertex[2]->n_infinity, weights))
return -1;
continue;
}
if (!owns_source_boundary(context->triangle, weights))
continue;