用虎克定理来近似模拟水波波动效果

原创 2004年06月23日 01:38:00

水波演示程序:

ScreenShot

    这个水波模拟程序和其它常见的算法不太一样。这是用虎克定理来近似模拟水波波动的。具体的算法如下。

    我们知道,当水面是平静的是时候。也就是说水面各点处于平衡位置时候。水面上的任何点的受力都是平衡的。但是有任何的扰动发生,就会有点偏离平衡位置。受力也就会不平衡,即会产生加速度。由于这些点受力是遵守虎克定理的,如果知道某一刻水面的状态,理论上,我们可以精确的计算出任何时候的水面状态(外干扰为0)。

  当然在我们的程序里,计算是不需要精确的。否则我们得建立复杂的微分方程……。我们在这里做如下的假设:一)水面上的点是离散的。二)一个点在dt的时间里受力是相同的。三)一个点受力只和周围的8个点有关。有了这样的三个假设,我们就可以建立我们的物理近似模型了。

   首先,我们来计算一个点的受力和他们周围点的位置的关系。设某个时刻S点的位移为S,速度为Vs

                           

S点的受力 Fs = k * b * [(B1+B2+B3+B4) - 4 * S ] + k * a * [(A1+A2+A3+A4)-4*S]k为虎克系数。a,b分别是两种距离点上的权系数。(距离不一样,效果当然不一样了。)

所以在这一刻,S 点的加速度就是 a = Fs * dm   (dm是水的质量。)。 下个时刻S点的速度就是Vs2 = Vs - a * dt   (dt为时间间隔)。下个时刻的惟一为 S2 = S + Vs2  * dt (dt为时间间隔)。

   一切都准备好了。现在该是我们实现程序的时候了。水面上的点的位移可以由一个数组来保存起来。我们需要两个数组来保存位移,一个保存当前的位移,一个用来计算下一刻的位移(计算的时候要用到当前的位移)。同时还要有一个数组来保存当前的速度。在程序里,我们计算加速度的时候,可以把dt假设成1。这样可以提高速度。同时可以把dm*k当成一个数就可以了。注意的是,如果这些常数取的不好,就得不到你想要的结果。在我的程序里,dm*k=1b=1。a=3。dt=1。其次我们还要对水波进行衰减,不然你的水波就停不下来了:-)。水波的扩散具体的代码如下:

void RippleSpread()
{
    for(int y=1;y<H-1;y++)
        for(int x=1;x<W-1;x++)
        {
            int a =( 16*pBack[y][x]-
                    (3*pBack[y-1][x]+
                     3*pBack[y+1][x]+
                     3*pBack[y][x-1]+
                     3*pBack[y][x+1]+
                     1*pBack[y-1][x-1]+
                     1*pBack[y-1][x+1]+
                     1*pBack[y+1][x+1]+
                     1*pBack[y+1][x-1])
                    )/16;
            pV[y][x] -= a;//计算下一刻的速度
            pV[y][x] -= pV[y][x]>>6;//速度的自动衰减
            pFront[y][x] =pBack[y][x] + pV[y][x];//下一刻的位移
            pFront[y][x]-= pFront[y][x]>>8;//位移的衰减
         }
    //交换缓冲区
    int (*pTemp)[W]=pFront;
    pFront=pBack;
    pBack=pTemp;
}

最后,我们要根据水面位移的数据来渲染水波。我们知道水面波动后,是有坡度的,我们真正好可以用坡度扭曲图象来产生水波的效果。做法如下。对水面上的任何一个点(X,Y)。算出offsetX和offsetY。然后把图象中(X+offsetX,Y+offsetY)里的数据拷贝到该位置就可以了。这里给出了渲染的代码:

