工控实时动画

1.计算机动画的基本原理

计算机动画是采用计算机技术,以一定速率连续播放的由计算生成的静态画面(帧),利用人眼的视觉残留特性,这些画面序列在人眼的视网膜上形成了连续的变化。

对给定的计算机动画应用程序,通常是以每秒更新动画帧的次数即帧速率(fps)来度量其显示能力的。对于较低的帧速率(2fps3fps),人眼看到的动画是从一幅图像突然“跳到”下一幅图像,当帧速率达到15fps(66.7ms)时会有平滑的活动,但能真正产生计算机平滑动画的最小帧速率是30fps,某些视觉模拟程序中,帧速率甚至要维持在60fps以上。实际得到的帧速率受到计算机运算能力和图像的复杂程度以及操作系统性能的影响。同时计算机监视器的刷新频率也会限制眼睛可以得到的帧速率,超出硬件刷新频率的帧速率没有什么实际意义,但这一点在PC上基本不用担心,因为普通计算机监视器的刷新速度在60Hz以上,在其它应用场合则应该留意一下。

2动画分类

2.1按照实现方式有以下几种

2.1.1 实时动画

是一种边画边显示的实时动画技术。主要由“绘制——清除——重绘”的循环操作来完成动画的整个过程。由于清除环节的存在会造成屏幕的闪烁。一般采用双缓冲技术来消除动画的闪烁。这种方法的基本思想是提供两个基本缓冲区,在显示前台缓冲内容中的一帧画面时,后台缓冲正在绘制下一帧画面,当绘制完毕,则后台缓冲内容在屏幕上显示出来。而前台缓冲绘制下一幅画面内容。这样循环反复,屏幕上显示的总是已经画好的图形。这种方法受图形生成速度的制约,图形绘制越复杂,则速度越慢。

2.1.2 非实时动画

在开始播放动画之前,将动画序列的各帧绘制好放在内存或文件中,然后顺序播放各帧页面,从而产生动画效果,其缺点是占用存储量较大且不能实时交互,不能实现实时动画(典型的应用便是多媒体文件)。

2.2按照动画实现效果可分为

2.2.1 2D动画

2D动画处理2D图形,其动作只有水平的X轴向与垂直的Y轴向,传统手工漫画 、插画等都属于2D类。2D动画不需要建立模型,是直接“画”出来的,制作动画时通常直接调用已经存放好的图片。

2.2.2 3D动画

3D动画处理3D图形,其动作内容除了有水平的X轴向与垂直的Y轴向外还有进深的Z轴。3D图形一般是先建立3D模型,然后再投影到显示屏上,3D图形可以包含360度的信息,能从各个角度去表现模型的动作。

2.2.3 2D3D比较

3D动画有非常高的自由度,能够以任意角度来观察模型,可以让模型进行任意方向的动作,这在2D中是实现不了的,但是其计算复杂,需要消耗较多的资源。

相对来说,2D动画自由度小,不需要建模和计算,消耗的资源较少,在屏幕上显示和处理就非常快,而且2D图像可以画的非常精致,把一些细节完美地表现出来。3D虽然也能通过增加多边形来更细致地表现对象,但与2D图像所能达到的最高水准还是差一些。

但是,随着计算机性能的提升以及3D动画技术的发展,2D动画的优势正在逐渐的消失,3D动画正在引起人们越来越多的兴趣。

毕竟我们是生活在一个真实的充满三维物体的三维世界,利用3D技术可以把人和计算机以一种直觉而自然的方式加以统一,3D动画可以应用于仿真、虚拟现实、游戏等等各个方面。医生可以直接查看病人的三维扫描图像,机械工程师可以仿真自己的设计是否达到了运动需求,军事指挥员可以指挥具有真实感的三维飞机、坦克、军舰并进行战斗方案效果分析,看房者可以不必亲临就能看到房子的状况等等。

3. 工业控制场合下的动画

工业控制中,有不少场合需要根据工业现场传回来的数据进行相应的动画显示,需要实时交互动画。

3.1  2D动画

3D动画需要建立模型且进行大量的实时计算,考虑到工业现场的实时性要求,我们倾向于用2D动画来实现。

 实现方案有以下几种

3.1.1 调用多媒体文件

