4

三线性插值使用立方体顶点处的值来近似立方体内点 (x, y, z) 的值。我正在尝试做一个“逆”三线性插值。知道立方体顶点的值和附加到点的值如何找到(x,y,z)?任何帮助将不胜感激。谢谢!

4

5 回答 5

3

给定 1 个数据,您正在求解 3 个未知数,并且当您使用线性插值时,您的答案通常是一个平面(2 个自由变量)。根据立方体的不同,可能没有解或 3D 解空间。

我会做以下事情。设 v 为初始值。对于立方体的 12 条边(相邻顶点对)中的每条“边”,查看是否有 1 个顶点 >=v 且另一个 <=v - 称其为穿过 v 的边。

如果没有边与 v 相交,则没有可能的解决方案。

否则,对于穿过 v 的每条边,如果边的两个顶点都等于 v,则整条边都是一个解。否则,在边缘上线性插值以找到值为 v 的点。因此假设边缘是 (x1, y1, z1)->v1 <= v <= (x2, y2, z2)->v2。

s = (v-v1)/(v2-v1)
(x,y,z) = (s*(x2-x1)+x1, (s*(y2-y1)+y1, s*(z2-z1)+z1)

这将为您提供等于 v 的所有边缘点。这是一个解决方案,但您可能需要一个内部解决方案 - 请注意,如果有内部解决方案,总会有一个边缘解决方案。

如果您想要一个内部解决方案,那么只需在边缘解决方案之间线性取任意点 - 因为您是线性插值,那么结果也将是 v。

于 2009-07-02T09:31:04.240 回答
2

我不确定您是否可以适用于所有情况。例如,对每个点的每种颜色 (C) 相同的颜色使用三线性过滤意味着无论您在哪里插值,您仍然会得到返回的颜色 C。在这种情况下,任何 x,y,z 都可能是有效的。因此,不可能确切地说出初始插值值是多少。

我敢肯定,在某些情况下,您可以反转数学运算,但我想,在很多情况下,如果不了解更多输入信息,这是不可能做到的。

祝你好运,我希望有人会证明我错了:)

于 2009-07-02T08:47:03.940 回答
0

您描述的问题有些不明确。
你所要求的基本上可以转化为:我有一个 3D 函数,我知道它在 8 个已知点中的值。我想知道函数接收值 V 的点是什么。
问题在于,很可能有无数这样的点构成一组曲面、线或点,具体取决于数据。
找到该集合的一种方法是使用等曲面算法,例如Marching cubes

于 2009-07-02T08:48:54.763 回答
0

三线性插值的维基百科页面有一个 NASA 页面的链接,据称该页面描述了反演过程 - 你看过吗?

于 2009-07-02T08:54:56.030 回答
0

让我们从 2d 开始:想象一平方公里的双线性山丘,高度为 0 10 20 30 在 4 个角处,水平面在高度 z 处切割山丘。从 0 角到 30 角画一条线(无论是相邻还是对角线)。对于任何 z,平面必须切割这条线,所以所有点 x,y,z 都落在这条线上,对吗?唔。

好的,有很多解决方案——任何 z 平面都以等高线曲线切割山丘。假设我们希望解决方案遍布整个山丘,即一次最小化两件事:

  • 垂直距离 z - bilin(x,y),
  • 从 x,y 到正方形中某个点的距离。

Scipy.optimize.leastsq 是这样做的一种方式,示例代码如下;三线类似。

(同时优化任何两件事需要任意权衡或加权:食物与金钱,工作与娱乐......参见有限理性

""" find x,y so bilin(x,y) ~ z  and  x,y near the middle """
from __future__ import division
import numpy as np
from scipy.optimize import leastsq

zmax = 30
corners = [ 0, 10, 20, zmax ]
midweight = 10

def bilin( x, y ):
    """ bilinear interpolate
        in: corners at 0 0  0 1  1 0  1 1 in that order (binary)
        see wikipedia Bilinear_interpolation ff.
    """
    z00,z01,z10,z11 = corners  # 0 .. 1
    return (z00 * (1-x) * (1-y)
        + z01 * (1-x) * y
        + z10 * x * (1-y)
        + z11 * x * y)

vecs = np.array([ (x, y) for x in (.25, .5, .75) for y in (.25, .5, .75) ])
def nearvec( x, vecs ):
    """ -> (min, nearest vec) """
    t = (np.inf,)
    for v in vecs:
        n = np.linalg.norm( x - v )
        if n < t[0]:  t = (n, v)
    return t

def lsqmin( xy ):  # z, corners
    x,y = xy
    near = nearvec( np.array(xy), vecs )[0] * midweight
    return (z - bilin( x, y ), near )
        # i.e. find x,y so both bilin(x,y) ~ z  and  x,y near a point in vecs

#...............................................................................
if __name__ == "__main__":
    import sys
    ftol = .1
    maxfev = 10
    exec "\n".join( sys.argv[1:] )  # ftol= ...
    x0 = np.array(( .5, .5 ))
    sumdiff = 0
    for z in range(zmax+1):
        xetc = leastsq( lsqmin, x0, ftol=ftol, maxfev=maxfev, full_output=1 )
            # (x, {cov_x, infodict, mesg}, ier)
        x,y = xetc[0]  # may be < 0 or > 1
        diff = bilin( x, y ) - z
        sumdiff += abs(diff)
        print  "%.2g  %8.2g  %5.2g %5.2g" % (z, diff, x, y)

print "ftol %.2g maxfev %d midweight %.2g  =>  av diff %.2g" % (
    ftol, maxfev, midweight, sumdiff/zmax)
于 2010-03-08T16:19:54.997 回答