matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例

整体展示

《matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例》

%% 创建窗口
f = figure('position',[200,200,500,500],'color','w');
%% 定义坐标区
ax = axes;
ax.XLim = [1 201];
ax.YLim = [1 201];
ax.ZLim = [-53.4 160];
%% 相机视角
view(3);
%% 生成曲面
s = surface(160*membrane(1,100));
s.EdgeColor = 'none';   % 消除网格线
%% 透视投影
camproj('perspective');   % 透视投影
%% 光照
l1 = light;
l1.Position = [160 400 80];
l1.Style = 'local';
l1.Color = [0 0.8 0.8];
l2 = light;
l2.Position = [.5 -1 .4];
l2.Color = [0.8 0.8 0];
%% 材质
s.FaceColor = [0.9 0.2 0.2];
s.FaceLighting = 'gouraud';
s.AmbientStrength = 0.3;
s.DiffuseStrength = 0.6; 
s.BackFaceLighting = 'lit';
s.SpecularStrength = 1;
s.SpecularColorReflectance = 1;
s.SpecularExponent = 7;
%% 清理背景
axis off
f.Color = 'none';

1. 创建窗口:figure()

%% 创建窗口
f = figure('position',[200,200,500,500],'color','w');

2. 定义坐标区:axes

MathWorks.axes:https://ww2.mathworks.cn/help/matlab/ref/axes.html?s_tid=srchtitle

MathWorks.AXES属性:https://ww2.mathworks.cn/help/matlab/ref/matlab.graphics.axis.axes-properties.html

%% 定义坐标区
ax = axes;
ax.XLim = [1 201];
ax.YLim = [1 201];
ax.ZLim = [-53.4 160];

3. 相机视角:view()

视线以图框的中心为起点,指向照相机。MATLAB 使用方位角和仰角这两个角度定义视线。这些角度是在原点位于图框中心的三维坐标系中测量的。

  • 方位角az是 x-y 平面上的极坐标角,正值表示按逆时针方向旋转视点;
  • 仰角el是线-面角,是视线位于 x-y 平面上方(正)或下方(负)的角度。

定义视线向量v:

  • v = [az el]:二元素数组,方位角和仰角。
  • v = [x y z]:三元素数组,从图框中心点到照相机位置所形成向量的 x、y 和 z 坐标。本质上是计算同方向上的单位向量,v 的模不影响。
%% 语法
view(v);   % 根据 v视线向量设置视线
view(dim);   % 默认的2维、3维视角
view(az,el);   % 为当前坐标区设置照相机视线的方位角和仰角
[caz,cel] = view(___);   % 分别返回[x y z]的方位角和仰角

《matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例》

《matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例》

4. 曲面生成:surface()

MathWorks.surface():https://ww2.mathworks.cn/help/matlab/ref/surface.html

%% 生成曲面
s = surface(160*membrane(1,100));

《matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例》在创建曲面对象之后可使用 s 访问并修改其属性。例如,通过设置 EdgeColor 属性来隐藏边。

s.EdgeColor = 'none';   % 消除网格线

《matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例》

5. 正交&透视投影:camproj()

  • 使用透视投影,照相机获得的结果是类似人眼在真实世界中看到的,有“近大远小”的效果;
  • 使用正交投影,照相机获得的结果就像我们在数学几何学课上老师教我们画的效果,在三维空间内平行的线,投影到二维空间中也一定是平行的。
%% 语法示例
f = figure('position',[200,200,1000,500],'color','w');
X=linspace(0,1);
Y=linspace(0,1);
[X,Y]=meshgrid(x,y);
%% 左边透视投影
subplot(1,2,1) 
for i=0:1:1
Z=linspace(i,i);
plot3(X,Y,Z,'b');hold on;
plot3(Y,Z,X,'b');hold on;
plot3(Z,X,Y,'b');hold on;
end
camproj('perspective')
%% 右边正交投影
subplot(1,2,2) 
for i=0:1:1
Z=linspace(i,i);
plot3(X,Y,Z,'b');hold on;
plot3(Y,Z,X,'b');hold on;
plot3(Z,X,Y,'b');hold on;
end
camproj('orthographic')

《matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例》

《matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例》

6. 添加光照:light、lighting算法

  • light 在当前坐标区中创建一个光源,光源仅影响补片和曲面图对象。

  • light(‘PropertyName’,propertyvalue,…) 使用给定属性的指定值创建一个 Light 对象。

  • light(ax,…) 将在由 ax 指定的坐标区中而不是在当前坐标区 (gca) 中创建光源对象。选项 ax 可以位于前面的语法中的任何输入参数组合之前。

  • handle = light(…) 返回创建的 Light 对象。

Light 属性控制 Light 对象的外观和行为。通过更改属性值,可以修改该光源的特定方面。从 R2014b 开始可以使用圆点表示法查询和设置属性。

光源类型(Light.Style),指定为下列值之一:
‘infinite’ (默认)- 将光源放置于无穷远处。利用 Position 属性指定光源发射出平行光的方向。
‘local’ – 将光源放置在 Position 属性指定的位置。光是从该位置向所有方向发射的点源。

光源位置(Light.Position),默认[1 0 1],指定为 [x y z] 形式的三元素向量。以数据单位定义从坐标区原点到 (x, y, z) 坐标的向量元素。光源的实际位置取决于 Style 属性的值。

lighting 选择用于计算 light 对象对当前坐标区中所有 surface 和 patch 对象的影响的算法。但是要使 lighting 命令产生任何影响,必须使用 light 函数创建一个光照对象。

lighting flat 在对象的每个面上产生均匀分布的光照。选择此方法可查看分面着色对像。

lighting gouraud 计算顶点法向量并在各个面中线性插值。选择此方法可查看曲面。

lighting none 关闭光照。

lighting(ax,…) 使用 ax 指定的坐标区,而不是使用当前坐标区。
《matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例》

7. 材质着色、反射

《matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例》

8. 清理背景:axis off

《matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例》

另一个例子:克莱因瓶

《matlab | 绘制有渲染效果的三维曲面常用命令:以matlab logo为例》

%% 创建窗口
f = figure('position',[200,200,500,500],'color','w');

%% 生成克莱茵瓶曲面
% 整体参数
n = 1000;
a = .2;                         
c = .5;                         
t1 = pi/4 : pi/n : 5*pi/4;      
t2 = 5*pi/4 : pi/n : 9*pi/4;    
u  = pi/2 : pi/n : 5*pi/2;
[X,Z1] = meshgrid(t1,u);
[Y,Z2] = meshgrid(t2,u);

% 瓶颈
len = sqrt(sin(X).^2 + cos(2*X).^2);
x1 = c*ones(size(X)).*(cos(X).*sin(X) ...
   - 0.5*ones(size(X))+a*sin(Z1).*sin(X)./len);
y1 = a*c*cos(Z1).*ones(size(X));
z1 = ones(size(X)).*cos(X) + a*c*sin(Z1).*cos(2*X)./len;
handleHndl = surf(x1,y1,z1,X);
hold on;

% 瓶体
r = sin(Y) .* cos(Y) - (a + 1/2) * ones(size(Y));
x2 = c * sin(Z2) .* r;
y2 = - c * cos(Z2) .* r;
z2 = ones(size(Y)) .* cos(Y);
bulbHndl = surf(x2,y2,z2,Y);

%% 光照
axis vis3d
l1 = light;
l1.Position = [160 400 80];
l1.Style = 'local';
l1.Color = [0 0.8 0.8];
l2 = light;
l2.Position = [.5 -1 .4];
l2.Color = [0.8 0.8 0];
l3 = light;
l3.Position = [2 -4 5];
l4 = light;
l4.Position = [2 -4 5];
hold off
shading interp
lighting phong

%% 透视投影
camproj('perspective'); 

%% 相机视角
view(-37,30);

%% 清理背景
axis off
f.Color = 'white';
    原文作者:tiiaan
    原文地址: https://blog.csdn.net/BAR_WORKSHOP/article/details/108267640
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