一般说来,多媒体文件是典型的非实时动画,只能顺序播放,难以满足实时和交互需求。但是在程序中可以实现多媒体文件指定时间段的播放、逆序播放以及暂停播放,或者说,可以调用不同的多媒体文件。利用高级语言(例如C++)来实现实时接收串口数据,根据接收到的不同的串口命令,再来实时调用相应的多媒体文件。

应该说,对于动作比较简单的情形,这种方式是可行的,而且对于控制端来说是比较省时省力的。

对于动作比较复杂的情形,如果动作之间是相互独立的,没有相互间的影响,那么可以把多媒体文件进行分割,屏幕上不同的部分调用不同的多媒体文件。例如:要显示两只小鱼在两只水缸中游动的情形,两只水缸没有相互间的遮挡,那么可以把小鱼1在水缸1中游动作为一个多媒体文件在窗口左边显示,再把小鱼2在水缸2中游动作为另一个多媒体文件,如果两个动作间是有相互影响的,有相互的遮挡关系,那么这样的一种方案将是不可行的,可以利用下面 3.1.2 所介绍的调用图片的方法。

附录1详述了如何利用Visual C++MCIWnd控件实现对AVI格式的多媒体文件的实时调用。

Flash动画是其中的一个特例。首先,FLASH中有分层的概念,这使得它可以比较容易的实现零部件间的相互遮挡关系。其次,它利用action script脚本语言实现了一定的交互性——可以利用鼠标和键盘来实时控制动画。但是该脚本语言只是一种简单的交互语言,它并未提供实时通讯接口,例如它并不能实时接收经由串口传过来的动画。如果真的要实现这样的一种控制方式,也许可以借助Visual C++实现,因为Visual C++可以实时接收串口数据,关键是在Visual C++中是否可以控制导入VC中的FLASH动画中的控件,而且这些控件最好能够隐藏以避免误操作。

3.1.2 调用图片

    当某些环境条件下,不支持多媒体控件或者当通过调用媒体控件无法满足需求时,可以通过直接调用图片的方法。

    2D图片,可以构造非常细致的,非常具有表达力的场景图片,大部分的2D动画都是通过调用图片来实现的。

    在图片动画中,可以直接调用整张图片来实现帧动画;还可以进行一些简单的操作,然后再在屏幕上显示出来。这些简单操作主要是指可以在一张图片上叠加另一张图片,然后再一起在屏幕上显示出来,这一点在直接调用多媒体控件实现动画的方案中是做不到的。为了防止屏幕的闪烁,我们仍然采用类似双缓冲的技术——在后台把要进行的图像操作操作完,然后再在前台显示出来。

    图片动画的缺点是如果动作稍微复杂一点,用到的图片就会很多,工作量比较大。另外,还涉及到屏幕分辨率的问题。图片要想不失真的显示出来,最好以图片原来的分辨率来显示,进行图片的缩放或者放大将会影响图片的显示效果。这样,图片的分辨率定好之后,窗口的分辨率也就定了,如果说想要修改一下屏幕的分辨率的话,将是非常困难的。为了不失真的显示图片,所有的图片都要重新绘制一次。

    对于要进行图片叠加实现的图片动画来说,另外一个问题就是坐标的定位问题。图片叠加的时候,必须精确的定位坐标,不然显示效果将会跟想象的有出入。

附录2详述了如何利用Visual C++调用图片实现平面动画。

3.1.3 直接在程序中绘制及控制动画

    应该说,在程序中直接进行图形的绘制,然后进行控制,这样的一种方式将是最直接的和可控制的。但是,一般直接在程序中绘制的图形都是很简单的图形,例如:圆啊,长方体啊,线段啊等,表现力难以与图片媲美(尤其是用专业的平面绘制软件PhotoshopCoreDraw等绘制的图片)。所以,用这种方法实现的2D动画并不多。应该说FLASH也可以算是一种直接在程序中绘制和控制的方法,但是如前所述,它并没有实时通讯的能力,也不太可行。

3.2  3D动画

