是的,图片居中位置错误。
纹理映射应用于整个表面,而不仅仅是“活动”点(您没有 NaN 的那个点)。基本上,您得到的是将图像传播到整个球体上,然后当您裁剪球体的顶部以获得圆顶时,图像也会被裁剪:
您需要做的实际上是删除所有转换为NaN 的点,因此它们根本不是表面的一部分,纹理映射仅应用于顶部圆顶表面。
所以用下面的代码替换你的嵌套for循环:
idx_Raws2crop = Z1(:,1) < r2 ;
X1(idx_Raws2crop,:) = [] ;
Y1(idx_Raws2crop,:) = [] ;
Z1(idx_Raws2crop,:) = [] ;
然后继续你的代码,你会得到:
其实我也加了指令:
cdata = flipud(cdata) ;
为了使THE CIRCLEwriting 具有正确的方向(否则它会出现颠倒)。
编辑:
要根据您的评论以您喜欢的方式在圆顶上渲染图片,我可以看到2个选项:
选项 1:建立在我们已有的基础上
这将包括:
- 在正方形网格上扩展
[X,Y]域(这样当纹理映射到表面时图片不会失真)。
- 扩展图片本身(添加一些透明边距),这样边距将覆盖我们引入的域扩展,并且图片的实际可见部分将很好地居中在圆顶上。
使用与上面代码相同的X1、Y1 和Z1:
% Create a square grid large enough to cover the dome and a bit more:
[X2,Y2] = meshgrid(linspace(-5,5,100),linspace(-5,5,100)) ;
% reinterpolate Z1 over this new grid
Z2 = griddata(X1,Y1,Z1,X2,Y2) ;
现在您的表面如下所示:
正如我警告过的那样,图像现在已正确应用,但圆顶的边缘看起来相当难看。为了便于您将 NaN 替换为圆顶的基本值,这将在 dome 和 flat 域之间转换得更好:
Z2(isnan(Z2)) = 9 ;
现在将产生:
如您所见,下一个问题是(如您的第一个问题),图像被拉伸到整个表面。因此,部分文字现在位于表面的平坦部分。为了简单地缓解这种情况,您可以修改图片(在每一侧添加一点透明边距),直到图像的可见部分与圆顶尺寸匹配。
选项 2:以不同方式构建表面
这实际上更简单、更直接。我们将首先用方形表面建造一个圆顶(没有修剪和NaNing)。
此代码不需要您之前代码的任何部分,它是自包含的:
r = 10 ;
% Build a square grid
[X2,Y2] = meshgrid(linspace(-5,5,100),linspace(-5,5,100)) ;
% build Z2 according to the sphere equation.
Z2 = sqrt( r^2 - X2.^2 - Y2.^2) ;
figure();
my_dome = surf(X2,Y2,Z2,'EdgeColor', 'none', 'FaceColor', 'texturemap', 'CData', cdata, 'FaceAlpha', 1) ;
axis equal
这会产生一个很好地居中的纹理贴图:
注意:纹理映射效果很好,因为您的实际表面仍然是正方形,只是稍微弯曲以符合球体。纹理映射不显示图片透明的表面部分,因此它是不可见的,但是如果您在没有纹理映射的情况下查看表面,您将了解背景中发生了什么:
hs=surf(X2,Y2,Z2) ; shading interp ; axis equal