How to draw a triangle with a texture in MATLAB?

I have a triangle in the coordinates (u,v) in the image. I would like to draw this triangle in three-dimensional coordinates (X,Y,Z) with a texture with a triangle in the image.

Here u,v,X,Y,Z are all vectors with three elements representing the three angles of the triangle.

I have a very ugly, slow and unsatisfactory solution in which I:

  • extract the rectangular part of the image
  • converts it to 3D space with a transformation defined by three points
  • draw it with a surface
  • finally disguises everything that is not part of the triangle with AlphaData li>

Could there really be an easier way to do this?

+4
source share
2 answers

I have what I consider the best solution for you, including two steps. Firstly, it extracts the rectangular part of your image, half of which is a triangular section that will be used as a texture map, and half of them will be ignored. This texture map is then applied to a 3-D surface object whose points are adjusted to make it a triangle instead of a four-sided one.

In the example below, I will use the following values ​​for your various parameters, assuming that you have a triangle whose points are designated as the "beginning" (triangle of the triangle), point "A" and point "B" in the image space (as in the first image below):

 x = [0.1 0.9 0.8]; % [xorigin xA xB] coordinates in 3-D space y = [0.9 0.1 0.8]; % [yorigin yA yB] coordinates in 3-D space z = [0.1 0.1 0.9]; % [zorigin zA zB] coordinates in 3-D space origin = [150 350]; % Vertex of triangle in image space U = [300 -50]; % Vector from origin to point A in image space V = [50 -250]; % Vector from origin to point B in image space img = imread('peppers.png'); % Sample image for texture map 


Extracting a texture map through projective transformation:

This step uses the Image Processing Toolbox maketform and imtransform to projectively transform the portion of the image containing the triangle that you want to use as the texture imtransform that since the images must be rectangular, you need to add an additional triangular section defined by points (O,B,C) .

enter image description here

The triangular part of the image you want will be in the lower right half of the image, and the additional triangular β€œfill” part will be in the upper left corner. Please note that this extra triangle may extend beyond the image, due to which part of it will fill with black by default. Here is the code for performing the projective conversion shown above:

 A = origin+U; % Point A B = origin+V; % Point B C = BU; % Point C [nRows, nCols, nPages] = size(img); % Image dimensions inputCorners = [origin; ... % Corner coordinates of input space A; ... B; ... C]; outputCorners = [1 nRows; ... % Corner coordinates of output space nCols nRows; ... nCols 1; ... 1 1]; tform = maketform('projective', ... % Make the transformation structure inputCorners, ... outputCorners); triTexture = imtransform(img,tform, 'bicubic', ... % Transform the image 'xdata', [1 nCols], ... 'ydata', [1 nRows], ... 'size', [nRows nCols]); 

Note that this code will create the final triTexture image, which will be the same size as the input img image.


Building a triangular textured surface:

Building a surface is now quite simple, assuming you ordered values ​​in your variables x,y,z , so that the coordinates of the start point are in the first indices, the coordinates for point A are in the second indices, and the coordinates for point B are in the third indices. Now you can create new sets of 2-by-2 surface coordinates x,y,z that contain two copies of point B, which forces you to display only half the surface (i.e., the Half containing the desired triangular image as a texture map). Here is the code for this:

 index = [3 3; 1 2]; % Index used to create 2-by-2 surface coordinates X = x(index); % x coordinates of surface Y = y(index); % y coordinates of surface Z = z(index); % z coordinates of surface hSurface = surf(X, Y, Z, triTexture, ... % Plot texture-mapped surface 'FaceColor', 'texturemap', ... 'EdgeColor', 'none'); axis equal % Use equal scaling on axes axis([0 1 0 1 0 1]); % Set axes limits xlabel('x-axis'); % x-axis label ylabel('y-axis'); % y-axis label zlabel('z-axis'); % z-axis label 

And here is the resulting textured triangular surface that he creates, with an insert added to show that the texture map contains the correct triangular part of the original image:

enter image description here

+13
source

Source: https://habr.com/ru/post/1301454/


All Articles