有些时候2D动画并不能满足实际物体的动作需求。我们可以想象一下用2D动画实现如下情形:要想仿真一个人大臂抬升的动作,假设动作幅度为180°,每隔1°角做一张图片,那么我们需要180张图片;假如在大臂抬升的同时,我们想让小臂也可以动作,动作幅度为180°,仍是每隔1°角做一张图片,那么我们需要180x180张图片;假如在大小臂抬升的同时,我们想让手腕也动作,作幅度为180°,仍是每隔1°角做一张图片,那么我们需要180x180x180张图片。以上只是假设人在一个平面上的动作,假如我们要仿真胳膊和手腕在空间中的任意角度的任意动作,用2D动画来实现几乎是不可能的。

所以在2D动画满足不了需求的时候,我们可以用3D动画来实现。

另外,有些情况下需要3D动画的效果,这时候就必须用3D动画了。

3.2.1 实现方案

我们可以用直接在程序中对模型进行控制的方法来实现3D动画,进一步地,我们可以使用Visual C++OpneGL结合3D MAX建模的方法。

OpenGL是由SGI公司在其GLgraphics library)基础上发展起来的三维图形库,作为三维图形API的标准,它已被广泛地应用于图形与动画绘制、虚拟现实技术和计算机可视化等领域。OpenGL是一个功能强大的三维图形库,它与操作系统无关,可以很容易的移植到支持OpenGL的操作系统上。

OpenGL提供了以下基本操作:绘制基本图元、变换、光照处理、着色、融合、雾化、位图和图像。纹理映射、动画制作等。OpenGL还提供了十几个生成三维实体模型的辅助函数,简单的模型如球体、立方体和圆柱等可以使用这些函数来实现。但是OpenGL没有提供高级命令函数来定义复杂的三维形体,难以满足建立复杂三维实体的需要。

既然我们是制作动画,那就对OpenGL的动画制作功能多做一点介绍。OpenGL中提供了双缓冲技术,可以直接开启从而避免屏幕闪烁;OpenGL提供了深度缓冲技术,开启后会根据坐标值自动实现覆盖、遮挡等空间效果。OpenGL提供了三维模型的平移和旋转函数,理论上讲,可以实现对模型的任意运动控制。

与此同时,一些优秀的3D建模软件,如3D Studio MaxMayaSolidWorks等等,可以很方便的来构造复杂的3D模型,但是在这些3D建模软件中很难进行交互式的程序控制,难以满足实时应用系统的需要。

为此,我们考虑先在3DMAX等建模软件中建立复杂模型,然后在OpenGL中实现对其控制和变换。

OpenGL是一个可移植的,能在微机上实现并且速度很快的3D图形和建模库,使用OpneGL,可以使程序员创建交互式程序来产生三维运动图形。但是OpenGL本身只提供了一系列预封装的图形处理函数,要完成所谓的“OpenGL程序”,必须借助于某种编程语言(Visual C++Delphi等)。本方案中,我们选择了Visual C++

附录3详述了如何利用Visual C++实现OpenGL以及如何把用3D建模软件建立的3D模型文件导入到OpenGL中的具体过程。

3.2.2 使用基于Visual C++OpenGL实现3D动画所遇到的一些问题

3.2.2 .1 OpenGL中的坐标系以及零件的平移和旋转问题

3.2.2 .1.1 OpenGL坐标系

OpenGL中,有两个坐标系,都是左手坐标系,这与通常所用的右手坐标系不太一样,如果稍不留意,会犯下错误,而且有的错误并不易察觉,在这方面我是吃过一次苦头的。

这两个坐标系,一个是全局坐标系,是固定不变的全局坐标系,又称为眼睛坐标系(eye coordinate system),简称ECS,另一个是局部坐标系,是可变的局部坐标系,又称为目标坐标系(object coordinate system),简称OCS。初始条件下,ECSOCS是重合的,我们可以利用glTraslatefglRotatefglScalef函数来实现OCS的平移、旋转和缩放。而我们在OpenGL中所绘制的三维模型正是依赖于OCS的,这样,通过坐标系的平移、旋转和缩放,也就实现了三维模型的平移、旋转和缩放。经过一定的变换后,一般OCSECS不再重合,这时候我们可以利用glLoadIdentity函数来实现OCS的强制复位,强制使OCSECS重合。

3.2.2 .1.2 绕指定轴旋转问题

