1

I have a 3D matrix defined like so:

A = zeros(3,3,3)*3;
A(:,:,1) = [1 2 3; 3 2 1; 3 4 7];
A(:,:,2) = [4 5 6; 6 5 4; 2 5 8];
A(:,:,3) = [7 8 9; 9 8 7; 3 6 9];

My goal is to extract a 2D matrix by interpolating 2 consecutive layers of the 3D matrix. In this example i want the matrix at a 75% distance between layer 1 and 2. I was able to achieve this by doing a simple linear interpolation but I would like to get some better and smarter way to perform this task maybe taking advantage of the built-in Matlab functions.

l = 1; % Layer: 1<= l <= size(A,3)-1
x = 0.75; % Distance at which i want to interpolate from layer 0<= x <= 1
AMin = A(:,:,l);
AMax = A(:,:,l+1);

AMin + (AMax-AMin)*x

Which returns

3.25         4.25         5.25
5.25         4.25         3.25
2.25         4.75         7.75

as expected.

Luis Mendo
  • 109,078
  • 12
  • 70
  • 142
Federico Gentile
  • 4,882
  • 8
  • 41
  • 91

2 Answers2

3

You can use interp3, but your code is clearer and probably faster:

x = 1.75; % interpolate between 3rd-dim layers 1 and 2, closer to 2
result = interp3(A, 1:size(A,2), (1:size(A,1)).', x);

Note that the second and third arguments to interp3 here are a row and a column vector. This selects all values of each 3rd-dim layer, because, from the documentation,

Vq = interp3(V,Xq,Yq,Zq)

If Xq, Yq, and Zq are vectors of different orientations, then Xq, Yq, and Zq are treated as grid vectors in R3.

Community
  • 1
  • 1
Luis Mendo
  • 109,078
  • 12
  • 70
  • 142
3

The built-in function interp3 can do what you're looking for.

A = zeros(3,3,3)*3;
A(:,:,1) = [1 2 3; 3 2 1; 3 4 7];
A(:,:,2) = [4 5 6; 6 5 4; 2 5 8];
A(:,:,3) = [7 8 9; 9 8 7; 3 6 9];

X = 0:size(A,1)-1;
Y = 0:size(A,2)-1;

[XX,YY] = meshgrid(X,Y); % 2D grid - so we can evaluate at many points
Target_Z = 0.75 * ones(size(XX));

OUT = interp3(X,Y,Z,A,XX,YY,Target_Z); 

The output would be

OUT =
    3.2500    5.2500    2.2500
    4.2500    4.2500    4.7500
    5.2500    3.2500    7.7500

Of course, you don't have to pick a regular grid to evaluate this function. You could easily have selected any (x,y,z) triples to evaluate.

Wick
  • 304
  • 1
  • 11
  • Don't transpose the output of the interpolation, instead use `meshgrid`, or change the input of `ndgrid` so it's not transposed: `[XX,YY]=meshgrid(X,Y)` or `[YY,XX]=ndgrid(Y,X)`. – Cris Luengo May 09 '19 at 18:09
  • Originally I had used ndgrid to make 3D XX,YY, ZZ blocks but I didn't need them. I've always been annoyed meshgrid and ndgrid aren't the same orientation. – Wick May 09 '19 at 18:18
  • Indeed, it's annoying. :) – Cris Luengo May 09 '19 at 18:20