// bug: won't work: field#1(2)[] F = bspln3 ⊛ image("../data/ddro.nrrd") - isoval; // field#2(2)[] F = bspln3 ⊛ image("../data/ddro.nrrd") - isoval; /* $DDRO_HOME/branches/vis12/bin/diderotc --exec bug027.diderot \ && ./bug027 \ && unu jhisto -i x.nrrd -b 800 800 -min 0 0 -max 1 1 \ | unu 2op neq - 0 \ | unu quantize -b 8 -o bug027.png */ input real isoval = 0.5; /* BUG: it looks like the type promotion from field#2 to field#1 doesn't work with subtracting a constant error converting OffsetField uncaught exception Fail [Fail: bogus operator OffsetField] raised at common/phase-timer.sml:76.50-76.52 raised at common/phase-timer.sml:76.50-76.52 raised at high-to-mid/high-to-mid.sml:297.85-297.87 raised at high-to-mid/high-to-mid.sml:294.32-294.78 */ field#1(2)[] F = bspln3 ⊛ image("../data/ddro.nrrd") - isoval; int grid = 150; int stepsMax = 10; real epsilon = 0.000001; strand RootFind(vec2 x0) { output vec2 x = x0; int steps = 0; update { // Stop if we're no longer inside or taken too many steps. if (!inside(x, F) || steps > stepsMax) die; vec2 grad = ∇F(x); // subsequent expressions are undefined if |∇F| is zero if (|grad| == 0.0) die; // the Newton-Raphson step vec2 delta = normalize(grad) * F(x)/|grad|; // we've converged if the change is small enough if (|delta| < epsilon) stabilize; x -= delta; steps += 1; } } initially { RootFind([lerp(0, 1, -0.5, ui, grid-0.5), lerp(0, 1, -0.5, vi, grid-0.5)]) | vi in 0..(grid-1), ui in 0..(grid-1) }; /* different in 3D: vec2 -> vec3 field#1(2)[] F -> field#1(3)[] F initially over 3D grid */