由上文,用glTraslatef(x,y,z)glRotatef(rotate,x,y,z)函数来实现三维物体的平移和旋转。平移的情况比较简单,旋转的时候,涉及到一个旋转轴的问题。glRotatef函数默认的旋转轴是以ECS的原点为原点,以glRotatef(rotate,x,y,z)函数参数x,y,z指定的(x,y,z)向量。那么,如何让物体绕指定轴旋转呢?

 答案是再glRotatef之前和之后,要调用glTraslatef(a,b,c)glTraslatef(-a,-b,-c)函数,这样做后三维物体显示的时候的位置并没有改变,但是把旋转轴改变了。先平移还是先旋转会产生不同的结果,这在下面会有交代。glTraslatef(a,b,c)中的abc参数又如何获知呢,要获知abc参数,只要获知旋转轴的中心坐标位置就可以了。旋转轴的中心坐标位置可以用求旋转轴上各点平均值的办法来获知,可以参见附录3

3.2.2 .1.3 旋转和平移的顺序问题

    很显然,先旋转后平移和先平移后旋转产生的结果是不相同的,不同点就在旋转轴不同。而且,在OpenGL中,由于旋转和平移的是局部坐标系,先平移还是先旋转正好跟我们平常所想的相反,这一点应该注意。

3.2.2 .2 OpenGL中实现运动控制

OpenGL提供了使三维物体平移和旋转的函数glTranslatefglRotatef,理论上讲,任何三维物体的运动都可以由平移和旋转来达到。但三维物体的运动不是孤立的,是和其它物体的运动相关联的。以一个四连杆机构的运动为例(如图1)。图中的C点和D点固定,连杆d作为主动件向左旋转,将会带动整个机构向左旋转,需要计算出其它件——连杆b及连架杆c相应的运动情况,并且最后的落脚点要落到每个零件平移了多少,绕哪个轴旋转了多少度,因为最后我们是使用glTranslatefglRotatef来达到零件运动的目的的。如果整个机构比较复杂的话,一个主动件的旋转将会引起很多其它从动件的运动,每个从动件的运动都是需要经过计算的。

 

1 四连杆机构

    如果每个零件的计算方法都不一样,整个装配体的运动计算就很麻烦。因此,如果能够考虑一种通用的计算方法,将会减轻程序员的计算思考难度。或者说,如果能够在建立装配体的时候,就能够给零件之间加上相应的约束关系(例如在3D建模软件中,给零件添加相应的约束关系后,各个零件的运动将会受这些约束的制约),将会减轻后面的运动计算难度。这方面的文章不多,在网上见过,关系还没有理顺。

3.2.2 .3OpenGL中实现零部件色彩控制

    其实,运动是一种动画效果,色彩控制也是一种动画效果。在OpenGL中,开启光源后,零件的颜色是由材质特性——对光源的反射特性来决定的。当读入零件模型的同时,也读入了材质特性,所以我们在程序中看到的模型颜色跟3D建模软件中看到的模型颜色差别不大。当需要对某个特定零件进行颜色控制时,必须先取消原来的读入材质特性。设置允许设置零件的材质特性——glEnable (GL_COLOR_MATERIAL)后,我们可以调用glColor3fv(col)来改变所要绘制的零件颜色值(参数中的col既是用RGB表示的材料颜色值)。

3.2.2 .4OpenGL中加入纹理效果

    对于纹理效果,我还不太理解。书上的解释是“3D图形中的2D贴图。例如一面墙,可以看成一个大矩形,然后将一幅墙的照片贴上去”。只是从代码上来看,现在的纹理值都设为0,但是在3D Studio MAX中我注意到可以加入纹理效果,现在的3D模型的显示效果还欠佳,也许加入纹理效果会好些?

3.2.2 .5OpenGL中实现汉字的显示

    OpenGL中,只提供了绘制字符串和操纵字体的最低级的支持,要想显示ASCII字符甚至汉字并不是直接调用一个函数那么简单。幸运的是,我在网上找到一个显示汉字的类,该类支持在屏幕上输出图像文字、3D文字。虽然该类还存在一些问题,例如在显示3D文字的时候,消耗的内存资源是逐渐增加的,这将最终导致系统资源耗尽,但是该类显示图像文字效果还不错,可以设置文字的字体、大小以及在屏幕上的显示位置。

    附录4是该类的源码及一点简单说明。

3.2.2 .6 实时性分析

工业控制场合中,对实时性要求比较高。因此,研究一下如何加快动画的显示速度也是很有必要的,附录5对影响实时性的因素进行了分析。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值