demo下载

水波纹,鼠标点击后水会四散,产生涟漪的感觉,十分真实.

实现原理:

扩散:当你投一块石头到水中,你会看到一个以石头入水点为圆心所形成的一圈圈的水波,这里,你可能会被这个现象所误导,以为水波上的每一点都是以石头入水点为中心向外扩散的,这是错误的。实际上,水波上的任何一点在任何时候都是以自己为圆心向四周扩散的,之所以会形成一个环状的水波,是因为水波的内部因为扩散的对称而相互 抵消了。 
衰减:因为水是有阻尼的,否则,当你在水池中投入石头,水波就会永不停止的震荡下去。 
水的折射:因为水波上不同地点的倾斜角度不同,所以,因为水的折射,我们从观察点垂直往下看到的水底并不是在观 察点的正下方,而有一定的偏移。如果不考虑水面上部的光线反射,这就是我们能感觉到水波形状的原因。 
反射:水波遇到障碍物会反射。 
衍射:如果能在水池中央放上一块礁石,或放一个中间有缝的隔板,那么就能看到水波的衍射现象了

多说无益,看一下效果图

                                     

这样子看起来还是极好的.

我先要定义两个波能缓冲区

int   *m_pWaveBuf1; //波能缓冲区1
int   *m_pWaveBuf2; //波能缓冲区2

在初始化函数里,波能缓冲区水池图象一样大小的数组

//获取位图宽、高、一行的字节数m_iBmpWidth = stBitmap.bmWidth;m_iBmpHeight = stBitmap.bmHeight;//分配波能缓冲区m_pWaveBuf1 = new int[m_iBmpWidth*m_iBmpHeight];m_pWaveBuf2 = new int[m_iBmpWidth*m_iBmpHeight];

水波扩散函数

