我對經典的水波演算法略微做了些擴充套件

2021-04-02 08:15:31 字數 1638 閱讀 3289

這是效果圖注意荷葉邊的效果。

經典的水波演算法:

//能量的擴散

t=waterb[a-mwidth];

b=waterb[a+mwidth];

r=waterb[a+1];

l=waterb[a-1];

watera[a]=((t+b+l+r)>>1)-watera[a];

//能量的衰減

watera[a]-=(watera[a]>>6);

乙個非常重要的依據--能量守恆。

在無阻尼前提下,乙個時間內的所有水分子的能量之和是不變的

上面的能量的擴散就是按照這個原則實現的,感興趣的話看一下

這裡就不再重複了。

watera,waterb是兩個int 陣列,用來儲存和推演波的能量。

什麼樣的波會反射?

簡單的來說我打了老婆十下,老婆也打了我十下這樣就相當與有十下被反射回來了。

當乙個水分子給左邊的水分子的能量被原樣返回時便使得水波想右反**。

當我們計算waterb到a的變換(也就是上乙個時間點和下乙個時間點的波的變換)時,如果該點的波的能量被忽略過去時,該點會保留原來的能量,並把它儲存到了下乙個時間段,然後把自身的能量想周圍擴散。

下面是關鍵部分的**:

for(int a=mwidth;a//邊緣反射

if(a%mwidth==0)

continue;

//根據障礙物計算波的反射

if(this->mbarrier!=null&&this->mbarrier[a*mbarrierbytesperpix]!=0)

continue;

int t,b,l,r;

//能量的擴散

t=waterb[a-mwidth];

b=waterb[a+mwidth];

r=waterb[a+1];

l=waterb[a-1];

watera[a]=((t+b+l+r)>>1)-watera[a];

//能量的衰減

if(m_decayfactor>0)

watera[a]-=(watera[a]>>m_decayfactor);

}color_int *temp=watera;

watera=waterb;

waterb=temp;

int xoff,yoff;

for(int u=1;umheight)

if ((u+xoff )< 0 )

if ((u+xoff )>mwidth )

//計算出偏移象素和原始象素的記憶體位址偏移量

int color;

int backindex=(u+xoff+(v+yoff)*mwidth)*mbarrierbytesperpix;

if(this->mbarrier!=null&&this->mbarrier[backindex]!=0){

color=(mbarrier[backindex]);

for(int i=1;imbackimage:

mbarrier:

對網上流傳的水波演算法的質疑

我在研究你的水波程式時,認真的進行了研究了很長時間,我覺得網上流傳的水波演算法在推理的過程中有一些問題值得商榷。1。你推出公式4a b 1的前提是能量守恆,水波的振幅之和不發生變化.如果真是能量守恆的話,應該是a 1 4,b 0 這是因為該點的能量全部傳給四周,而中心的能量傳出去了。而若取a 1 2...

研究mysqldump對我的資料庫做了哪些操作

usr local mysql55 bin mysqldump uroot s data mysqldata 3306 mysql.sock single transaction default character set gbk test t10 usr tmp testzsd.sql singl...

對經典排序演算法的理解

直接插入排序 為什麼叫直接插入排序呢?書上定義 插入排序 insertion sort 的基本思想是 每趟將乙個元素,按其關鍵字大小插入到它前面已經排序的子串行中,使得插入後的子串行仍然是排序的,依此重複,直到元素全部插入完畢 1 直接 沒有其他過程 2 插入 找到需要插入的位置,直接插入 乙個有n...