MATLAB中的纹理映射

yxk*_*yxk 10 matlab plot interpolation texture-mapping geometry-surface

我在3D空间中有点和它们相应的2D图像点.如何从3D点中制作网格,然后纹理网格形成的三角形面?

gno*_*ice 5

请注意,trisurf您最初尝试使用的函数会返回修补程序对象的句柄.如果查看'FaceColor'属性中的补丁对象,可以看到没有'texturemap'选项.该选项仅对曲面对象'FaceColor'属性有效.因此,您必须找到一种方法将三角形曲面绘制为曲面对象而不是贴片对象.以下是两种方法:

如果您的数据在统一网格中......

如果您的表面数据的坐标是一个统一的电网,从而z是一个长方形的点的集合,从跨越xminxmax在x轴,yminymax在y轴,您可以使用绘制它surf,而不是trisurf:

Z = ...  % N-by-M matrix of data
x = linspace(xmin, xmax, size(Z, 2));  % x-coordinates for columns of Z
y = linspace(ymin, ymax, size(Z, 1));  % y-coordinates for rows of Z
[X, Y] = meshgrid(x, y);               % Create meshes for x and y
C = imread('image1.jpg');              % Load RGB image
h = surf(X, Y, Z, flipdim(C, 1), ...   % Plot surface (flips rows of C, if needed)
         'FaceColor', 'texturemap', ...
         'EdgeColor', 'none');
axis equal
Run Code Online (Sandbox Code Playgroud)

为了说明上述代码的结果,我将数据初始化为Z = peaks;,使用内置的样本图像'peppers.png',并将xy值设置为从1到16.这导致以下纹理映射表面:

在此输入图像描述

如果您的数据是非均匀间隔的......

如果您的数据没有规则间隔,您可以创建一组规则间隔XY坐标(如上所述meshgrid),然后使用其中一个函数griddataTriScatteredInterp插入Z来自不规则z值集的常规网格值.我在另一个SO问题的答案中讨论了如何使用这两个函数.这是您发布的代码的精炼版本TriScatteredInterp(注意:从R2013a开始scatteredInterpolant是推荐的替代方案):

x = ...  % Scattered x data
y = ...  % Scattered y data
z = ...  % Scattered z data
xmin = min(x);
xmax = max(x);
ymin = min(y);
ymax = max(y);
F = TriScatteredInterp(x(:), y(:), z(:));  % Create interpolant
N = 50;  % Number of y values in uniform grid
M = 50;  % Number of x values in uniform grid
xu = linspace(xmin, xmax, M);         % Uniform x-coordinates
yu = linspace(ymin, ymax, N);         % Uniform y-coordinates
[X, Y] = meshgrid(xu, yu);            % Create meshes for xu and yu
Z = F(X, Y);                          % Evaluate interpolant (N-by-M matrix)
C = imread('image1.jpg');             % Load RGB image
h = surf(X, Y, Z, flipdim(C, 1), ...  % Plot surface
         'FaceColor', 'texturemap', ...
         'EdgeColor', 'none');
axis equal
Run Code Online (Sandbox Code Playgroud)

在这种情况下,你必须首先选择的值N,并M为您的矩阵的大小Z.为了说明上面的代码的结果,我初始化数据x,y以及z如下以及所使用的内置采样图像'peppers.png':

x = rand(1, 100)-0.5;  % 100 random values in the range -0.5 to 0.5
y = rand(1, 100)-0.5;  % 100 random values in the range -0.5 to 0.5
z = exp(-(x.^2+y.^2)./0.125);  % Values from a 2-D Gaussian distribution
Run Code Online (Sandbox Code Playgroud)

这导致以下纹理映射表面:

在此输入图像描述

请注意,表面角落附近有锯齿状边缘.这些地方的点数太少,TriScatteredInterp无法充分拟合插值曲面.Z因此nan,这些点处的值导致表面点未被绘制.