void CRipple::WaveSpread()
{int *lpWave1 = m_pWaveBuf1;int *lpWave2 = m_pWaveBuf2;for(int i = m_iBmpWidth; i < (m_iBmpHeight - 1)*m_iBmpWidth; i++){//波能扩散lpWave2[i] = ((lpWave1[i - 1] + lpWave1[i - m_iBmpWidth] +lpWave1[i + 1] + lpWave1[i + m_iBmpWidth]) >> 1) - lpWave2[i];//波能衰减lpWave2[i] -= (lpWave2[i] >> 5);}//交换缓冲区m_pWaveBuf1 = lpWave2;m_pWaveBuf2 = lpWave1;
}

某一时刻,X0点的振幅除了受X0点自身振幅的影响外,同时受来自它周围前、后、左、右四个点(X1、X2、X3、X4)

的影响.这四个点对a0点的影响力可以说是机会均等的。那么我们可以假设这个一次公式为:

X0’=a(X1+X2+X3+X4)+bX0            (公式1)

最终我们得到这个函数

X0’=(X1+X2+X3+X4)/ 2- X0

水在实际中是存在阻尼的,否则,用上面这个公式,一旦你在水中增加一个波源,水面将永不停止的震荡下去。所以,

还需要对波幅数据进行衰减处理,让每一个点在经过一次计算后,波幅都比理想值按一定的比例降低。这个衰减率经过

测试,用1/32比较合适,也就是1/2^5。可以通过移位运算很快的获得。

渲染函数:

在程序中,用一个页面装载原始的图象,用另外一个页面来进行渲染。取得指向页面内存区的指针,然后用根据偏

移量将原始图象上的每一个象素复制到渲染页面上。进行页面渲染.

void CRipple::WaveRender()
{int iPtrSource = 0;int iPtrRender = 0;int lineIndex = m_iBmpWidth;int iPosX = 0;int iPosY = 0;//扫描位图for(int y = 1; y < m_iBmpHeight - 1; y++){for(int x = 0; x < m_iBmpWidth; x++){//根据波幅计算位图数据偏移值,渲染点(x,y)对应原始图片(iPosX,iPosY)
//          iPosX = x + (m_pWaveBuf1[lineIndex - 1] - m_pWaveBuf1[lineIndex + 1]);
//          iPosY = y + (m_pWaveBuf1[lineIndex - m_iBmpWidth] - m_pWaveBuf1[lineIndex + m_iBmpWidth]);//另外一种计算偏移的方法int waveData = (1024 - m_pWaveBuf1[lineIndex]);iPosX = (x - m_iBmpWidth/2)*waveData/1024 + m_iBmpWidth/2;iPosY = (y - m_iBmpHeight/2)*waveData/1024 + m_iBmpHeight/2;if(0 <= iPosX && iPosX < m_iBmpWidth &&0 <= iPosY && iPosY < m_iBmpHeight){//分别计算原始位图(iPosX,iPosY)和渲染位图(x,y)对应的起始位图数据iPtrSource = iPosY*m_iBytesPerWidth + iPosX*3;iPtrRender = y*m_iBytesPerWidth + x*3;//渲染位图,重新打点数据for(int c = 0; c < 3; c++){m_pBmpRender[iPtrRender + c] = m_pBmpSource[iPtrSource + c];}}lineIndex++;}}//设置渲染后的位图SetDIBits(m_hRenderDC, m_hRenderBmp, 0, m_iBmpHeight, m_pBmpRender, &m_stBitmapInfo, DIB_RGB_COLORS);
}

增加波源:

我们必须在水池中加入波源,你可以想象成向水中投入石头,形成的波源的大小和能量与石头的半径和你扔石头的力量都有关系。知道了这些,那么好,我们只要修改波能数据缓冲区m_pWaveBuf1,让它在石头入水的地点来一个负的“尖脉冲”.
void CRipple::DropStone(int x, int y, int stoneSize, int stoneWeight)
{int posX = 0;int posY = 0;for(int i = -stoneSize; i < stoneSize; i++){for(int j = -stoneSize; j < stoneSize; j++){posX = x + i;posY = y + j;//控制范围,不能超出图片if(posX < 0 || posX >= m_iBmpWidth ||posY < 0 || posY >= m_iBmpHeight){continue;}//在一个圆形区域内,初始化波能缓冲区1if(i*i + j*j <= stoneSize*stoneSize){m_pWaveBuf1[posY*m_iBmpWidth + posX] = stoneWeight;}}}
}

这个例子是别人写的,姑且把放出这个链接,让更多的人去学习理解
demo下载

本文参考 http://blog.csdn.net/ghj1976/article/details/3071

水波纹(water ripple)相关推荐

  1. Android5.0水波纹效果ripple实现

    1.如何设置波纹效果 // 波纹有边界 android:background="?android:attr/selectableItemBackground" // 波纹超出边界 ...

  2. 图像处理之水波纹扩散效果(water ripple effect)

    Water Ripple Effect - 水波纹效果 一:原理 模拟水波纹效果,最常见的是sine或者cosn的函数,周期性变化,贴近自然 当水波纹中中间开始向四周扩散的时候,一般都是慢慢的失去能量 ...

  3. Android 水波纹点击效果(Ripple Effect)

    本文介绍的是Android5.0中其中一个炫酷的效果,点击水波纹扩散效果(Ripple Effect). 以下介绍的实现方式都是调用Android5.0的新API,并非自定义实现,所以只支持在Andr ...

  4. android ripple 大小,Android L限制Ripple水波纹范围大小

    Android L限制Ripple水波纹范围大小 Ripple 简介 Android 5.0 之后 google 推出了 Material Design,Botton 默认的触摸反馈会有水波纹涟漪效果 ...

  5. 【安卓R 源码】Ripple 水波纹效果源码

    安卓使用ripple实现点击时的涟漪效果 - 简书 https://www.jb51.net/article/145309.htm Android:RippleDrawable 水波纹/涟漪效果 - ...

  6. Android TabLayout选项卡点击选中Ripple水波纹

    Android TabLayout选项卡点击时候选中的Ripple水波纹 如果要实现自定义的TabLayout选项卡被点击选中时候的水波纹效果,要从xml属性定义中的: app:tabBackgrou ...

  7. android ripple水波纹详解

    Ripple是Material Design(材料设计)中的效果: 虽然在5.0的机型上,会自带Ripple点击效果,但是有时候需要自己更改点击效果: 使用Ripple的关键就是在android:ba ...

  8. canvas水波纹效果_如何使用HTML5 canvas创建水波纹效果

    canvas水波纹效果 Water ripple effect with HTML5. Today we continue JavaScript examples, and our article w ...

  9. Android自定义水波纹动画Layout

    Android自定义水波纹动画Layout 源码是双11的时候就写好了,但是我觉得当天发不太好,所以推迟了几天,没想到过了双11女友就变成了前女友,桑心.唉不说了,来看看代码吧. 展示效果 Hi前辈 ...

最新文章

  1. 学术-数学:哥德巴赫猜想
  2. RDKit | 基于RDKit的指定原子或键高亮
  3. C#数组排序(按列)
  4. 设置Eclipse中的tab键为4个空格的完整方法
  5. 异步社区本周半价电子书(6月11-17日)
  6. 搜狗拼音输入法大头贴新增几个新的模板,欢迎使用.
  7. python数据类型特点_Python 基础数据类型
  8. linux内核跳转到文件系统,Uboot到Kernel到文件系统(Cortex_A9)移植详细文档
  9. js的with语句使用方法
  10. 大数据_MapperReduce_协处理器_类似Mysql的触发器---Hbase工作笔记0024
  11. 测试面试题集-3.生活物品测试:行李箱、电梯、洗衣机
  12. sklearn中的Linear_model的score函数讲解
  13. 三级数据库知识点总结
  14. python代码判断身份证号是男是女
  15. Android JSON:Gson,FastJson解析库的使用和对比分析(1)
  16. 领淘宝优惠券的微信小程序
  17. 微信小程序云开发-微信小程序账号申请及新手环境配置
  18. 2022-2028年全球与中国机身导线行业产销需求与投资预测分析
  19. 利用vbs维护qtp的虚拟对象的坐标
  20. 0基础光缆/光纤熔接教程

热门文章

  1. 天龙八部网单服务器装备修改,【图文教程】手把手教你修改游戏称号、武器外观!!!...
  2. pyecharts从入门到精通-地图专题Map-世界地图和中国城市地图
  3. 仿百度搜索热点列表的实现
  4. Content-Type是什么意思?
  5. 第24节 综合网络配置实验(含IP、RIP、VLAN、VTP、HSRP、ACL、NAT等配置完整命令)——基于PacketTracer8.0仿真实验
  6. 深度学习在智能机器人中的应用
  7. 让字体显得更平滑的CSS方法
  8. 自顶向下深入分析Netty(四)--优雅退出机制
  9. c语言判断一个数是不是质数的n次方,c语言实践 判断一个数是不是素数
  10. 生产订单可用性检查锁定预留库存的配置