查找最接近与非线性曲面相交的 Z 平面的整数 X 和 Y

Find integer X and Y closest to a Z plane intersecting a nonlinear surface

对于非线性函数 f(x,y),我需要沿着与表面相交的 f(x,y) 轴找到最接近任何实数平面的整数 x 和 y。 x 的范围为 0 到 255,y 的范围为 0 到 1023。

完成此操作的一种方法是评估 f(x,y) s.t 的所有 262,144 个值。 x 和 y 是整数,对其进行排序,然后进行高效搜索,但我希望在微积分或几何学中找到更优雅的解决方案。

我最初的想法是提取由平面和曲面相交创建的曲线,以便我可以在二维中工作,然后沿着该曲线搜索使我最接近的 x 和 y 整数值曲线。问题是我不知道一种有效的方法来确定哪些点很近,哪些点最近。

这需要尽快完成大约 32000 个不同的 f(x,y) 值,因此我试图找到最有效的方法来即时计算它。例如:图像中的平面是 f(x,y)=3500.6,最接近的整数坐标可能是 (112,432)。注意:坐标轴 x*8 和 y*8

我认为 pre-computing 是正确的选择。

给定一个函数 f(x,y),计算所有 z 值并对它们进行排序:

var xrange = Enumerable.Range(0, 256);
var yrange = Enumerable.Range(0, 1024);
var xyzValues = xrange.SelectMany(x => yrange.Select(y => new { x, y, z = f(x, y) })).OrderBy(xyz => xyz.z).ToList();

现在使用扩展方法对存储在 planes 中的每个可能值进行二进制搜索(进行 Log2(262,144) = 18 次比较):

var ans = planes.Select(p => new { Plane = p, xyz = xyzValues.BinaryFindDoubleBy(p, xyz => xyz.z) });

这里是扩展方法:

public static class ListExt {
    public static T BinaryFindDoubleBy<T>(this List<T> src, double key, Func<T, double> selectorFn) {
        var lower = 0;
        var upper = src.Count;
        do {
            var pos = (lower + upper) / 2;
            var posKey = selectorFn(src[pos]);
            if (key < posKey)
                upper = pos;
            else
                lower = pos;
        } while (lower < upper - 1);

        return Math.Abs(selectorFn(src[lower])-key) < Math.Abs(selectorFn(src[upper])-key) ? src[lower] : src[upper];
    }
}