How to plot a surface with a texture map

非 Y 不嫁゛ 提交于 2019-11-30 15:33:24
shoelzer

I don't think you can do what you want with Matlab's built in commands and features. But using the technique from my other answer with a high-res version of the grid can do it for you.

By "high-res", I mean an interpolated version of the non-uniform grid with denser data points. That is used to sample the texture at denser data points so it can be drawn using the texturemap feature of surf. You can't use a normal 2D interpolation, however, because you need to preserve the non-uniform grid shape. This is what I came up with:

function g = nonUniformGridInterp2(g, sx, sy)

[a,b] = size(g);
g = interp1(linspace(0,1,a), g, linspace(0,1,sy)); % interp columns
g = interp1(linspace(0,1,b), g', linspace(0,1,sx))'; % interp rows

Note that you have to call this twice to interpolate the X and Y points independently. Here's an example of the original grid and an interpolated version with 10 points in each direction.

Here's how to use that high-res grid with interp2 and texturemap.

function nonUniformTextureMap

% define the non-uniform surface grid
X = [310,270,330; 430,410,400; 480,500,520];
Y = [300,400,500; 300,400,500; 300,400,500];
Z = [300,330,340; 300,310,330; 290,300,300];

% get texture data
load penny % loads data in variable P

% define texture grid based on image size
% note: using 250-550 so that a,b covers the range used by X,Y
[m,n] = size(P);
[a,b] = meshgrid(linspace(250,550,n), linspace(250,550,m));

% get a high-res version of the non-uniform grid
s = 200; % number of samples in each direction
X2 = nonUniformGridInterp2(X, s, s);
Y2 = nonUniformGridInterp2(Y, s, s);

% sample (map) the texture on the non-uniform grid
C = interp2(a, b, P, X2, Y2);

% plot the original and high-res grid
figure
plot(X(:),Y(:),'o',X2(:),Y2(:),'.')
legend('original','high-res')

% plot the surface using sampled points for color
figure
surf(X, Y, Z, C, 'edgecolor', 'none', 'FaceColor','texturemap')
colormap gray

You can use the texturemap property of surf which works with rectangular meshes as well as with non-rectangular ones.

Creating non-rectangular data points

% creating non-rectangular data points
[X, Y] = meshgrid(1:100, 1:100);
X = X+rand(size(X))*5; 
Y = Y+rand(size(X))*5; 

which results in the following data points:

Generating height data:

Z = sin(X/max(X(:))*2*pi).*sin(Y/max(Y(:))*2*pi);

Loading picture:

[imageTest]=imread('peppers.png');

and mapping it as texture to the mesh:

surf(X,Y,Z, imageTest, ...
     'edgecolor', 'none','FaceColor','texturemap')

Note that, for the sake of demonstration, this non-rectangular grid is quite sparsely populated which results in a rather jagged texture. With more points, the result gets much better, irrespective of the distortion of the grid points.

Note also that the number of grid points does not have to match the number of pixels in the texture image.

~edit~

If X and Y coordinates are only available for parts of the image, you can adjust the texture accordingly by

minX = round(min(X(:)));
maxX = round(max(X(:))); 
minY = round(min(Y(:)));
maxY = round(max(Y(:)));

surf(X,Y,Z, imageTest(minX:maxX, minY:maxY, :), ...
     'edgecolor', 'none','FaceColor','texturemap')

I'm not sure I understand your question, but I think that what you need to do is sample (map) the texture at your grid's X,Y points. Then you can simply plot the surface and use those samples as colors.

Here's an example using the data you gave in your question. It doesn't look like much, but using more X,Y,Z points should give the result you're after.

% define the non-uniform surface grid
X = [310,270,330; 430,410,400; 480,500,520];
Y = [300,400,500; 300,400,500; 300,400,500];
Z = [300,330,340; 300,310,330; 290,300,300];

% get texture data
load penny % loads data in variable P

% define texture grid based on image size
% note: using 600 so that a,b covers the range used by X,Y
[m,n] = size(P);
[a,b] = meshgrid(linspace(0,600,n), linspace(0,600,m));

% sample (map) the texture on the non-uniform grid
C = interp2(a, b, P, X, Y);

% plot the surface using sampled points for color
figure
surf(X, Y, Z, C)
colormap gray

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!