热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何用Matlab快速画出带有3D渲染效果的复杂曲面

简要地介绍了一下如何用Matlab快速画出带有3D渲染效果的复杂曲面图,包括三维曲面绘制、光线、材质、着色等等控制,以及如何
简要地介绍了一下如何用Matlab快速画出带有3D渲染效果的复杂曲面图,包括三维曲面绘制、光线、材质、着色等等控制,以及如何快速生成简易动画等。

   Matlab是一个很常用的理工科数学软件,我们平常会用它来画一些平面函数或者简单的曲线或者简单的3D平面图,但是通常很少用到它的稍微高级一点的画图功能。这里介绍一些高级渲染功能和画图技巧,先看结果。

写论文中可能会经常遇到这样的事情,想画一些高级点的漂亮的图不知道怎么画。当然我们通常可能会用solidworks, 3dsmax等等软件画这种3D的图,但是Matlab的好处是可以比较容易生成函数控制的复杂3D曲面形状,就比如上面的鸡蛋盒子一样的晶格图形,看似简单,用其他的软件还真的不太容易画。还有比如像下面这样的波浪图。想要画出这样的图,除了通常的一些画图命令外,还需要掌握一些小的tips,下面来逐一介绍。

 

1、 光照设置

以第二个图为例,它的Matlab代码如下

