8

So I'm trying to write a trilinear interpolation function but am having some trouble coming up with it.

So first we have a 1D interpolation:

float interpolate1D(float v1, float v2, float x){
    return v1*(1-x) + v2*x;
}

And then 2D interpolation:

float interpolate2D(float v1, float v2, float v3, float v4, float x, float y){

    float s = interpolate1D(v1, v2, x);
    float t = interpolate1D(v3, v4, x);
    return interpolate1D(s, t, y);
}

But then things get tricky once it gets to 3D. I can't quite figure out how to implement a 3D interpolator using the 2D interpolation function. I don't know why I'm having this mental bock since it should just be a straightforward extension but I guess all of the different variables at play are throwing me off. So I've started off a function below but it's incomplete and I need help finishing it.

float interpolate3D(v1, v2, v3, v4, v5, v6, v7, v8, float x, float y, float z){


     float s = interpolate2D(v1, v2, v3, v4, x, y);
     float t = interpolate2D(v5, v6, v7, v7, x, z);

     //What do I do next?
}
duplode
  • 33,731
  • 7
  • 79
  • 150
user1855952
  • 1,515
  • 5
  • 26
  • 55
  • You have projections on the `xy` and `xz` plane now, so the intersection of those planes leaves one degree of freedom: in the `x` direction. So I guess you should `interpolate1D(s, t, x)`? – Vincent van der Weele Oct 09 '13 at 12:11
  • But I feel like I would need to do an interpolation for each of the 6 sides of the "cube" and then I'd have 6 values, s,t,u,w,x,y lets call them. And then from there I'm still lost... – user1855952 Oct 09 '13 at 12:16
  • I'm a little confused by your approach. If you interpolate two 2-dimensional vectors, wouldn't you expect a 2-dimensional vector as result? And in 3d you would expect a 3d vector as a result? – Vincent van der Weele Oct 09 '13 at 12:58

3 Answers3

7

You have 2 problems with your code - v7 appears twice.

Let me spell it out for you:

float interpolate3D(v1, v2, v3, v4, v5, v6, v7, v8, float x, float y, float z)
{
    float s = interpolate2D(v1, v2, v3, v4, x, y);
    float t = interpolate2D(v5, v6, v7, v8, x, y);
    return interpolate1D(s, t, z);
}

Compare this to interpolate2D():

  • interpolate twice by the "lower dimension" (1D for 2D, 2D for 1D), using the same variables (x for 1D, (x, y) for 2D)
  • interpolate the intermediate results 1D, using the remaining variable (y for 2D, z for 3D)

Also note - we don't know how you place your v1 through v8. But if you do it correctly, this function will work.

Tomasz Gandor
  • 8,235
  • 2
  • 60
  • 55
2

Linear interpolation does not operate on faces (not every hypercube has faces). It operates on vertices, in pairs.

You can think of nD interpolation as having two parts:

  1. A series of 1D interpolations on pairs of input vertices.
  2. (n-1)D interpolation on the interpolated values from the first part.

2D interpolation, for instance, is 1D interpolation on the 2 pairs of input vertices, followed by 1D interpolation on the 2 results. 3D interpolation is 1D interpolation on the 4 pairs of input vertices, followed by 2D interpolation on the 4 results. 4D interpolation is 1D interpolation on the 8 pairs of input vertices, followed by 3D interpolation on the 8 results.

Basically, the first part reduces the interpolation problem from nD to an equivalent (n-1)D interpolation problem; the second part performs that interpolation.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
-1

A very good source to understand the trilinear interpolation can be found at: https://en.wikipedia.org/wiki/Trilinear_interpolation

It mentions the following:

In practice, a trilinear interpolation is identical to two bilinear interpolation combined with a linear interpolation:

C = linear(bilinear(C_(000),C_(010),C_(100),C_(110)),
           bilinear(C_(001),C_(011),C_(101),C_(111)))
ObAt
  • 2,337
  • 3
  • 24
  • 44
DG44
  • 7
  • 2