水波纹(water ripple)
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);
}
增加波源:
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)相关推荐
- Android5.0水波纹效果ripple实现
1.如何设置波纹效果 // 波纹有边界 android:background="?android:attr/selectableItemBackground" // 波纹超出边界 ...
- 图像处理之水波纹扩散效果(water ripple effect)
Water Ripple Effect - 水波纹效果 一:原理 模拟水波纹效果,最常见的是sine或者cosn的函数,周期性变化,贴近自然 当水波纹中中间开始向四周扩散的时候,一般都是慢慢的失去能量 ...
- Android 水波纹点击效果(Ripple Effect)
本文介绍的是Android5.0中其中一个炫酷的效果,点击水波纹扩散效果(Ripple Effect). 以下介绍的实现方式都是调用Android5.0的新API,并非自定义实现,所以只支持在Andr ...
- android ripple 大小,Android L限制Ripple水波纹范围大小
Android L限制Ripple水波纹范围大小 Ripple 简介 Android 5.0 之后 google 推出了 Material Design,Botton 默认的触摸反馈会有水波纹涟漪效果 ...
- 【安卓R 源码】Ripple 水波纹效果源码
安卓使用ripple实现点击时的涟漪效果 - 简书 https://www.jb51.net/article/145309.htm Android:RippleDrawable 水波纹/涟漪效果 - ...
- Android TabLayout选项卡点击选中Ripple水波纹
Android TabLayout选项卡点击时候选中的Ripple水波纹 如果要实现自定义的TabLayout选项卡被点击选中时候的水波纹效果,要从xml属性定义中的: app:tabBackgrou ...
- android ripple水波纹详解
Ripple是Material Design(材料设计)中的效果: 虽然在5.0的机型上,会自带Ripple点击效果,但是有时候需要自己更改点击效果: 使用Ripple的关键就是在android:ba ...
- canvas水波纹效果_如何使用HTML5 canvas创建水波纹效果
canvas水波纹效果 Water ripple effect with HTML5. Today we continue JavaScript examples, and our article w ...
- Android自定义水波纹动画Layout
Android自定义水波纹动画Layout 源码是双11的时候就写好了,但是我觉得当天发不太好,所以推迟了几天,没想到过了双11女友就变成了前女友,桑心.唉不说了,来看看代码吧. 展示效果 Hi前辈 ...
最新文章
- 学术-数学:哥德巴赫猜想
- RDKit | 基于RDKit的指定原子或键高亮
- C#数组排序(按列)
- 设置Eclipse中的tab键为4个空格的完整方法
- 异步社区本周半价电子书(6月11-17日)
- 搜狗拼音输入法大头贴新增几个新的模板,欢迎使用.
- python数据类型特点_Python 基础数据类型
- linux内核跳转到文件系统,Uboot到Kernel到文件系统(Cortex_A9)移植详细文档
- js的with语句使用方法
- 大数据_MapperReduce_协处理器_类似Mysql的触发器---Hbase工作笔记0024
- 测试面试题集-3.生活物品测试:行李箱、电梯、洗衣机
- sklearn中的Linear_model的score函数讲解
- 三级数据库知识点总结
- python代码判断身份证号是男是女
- Android JSON:Gson,FastJson解析库的使用和对比分析(1)
- 领淘宝优惠券的微信小程序
- 微信小程序云开发-微信小程序账号申请及新手环境配置
- 2022-2028年全球与中国机身导线行业产销需求与投资预测分析
- 利用vbs维护qtp的虚拟对象的坐标
- 0基础光缆/光纤熔接教程
热门文章
- 天龙八部网单服务器装备修改,【图文教程】手把手教你修改游戏称号、武器外观!!!...
- pyecharts从入门到精通-地图专题Map-世界地图和中国城市地图
- 仿百度搜索热点列表的实现
- Content-Type是什么意思?
- 第24节 综合网络配置实验(含IP、RIP、VLAN、VTP、HSRP、ACL、NAT等配置完整命令)——基于PacketTracer8.0仿真实验
- 深度学习在智能机器人中的应用
- 让字体显得更平滑的CSS方法
- 自顶向下深入分析Netty(四)--优雅退出机制
- c语言判断一个数是不是质数的n次方,c语言实践 判断一个数是不是素数
- 生产订单可用性检查锁定预留库存的配置