x=-6*pi:pi/100:6*pi;
y=x;
[X,Y]=meshgrid(x,y);
Z=5*(exp(-(X.^2+Y.^2)/100)+exp(-(X.^2+Y.^2)/4)).*cos(sqrt(X.^2+Y.^2));
figure;surf(X,Y,Z);shading flat; axis off;
view(15,45);axis([min(x),max(x),min(y),max(y),-6,12]);colormap(\'summer\');

%光照渲染

light(\'position\',[0,0,20],\'style\',\'local\',\'color\',\'w\');lighting phong;
light(\'position\',[0,0,20],\'style\',\'local\',\'color\',\'w\');lighting phong;

前面四句是定义二元函数,meshgrid函数是将两个一维数组转化为二维数组以便定义二元函数,此时X,Y,Z都是二维矩阵。

figure;surf(X,Y,Z);是画出3D的表面图,但是这个图通常是带有网格的,而且由于定义的数据间隔小,网格也会很密,整张图看起来一片漆黑。因此需要用shading flat命令来去掉这些网格,此时显示的结果如下图所示,可以看到没什么光泽,不是很好看。上面的view命令是用来设置观察的角度的,axis([min(x),max(x),min(y),max(y),-6,12])设置图显示的区域大小,axis off意思是不显示坐标轴,colormap用来选择Matlab自带的一些色调,比如summer、pink、gray、winter等等。

 

最后要介绍的就是light命令了,在Matlab command 窗口输入 help light命令就可以查看light函数的所有性质,读者可以自行查询,这里只介绍它的功能。light(\'position\',[0,0,20],\'style\',\'local\',\'color\',\'w\');lighting phong; 这段命令中,\'position\'是用来设置光源的位置,\'local\'表示光源是局域的光源而不是从无穷远处射来的平行光。lighting phong是设置光照的方式。用两次同样的light命令是提高光照的亮度,使图片看起来色泽更鲜亮。

 

2、着色设置

上面第一张的图中的球可以在极坐标下写出来,这里期待能够实现更复杂的着色控制,比如像下图这样的,所以代码稍微复杂些。

这个图的代码如下:

theta=-pi/2:pi/50:pi/2;
phi=0:pi/50:2*pi;
[Phi,Theta]=meshgrid(phi,theta);
x=R*cos(Theta).*cos(Phi);
y=R*cos(Theta).*sin(Phi);
z=R*sin(Theta);

%着色控制
color=zeros(length(theta),length(phi),3);
color(:,:,1) = cos(Theta)*cos(Theta0).*cos(Phi-Phi0)+sin(Theta)*sin(Theta0); % red
color(:,:,2) = sin(Theta)*sin(Theta0).*cos(Phi-Phi0)+cos(Theta)*cos(Theta0); % green
color(:,:,3) = sin(Theta)*sin(Theta0).*cos(Phi-Phi0); % blue
figure;
surf(x,y,z,color);shading flat;axis off;
view(15,45);axis([-1 1 -1 1 -1 1]);colormap(\'summer\');
light(\'position\',[0,0,20],\'style\',\'local\',\'color\',\'w\');lighting phong;
light(\'position\',[-20,0,0],\'style\',\'local\',\'color\',\'w\');lighting phong;

前面到x,y,z的定义和上面一样,都是定义二元函数。这里唯一的不同点在于color变量的使用,我们可以自定义每个数据点的红、绿、蓝三个颜色的数值,就可以组合出任意的颜色。这样就几乎可以把这个图涂上任意的想要的颜色。曲面形状拓展一下,还可以画一个铁蒺藜的图。

 

3、材质设定

 Material命令是设置3D 表面的材料的,具体点说主要是反射光的性质,它的命令格式为 material([ka kd ks]);分别设置环境光、漫反射、镜面反射的反射程度,ka,kd,ks的值均在0到1之间。组合设置一下可以得到更细腻的3D表面的质感。

 

 从上图可以看到设置material后物体表面对光线的反射会更柔和点。

 

4、透明度设置

 

透明度的设置可以直接通过surf命令surf(x,y,z,color,\'FaceAlpha\',0.3);来设置,这里的\'FaceAlpha\'就是设置面的透明度,数值在0到1之间,0表示完全透明,1表示完全不透明。

 

5、动画控制

最后是动画的控制,Matlab可以直接生成动画,动画的每一帧都是一个图,因此每个图都需要画出来。可以用getframe得到每一帧,用movie函数播放动画。下面有个完整的例子。

x=-6*pi:pi/20:6*pi;
y=x;
[X,Y]=meshgrid(x,y);
loops=200;
for j=1:loops
    Z=5*cos(j/20*pi-sqrt(X.^2+Y.^2)).*(exp(-(X.^2+Y.^2)/100)+exp(-(X.^2+Y.^2)/4));
    surf(X,Y,Z);axis off;shading flat;
    view(15,45);axis([min(x),max(x),min(y),max(y),-6,12]);colormap(\'summer\');
    light(\'position\',[0,0,20],\'style\',\'local\',\'color\',\'w\');lighting phong;
    light(\'position\',[0,0,20],\'style\',\'local\',\'color\',\'w\');lighting phong;
    drawnow;
    F(j)=getframe;
end
movie(F,1,20); % 播放1次,每秒钟20张图

% 将动画存为一个视频文件

aviobj = VideoWriter(\'water wave.avi\');
aviobj.FrameRate = 20;
open(aviobj);
writeVideo(aviobj,F);
close(aviobj);

动画的每一帧是存在F这个变量里的,然后用movie(F,1,20)来播放动画。首先需要用VideoWriter函数建立一个新的视频文件,这个视频文件在Matlab里的操作是一个对象aviobj,我们可以 设置Framerate为20,即每秒钟播放20帧。open(aviobj)和close(aviobj)是打开和关闭文件的操作,writeVideo(aviobj,F)是把F中的动画存在aviobj里,也就是存在water wave.avi文件里,matlab默认生成avi文件。之后打开water wave.avi文件就可以看到生成的动画了。

 

6、总结

 本文介绍了用Matlab画3D 物体和3D表面的一些方法。Matlab的优势是可以非常方便的用函数去构建复杂的3D物体和表面,使得可以非常简单地表达复杂的3D曲面,通过一些材质和光线渲染可以画出比较漂亮的图或者动画。其缺点是这样的图的数据量相对较大,所画的曲面不太容易导出为3D 模型,因此Matlab画这种图的主要作用可能是在科研上,而非画模型上。当然一种解决方案是,直接用Matlab写一个程序直接生成3D模型的数据文件,或许可以实现把Matlab的编程优势与3D建模软件的优势结合在一起,实现更复杂的3D建模。


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
  • 前端开发工程师必读书籍有哪些值得推荐?我们直接进入代码复杂版式设置,如下所示,先写些标签,源码在这个链接里面:https://codepen.io/Shadid ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 如何用UE4制作2D游戏文档——计算篇
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了如何用UE4制作2D游戏文档——计算篇相关的知识,希望对你有一定的参考价值。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 关于extjs开发实战pdf的信息
    本文目录一览:1、extjs实用开发指南2、本 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了在插入,更新或删除操作期间,在实体上找不到属性?相关的知识,希望对你有一定的参考价值。 ... [详细]
author-avatar
xianghuanghaibo
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有