star-line

Structure for accelerating line importance sampling
git clone git://git.meso-star.fr/star-line.git
Log | Files | Refs | README | LICENSE

commit f3b7cff635e76f2c8da7bc3a4b788c3b42875761
parent a0c67190c1973f88f9a55cbe304963c2e8153e9b
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed,  4 Mar 2026 16:25:51 +0100

Fix numerical errors in polyline decimation

Update the calculation of the relative decimation error to avoid a
division by zero.

Manage "steps", type stairway, in line mesh. Although this cannot happen
in theory, digital uncertainty remains more creative. The normal of the
corresponding segment is then zero in Y so that it becomes impossible to
estimate, for a given abscissa, the value of the corresponding line,
which a division by zero would put forward. It was no longer possible to
decimate the polyline. Now, any vertex between the 2 boundaries of a
vertical segment is automatically removed to leave only this segment.

Diffstat:
Msrc/sln_polyline.c | 22+++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/sln_polyline.c b/src/sln_polyline.c @@ -100,6 +100,19 @@ find_falsest_vertex len = f2_normalize(N, N); ASSERT(len > 0); + + if(eq_eps(N[1], 0, 1e-6)) { + /* A normal with a value of zero in Y means a vertical segment. In fact, + * this is not supposed to happen because a line cannot have 2 different + * values for a single wave number. But this can happen due to numerical + * errors. In such a situation, all intermediate vertices may be considered + * to be located on the same vertical segment. And so, the error of using it + * to represent all intermediate vertices can be assumed to be zero. */ + *out_ivertex = range[0]; + *out_err = 0; + return; + } + /* Compute the last parameter of the edge equation */ C = -f2_dot(N, p0); @@ -120,7 +133,14 @@ find_falsest_vertex val = -(N[0]*p[0] + C)/N[1]; /* Compute the relative error of the linear approximation of p */ - err = absf(val - p[1]) / p[1]; + err = absf(val - p[1]); + if(err != 0) { + /* Divide by the maximum between the real and the approximated value to + * avoid a zero division */ + err /= MMAX(p[1], val); + } + ASSERT(!IS_NaN(err)); + if(err > err_max) { imax = ivertex; err_max = err;