基于MFC的雨滴水纹动画模拟
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Micr ocomputer Applica tions V ol.27,No.8,2011开发应用微型电脑应用2011年第27卷第8期文章编号:1007-757X(2011)08-0042-03
基于MFC的雨滴水纹动画模拟
郭瑾,高伟,刘德山,白萧涵
摘要:基于MFC的框架结构仿真实现雨滴三维水纹动画效果。提出利用MFC框架结构和8像素方法实现三维水纹的仿真。首先通过MFC的框架结构降低了编程的难度;其次通过采用8像素方法建立水波数学模型减少了计算工作量;最后通过偏微分方程绘制模拟圆形扩散水纹的效果。实验结果表明,该方法既减少了计算工作量,降低了编程难度又形象逼真的模拟了水纹动画仿真效果,对于在线实时游戏场景、影视动画制作中的雨滴水纹扩散效果的仿真模拟具有实际应用意义。
关键词:MFC;8像素;水纹;仿真模拟
中图分类号:TP311文献标识码:A
0引言
近年来,自然景物的模拟一直是计算机图形学中最具挑战性的问题之一。关于山、水、云、烟、火焰等自然景物的模拟,在计算机动画与游戏、影视艺术、广告设计等各种领域中有着广泛的用途。其中,动态流水效果的场景仿真广泛应用于虚拟现实应用、计算机游戏、数字电影和动画以及科学计算可视化场景中;基于此,水纹的计算机动画仿真得到了广泛关注。
目前,对于水纹的模拟主要分为三种不同的方法:
第一种方法是基于几何模型的方法,主要采用正余弦函数与二次函数线形叠加来模拟水流曲面的方法[1][4],该方法可以满足视觉上的逼真效果,但缺点是不能反映水流的规律以及雨滴圆形水纹的扩散效果。
第二种方法是基于物理模型的方法,以流体物体基本方程Navier Stokes(N-S方程)为基础[2][3],将数值计算和计算机图形学结合在一起,模拟出接近真实的水流动画,缺点是计算量及大,不易保证时性。
第三种方法是基于粒子系统的方法,使用大量的具有一定生命周期的微小粒子来模拟水流的效果[5],这种方法可以很好的模拟瀑布、喷泉和雪的效果,缺点是不能模拟作为一个整体的水波,并且需要不停的刷新粒子的属性,改变其运行状态,才能达到特定的目的。
本文提出了利用MFC框架结构和八像素方法实现三维水纹的模拟,该方法即降低了编程的难度和减少了计算工作量,又具有很强的实时性和真实感。
1基本原理
本文采用八象素的方法建立水波数学模型,利用MFC 的框架结构,编程实现水滴的水纹圆形一圈圈的扩散效果,非常的生动、形象。
1.1建立八像素法的水波数学模型
八像素法的基本原理是把水平面看成一个建立在水面上的二维平面坐标系,水面上任意点(x,y)的坐标和其周围八个点的坐标都是息息相关的,其中任何一点坐标的变动都会影响到四周。由于需要尽可能简便的模拟出水纹波动效果,故仅考虑点(x,y)将被(x-1,y-1)、(x-1,y)、(x-1,y+1)、(x,y+1)、(x+1,y+1)、(x+1,y)、(x+1,y-1)、(x,y-1)影响,从而推导出水波振幅的公式。记当前点(x,y)坐标的水波振幅为F(x,y),下一刻的振幅F′(x,y)将由F(x,y)、F(x-1,y-1)、F(x-1,y)、F(x-1,y+1)、F(x,y+1)、F(x+1,y+1)、F(x+1,y)、F(x+1,y-1)和F(x,y-1)决定,那么设水波振幅公式为:
F′(x,y)=a(F(x-1,y-1)+F(x-1,y)+F(x-1,y+1)+
F(x,y+1)+F(x+1,y+1)+F(x+1,y)+F(x+1,y-1)+F(x,y-1))+bF(x ,y)其中a、b为待定系数。(1)这里假设水的阻力为0,并处于理想状态下。其次,计算机模拟水波效果仅仅考虑某个瞬间状态,如果瞬间状态取得足够好,瞬间状态动能总和为0。在这种理想条件下,水波的总势能保持不变,即所有这些点的振幅的和保持不变,即满足下面的公式:
F′(0,0)+F′(0,1)+F′(1,0)+…+F′(n,n)=F(0,0)+ F(0,1)+F(1,0)+…+F(n,n)(2)理想状态下,若n取无限大,把(1)式代入(2)式,可得到:
(8a+b)F(0,0)+…+(8a+b)F(n,n)=
F(0,0)+…+F(n,n)(3)
任何满足上式的a和b都是式(3)的解。经过大量的计算和实验,得出取a=1/4,b=-1时效果最佳,那么
———————————
作者简介:郭瑾(1974-)女,辽宁大连,辽宁师范大学计算机与信息技术学院,讲师,硕士,研究方向:计算机动画与游戏,软件工程,辽宁,116081高伟(1972-)男,满族,沈阳,辽宁师范大学计算机与信息技术学院,副教授,硕士,研究方向:计算机动画与游戏,虚拟现实,计算机图形学,辽宁,116081
刘德山(1970-)男,沈阳,辽宁师范大学计算机与信息技术学院,副教授,硕士,研究方向:计算机应用及网络,计算机动画与游戏,辽宁,116081白潇晗,(1981-)男,沈阳,辽宁师范大学继续教育学院,助理工程师,学士,研究方向:计算机动画与游戏,计算机应用及网络,辽宁,116029
42
Microcomputer Applications V ol.27,No.8,2011开发应用微型电脑应用2011年第27卷第8期3可以得到水波振幅公式:
F ′(x,y)=(F(x-1,y-1)+F(x-1,y)+F(x-1,y+1)
+F(x,y+1)+F(x+1,y+1)+F(x+1,y)+F(x+1,y-1)+F(x,y-1))/4-F
(x,y)(4)
公式(4)与已往水波数学公式相比,计算量大大减
少,节省了计算的时间,更好的保证了实时性的要求。
1.2水纹扩散方法分析
一滴水滴落入到水平面上将会产生一圈圈的圆形水纹
扩散效果,基于此,落入点可以看成一个单独的像素点,利
用2.1的八像素法建立对应的水波数学模型,如图1
所示:
图1八象素分布图
考虑到水的传播特性,如果我们考虑的是各向同性传播
的水波,那么邻域的形状也应该是各向对称的,严格说来应
该是一个圆形区域,但由于我们所考察的是离散的矩形网
格,无法严格满足圆形的邻域条件;因此实际采用的是如图
2所示的多边形区域。
假设图1中的X 点为圆形水纹扩散的起始点,周围的
8个点顺时针连接起来即被作为由内向外扩散的第一个圆
形水纹,接下来再以这8个点为圆心,采用八像素方法依次
向外扩散,顺时针连接这12个点作为由内向外扩散的第二
个圆形水纹,如图2
所示:
图2八象素扩散分布图
重复上面的8像素扩散方法,既可以产生由内向外扩散
的一圈圈的圆形水纹效果。
实际生活中,水纹的扩散由于受到空气、水平面等阻力
影响,将会逐渐递减消失。这里使用一个阻尼系数模拟这种
变化,这个系数是一个振幅的百分比参数,结合前面的水波
振幅公式,可以轻而易举的计算出振幅衰减的速度,再更新
原点(x,y)的坐标值,如此循环下去,遍历所有的点,即可实
现整体的水纹扩散效果。
2类结构图、主要代码及仿真结果
程序是基于MFC 框架编写的,类结构图如图3所示:CWaterRoutine int m_iWidth;int m_iHeight;BOOL m_bDrawWithLight;int m_iLightModifier;int m_iHpage;int m_density;……public Create(int iWidth,int iHeight);public Render(DWORD*pSrcImage,DWORD*pT argetImage);public CalcWater(int npage,int density);public FlattenWater();public HeightBlob(int x,int y ,int radius,int height,int page);public DrawWaterNoLight(int page,DWORD*pSrcImage,DWORD*pT ar-getImage);……图3CWaterRoutine 结构图水纹产生区域的函数及边界裁减:void CWaterRoutine::HeightBlob(int x,int y,int radius,int height,int page){int rquad;int cx,cy,cyq;int left,top,right,bottom;int *newptr;int *oldptr;if(page ==0){newptr =&m_iHeightField1[0];oldptr =&m_iHeightField2[0];'}rquad =radius *radius;if(x<0)x=1+radius+rand()%(m_iWidth-2*radius-1);if(y<0)y =1+radius+rand()%(m_iHeight-2*radius-1);left=-radius;right=radius;top=-radius;bottom =radius;if(x -radius <1)left -=(x-radius-1);if(y -radius <1)top -=(y-radius-1);if(x +radius >m_iWidth-1)right -=(x+radius-m_iWidth+1);if(y +radius >m_iHeight-1)bottom-=(y+radius-m_iHeight+1);for(cy =top;cy 4