Skip to content

Commit 3187a40

Browse files
committed
Update sbisect to return no roots when ray domain range is tiny.
Roots being very closely packed as happens most often when a ray is nearly tangent to a surface cause instability in the sturm change sign counting (numchanges) results. The instability, if not avoided, leads to incomplete and sometimes inaccurately ordered roots. One of the triggers for the CEY patch added in 1997 and where we get the diagonal lines of no roots in certain objects.
1 parent 4a252b2 commit 3187a40

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

source/core/math/polynomialsolver.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ const DBL FOUR_M_PI_3 = 4.1887902047863909846168;
9595
/* Max number of iterations. */
9696
const int MAX_ITERATIONS = 65;
9797

98+
// NOTE: Value below which multiple roots ignored. Rays near tangent to surface
99+
// create extremely close roots and instability in sturm chain sign change
100+
// results from numchanges(). Also where the diagonal line of missed roots in
101+
// formed polynomials appears due root collapsing toward each other in
102+
// directions parallel to the ray.
103+
const DBL SBISECT_MULT_ROOT_THRESHOLD = 1e-6;
104+
98105
// NOTE: max_value - min_value threshold below which regula_falsa function is
99106
// tried when there is a single root. Single roots happen often. Rays continued
100107
// by transparency or internal reflection for example will have just one root.
@@ -554,6 +561,11 @@ static int sbisect(int np, const polynomial *sseq, DBL min_value, DBL max_value,
554561

555562
if ((n1 != 0) && (n2 != 0))
556563
{
564+
if ((max_value - min_value) < SBISECT_MULT_ROOT_THRESHOLD)
565+
{
566+
return(0);
567+
}
568+
557569
n1 = sbisect(np, sseq, min_value, mid, atmin, atmid, roots);
558570
n2 = sbisect(np, sseq, mid, max_value, atmid, atmax, &roots[n1]);
559571

0 commit comments

Comments
 (0)