void RenderRipple()
{
    int xoff,yoff,nx,ny;
    COLOR cl;
    DRAWSTRUCT ds;
    DRAWSTRUCT dst;
    BeginDraw(&dst,lpDDS_Texture);
    BeginDraw(&ds,lpDDS_Back);
    for(int y=1;y<H-1;y++)
    {
        for(int x=1;x<W-1;x++)
        {
            xoff=pFront[y][x+1]-pFront[y][x-1];
            yoff=pFront[y-1][x]-pFront[y+1][x];
            nx=x+xoff/10;
            ny=y+yoff/10;
            if(nx>=W) continue;
            if(nx<0) continue;
            if(ny>=H) continue;
            if(ny<0) continue;
            GetColor(dst,nx,ny,&cl);
            SetColor(ds,x,y,&cl);
        }
     }
    EndDraw(lpDDS_Texture);
    EndDraw(lpDDS_Back);
}

android:模拟水波效果的自定义View

Github地址:https://github.com/nuptboyzhb/WaterWaveView欢迎Fork,欢迎Star1.先看效果2.再看关键代码描绘函数y = Asin(wx+d)+of...
  • NUPTboyZHB
  • NUPTboyZHB
  • 2015年03月31日 16:58
  • 2426

Android开发技术点4——模拟声纹波动效果

最近在做声纹相关的东西,在画页面时,因为设计不在家,所以就在即琢磨着,突发奇想的如果能模拟声纹波动的效果,岂不是很形象,所以在这边做了个模拟声纹波动的动画,但是首先声明,不是真的检测外部的声音而实时波...
  • dong19870625
  • dong19870625
  • 2016年08月20日 16:11
  • 1154

对水波特效实现原理的解释

 声明:这个特效不是我原创的,当然我也不知道这个特效的最初制作者是谁。我仅仅试图解释这个水波特效实现的原理。 我曾经从vchelp网站下载过这样一个水波特效的demo(c#写的),当我第一...
  • pizi0475
  • pizi0475
  • 2015年09月15日 21:51
  • 1701

仿Android5.0点击水波效果

本文参考自:点击打开链接 和点击打开链接 package Views; import android.content.Context; import android.graphics.Canv...
  • gaitiangai
  • gaitiangai
  • 2016年07月07日 15:23
  • 793

【UnityShader】波动效果

波动实例: y=  Asin(ωx+φ) φ:决定波形与X轴位置关系或横向移动距离 ω:决定周期( A:决定峰值(纵向拉伸压缩的倍数) Shader "Hidden/test1" {...
  • Naruto_Hinata_
  • Naruto_Hinata_
  • 2018年01月07日 17:12
  • 60

[OpenGL] 动态的水面模拟

真实的水面模拟在三维游戏领域一直是一个非常热门的问题,因为在大型的场景中,流体总是不可避免地会存在的。在这一方面,我也查了不少资料,总结而言,水面模拟一般有这么几个方法:         1.比较简单...
  • ZJU_fish1996
  • ZJU_fish1996
  • 2016年08月25日 20:53
  • 4707

解释水波特效处理

这篇博文译自以下这篇文章——http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/the-...
  • pizi0475
  • pizi0475
  • 2015年10月03日 07:13
  • 1169

万能近似定理(universal approximation theorrm)

神经网络的架构(architecture)指网络的整体结构。大多数神经网络被组织成称为层的单元组,然后将这些层布置成链式结构,其中每一层都是前一层的函数。在这种结构中,第一层由下式给出: 第二层:...
  • guoyunfei20
  • guoyunfei20
  • 2017年10月19日 19:07
  • 433

水波的模拟

(精品技术文摘)水波的模拟 original writer:Imagic 2001-3-5 序(by EmilMatthew):这是一篇非常老的技术文档,但是时间的流逝却无法抹去此文作为精品技术文...
  • pizi0475
  • pizi0475
  • 2015年10月03日 07:22
  • 1697

教程[AGAL海底波纹和反光特效]

AGAL海底波纹和反光特效 这是从HLSL转过来的效果,具体的AGAL我就不解释了,注释里有详细的说明,或者参考AGAL点光源和AGAL红蓝3D,里面对每一行的AGAL都有详细的解释,框架也...
  • wkyb608
  • wkyb608
  • 2012年09月17日 19:40
  • 933
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用虎克定理来近似模拟水波波动效果
举报原因:
原因补充:

(最多只允许输入30个字)