Skip to content

Commit 51b710f

Browse files
committed
backtrack if overshooting
https://observablehq.com/@fil/2d-newton-raphson solves geoTetrahedralLee on the whole sphere https://observablehq.com/@fil/tetrahedral-lee-inverse
1 parent 311895a commit 51b710f

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

src/newton.js

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,23 @@ export function solve(f, y, x) {
1919
// Solve f(a,b) = [x,y]
2020
export function solve2d(f, MAX_ITERATIONS = 40, eps = epsilon2) {
2121
return function(x, y, a = 0, b = 0) {
22-
var tx, ty;
22+
var err2, da, db;
2323
for (var i = 0; i < MAX_ITERATIONS; i++) {
24-
var p = f(a, b);
25-
// diffs
26-
tx = p[0] - x;
27-
ty = p[1] - y;
24+
var p = f(a, b),
25+
// diffs
26+
tx = p[0] - x,
27+
ty = p[1] - y;
2828
if (abs(tx) < eps && abs(ty) < eps) break; // we're there!
2929

30+
// backtrack if we overshot
31+
var h = tx * tx + ty * ty;
32+
if (h > err2) {
33+
a -= da /= 2;
34+
b -= db /= 2;
35+
continue;
36+
}
37+
err2 = h;
38+
3039
// partial derivatives
3140
var ea = (a > 0 ? -1 : 1) * eps,
3241
eb = (b > 0 ? -1 : 1) * eps,
@@ -39,9 +48,9 @@ export function solve2d(f, MAX_ITERATIONS = 40, eps = epsilon2) {
3948
// determinant
4049
D = dyb * dxa - dya * dxb,
4150
// newton step — or half-step for small D
42-
l = (abs(D) < 0.5 ? 0.5 : 1) / D,
43-
da = (ty * dxb - tx * dyb) * l,
44-
db = (tx * dya - ty * dxa) * l;
51+
l = (abs(D) < 0.5 ? 0.5 : 1) / D;
52+
da = (ty * dxb - tx * dyb) * l;
53+
db = (tx * dya - ty * dxa) * l;
4554
a += da;
4655
b += db;
4756
if (abs(da) < eps && abs(db) < eps) break; // we're crawling

0 commit comments

Comments
 (0)