2009-07-02 5 views
4

L'interpolation trilinéaire se rapproche de la valeur d'un point (x, y, z) à l'intérieur d'un cube en utilisant les valeurs des sommets du cube. J'essaie de faire une interpolation trilinéaire "inverse". Connaissant les valeurs aux sommets du cube et la valeur attachée à un point, comment puis-je trouver (x, y, z)? Toute aide serait très appréciée. Je vous remercie!Est-ce que quelqu'un sait comment faire une interpolation trilinéaire "inverse"?

+0

Je ne sais pas le jargon de l'interpolation. Veuillez expliquer l'interpolation trilinéaire. Je vais essayer de vous aider avec les maths. – Martijn

+1

Combien de dimensions indépendantes les valeurs des sommets ont-elles? Si les valeurs sont scalaires, il n'y a pas de solution pour trouver un seul point, car il n'y en aura pas. Vous avez besoin de données avec au moins 3 dimensions indépendantes pour que cette opération soit réversible. – jerryjvl

+0

Mon commentaire n'était pas entièrement bien défini non plus, mais essayant fondamentalement de dire que vous devez avoir un ensemble de valeurs appropriées aux 6 sommets pour que cela soit même possible. – jerryjvl

Répondre

3

Vous résolvez 3 inconnues données 1, et comme vous utilisez une interpolation linéaire votre réponse sera typiquement un plan (2 variables libres). Selon le cube, il peut ne pas y avoir de solutions ou d'espace de solution 3D.

Je ferais ce qui suit. Soit v la valeur initiale. Pour chaque "arête" des 12 arêtes (paire de sommets adjacents) du cube, regardez si 1 sommet est> = v et l'autre < = v - appelez ceci une arête qui traverse v.

Si aucune arête croiser v, alors il n'y a pas de solutions possibles.

Sinon, pour chaque arête qui croise v, si les deux sommets du bord sont égaux à v, alors le bord entier est une solution. Sinon, interpolez linéairement sur le bord pour trouver le point qui a une valeur de v. Supposons donc que le bord est (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) 

Cela vous donnera tous les points de bord qui sont égaux à v Ceci est une solution, mais peut-être vous voulez une solution interne -. Sachez que s'il y a une solution interne il y aura toujours une solution de pointe.

Si vous voulez une solution interne puis il suffit de prendre un point quelconque linéaire entre les solutions de pointe - comme vous interpolation linéaire alors le résultat sera également v

2

Je ne suis pas sûr que vous pouvez pour tous les cas. Par exemple, en utilisant un filtrage tri-linéaire pour les couleurs où chaque couleur (C) à chaque point est identique signifie que partout où vous interpolez vous obtiendrez toujours la couleur C retournée. Dans cette situation, ANY x, y, z pourrait être valide. En tant que tel, il serait impossible de dire avec certitude quelles étaient les valeurs d'interpolation initiales. Je suis sûr que dans certains cas, vous pouvez inverser les maths mais, j'imagine, il y a beaucoup trop de cas où cela est impossible à faire sans en savoir plus sur les informations d'entrée.

Bonne chance, j'espère que quelqu'un va me prouver :)

0

Le problème que vous décrivez quelque peu mal défini. Ce que vous demandez se traduit essentiellement par ceci: j'ai une fonction 3D et je connais ses valeurs en 8 points connus. Je voudrais savoir quel est le point où la fonction a reçu la valeur V.
Le problème est que, selon toute vraisemblance, il existe un nombre infini de points qui forment un ensemble de surfaces, de lignes ou de points, selon les données .
Une façon de trouver cet ensemble est d'utiliser un algorithme iso-surfacing comme Marching cubes.

+0

Correct, en fait, la valeur de any (x, y, z) peut être n'importe quelle valeur. Bien sûr, s'il y a plus d'informations sur la fonction disponible (linéarité, quadratique, etc.), il peut être possible d'inverser les calculs, jusqu'à certains cas dégénérés. – Martijn

+0

Malheureusement, je n'ai pas de fonction 3D. Je n'ai que les valeurs attachées aux 8 sommets et la valeur d'un point que je connais c'est dans le cube et j'essaie de trouver sa position. –

+0

Si vous voulez utiliser une fonction linéaire, vous trouvez essentiellement quel point du 8 est le plus proche, prenez sa valeur et ajoutez-lui la distance. – shoosh

0

Le wikipedia page for trilinear interpolation a un lien vers a NASA page qui décrit le processus d'inversion - avez-vous déjà vu cela?

+0

Oui, je l'ai fait, mais je ne pouvais pas localiser où ils utilisent la valeur attachée au point. –

+0

en fait, il ne ressemble pas à un inverse –

0

Commençons par 2d:. Penser à une colline bilinéaire sur une km carrés, avec des hauteurs disons 0 10 20 30 aux 4 coins et un plan horizontal coupant la colline à la hauteur z. Tracez une ligne du coin 0 au coin 30 (adjacent ou en diagonale). L'avion doit couper cette ligne, pour tout z, de sorte que tous les points x, y, z tombent sur cette ligne, non? Hmm. OK, il existe de nombreuses solutions: tout plan z coupe la pente dans une courbe de contour. que nous voulons des solutions à répartir sur toute la colline, -à-dire réduire les deux choses à la fois:

  • distance verticale z - Bilin (x, y),
  • distance de x, y à un moment donné dans le carré. Scipy.optimize.leastsq est un moyen de le faire, exemple de code ci-dessous;

trilinéaire est similaire.

(Optimisation des deux choses à la fois exige un compromis entre arbitraire ou pondération: alimentaire par rapport à l'argent, le travail contre le jeu ... Cf. Bounded rationality )

""" 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) 
Questions connexes