How to build a surface with a texture map

I want to draw a surface with a texture map on it, but the conditions are not "ideal".

first lets explain what I have.

I have a set of points (~ 7000), which are the coordinates of the image in the grid. These points do NOT define perfect squares. This is not MESHGRID . For the sake of the question, let's assume that we have 9 points. Let's show what we have with the image:

X=[310,270,330,430,410,400,480,500,520] Y=[300,400,500,300,400,500,300,400,500] 

enter image description here Suppose we can get the "structure" of the grid, so

  size1=3; size2=3; points=zeros(size1,size2,2) X=[310,270,330; 430,410,400; 480,500,520] Y=[300,400,500; 300,400,500; 300,400,500] points(:,:,1)=X; points(:,:,2)=Y; 

Now let's say that we have a 3-dimensional dimension, Z.

EDIT: Forgot to add a piece if information. I triangulate the points in the image and get a three-dimensional correspondence, therefore, when they are displayed on the surface, they do not have the X and Y coordinates of the image, to simplify the data data, we can say that X = X / 2 Y = Y / 3

And we have:

  points=zeros(size1,size2,3) Z=[300,330,340; 300,310,330; 290,300,300] surf(points(:,:,1)/2,points(:,:,2)/3,points(:,:,3)) 

enter image description here

What I want is to build a surface in 3D with an image texture. Each element must have a piece of texture that it has in the first image.

This should work for huge data tables. I don't need it to be fast.

linked post (but I have a meshgrid as an initial set of points): Texture map for a 2D mesh

PD: I can publish original images + real data, if necessary, just posted this because I think that with small data is easier.

+4
source share
3 answers

I don’t think you can do what you want with Matlab built into commands and functions. But using the technique from my other high-resolution grid answer , you can do it for you.

By "high resolution" is meant an interpolated version of an uneven grid with denser data points. This is used to draw texture at denser data points, so you can draw it using the texturemap surf function. However, you cannot use regular 2D interpolation because you need to preserve the irregular shape of the grid. Here 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 must call this twice to interpolate the X and Y points independently. Here is an example of the original grid and the interpolated version with 10 points in each direction.

Plot of the original and interpolated grids

Here's how to use this high resolution 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 

Plot of the mapped texture

+4
source

You can use the texturemap surf property, 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; 

leading to the following data points:

enter image description here

Altitude data generation:

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

enter image description here

Image upload:

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

enter image description here

and displaying it as a texture in a grid:

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

enter image description here

Note that for demonstration, this non-rectangular grid is quite sparsely populated, resulting in a rather uneven texture. With more points, the result is much better, regardless of the distortion of the grid points.

Please also note that the number of grid points must not coincide with the number of pixels in the texture image.

~ ~ edit

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

 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') 
+10
source

I'm not sure I understand your question, but I think that you need to make a selection (display) of the texture in your grid of X, Y points. Then you can simply build the surface and use these patterns as colors.

Here is an example of using the data that you provided in your question. This doesn't seem like much, but using more of the points X, Y, Z should give the result you are 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 

Plot of the mapped texture

+1
source

All Articles