public bool xClosest(ref Vect2 uv, ref Vect3 xyzTarget, ref double dist, double tol) { Vect3 x = new Vect3(xyzTarget); Vect3 dxu = new Vect3(), dxv = new Vect3(); Vect3 ddxu = new Vect3(), ddxv = new Vect3(), dduv = new Vect3(); Vect3 h = new Vect3(); Vect2 c = new Vect2(); Vect2 res = new Vect2(); Vect2 a = new Vect2(), b = new Vect2(); double det, r; Vect2 d = new Vect2(); int loop = 0, max_loops = 150; while (loop++ < max_loops) { xCvt(uv, ref x, ref dxu, ref dxv, ref ddxu, ref ddxv, ref dduv); h = x - xyzTarget; //h = BLAS.subtract(x, xyzTarget); dist = h.Magnitude; //e[0] = s; c[0] = h.Dot(dxu);// BLAS.dot(h, dxu); // error, dot product is 0 at pi/2 c[1] = h.Dot(dxv);// BLAS.dot(h, dxv); // error, dot product is 0 at pi/2 if (Math.Abs(c[0]) < tol && Math.Abs(c[1]) < tol) // error is less than the tolerance { xyzTarget.Set(x);// return point to caller return true; } a[0] = dxu.Norm + h.Dot(ddxu); a[1] = b[0] = dxu.Dot(dxv) + h.Dot(dduv); b[1] = dxv.Norm + h.Dot(ddxv); //a[0] = BLAS.dot(dxu, dxu) + BLAS.dot(h, ddxu); //a[1] = BLAS.dot(dxu, dxv) + BLAS.dot(h, dduv); //b[0] = a[1]; //b[1] = BLAS.dot(dxv, dxv) + BLAS.dot(h, ddxv); det = a.Cross(b); //det = BLAS.cross2d(a, b); d[0] = c.Cross(b) / det; d[1] = a.Cross(c) / det; //d[0] = BLAS.cross2d(c, b) / det; //d[1] = BLAS.cross2d(a, c) / det; c[0] = 0.01 > Math.Abs(d[0]) ? 1 : 0.01 / Math.Abs(d[0]); c[1] = 0.01 > Math.Abs(d[1]) ? 1 : 0.01 / Math.Abs(d[1]); //enforce maximum increment r = Math.Min(c[0], c[1]); //increment uv by scaled residuals //uv = BLAS.subtract(uv, BLAS.scale(d, r)); uv = uv - d * r; //logger.write_format_line("%.5g\t%.5g\t%.5g\t%.5g\t%.5g\t", x[ox], x[oy], e[ox], e[oy], dist); } //s = s0; return false; }