用查表法实现对水波的模拟



最近在网上看到个水波摸拟贴子觉得算法可以更快因此自己想出这个查表法模拟大家看看有没有价值

原理
个波长范围内任意点位移disp = sin(dist)*force +disp_center;
这里设水波为正弦波振幅为force,disp_center为振中位移
推广到任何点disp = sin(dist % wave_length)*force + disp_center;
这里wave_length 为波长可以看出在离散数据中任何点位移是有限集合我们先构造出这个集合在运算过程中从集合中选取个位移值就行了而不用实时计算每个点位移

设计如下:取波长为12任何点位移由个12个元素
disp[12];

建立成存贮各点来振中距离
dist[600][800];

下面生成个水波
inline void Build_Disp_Matrix
{
for( i = 0; i < 12; i)
disp[i] = _cast<>(sin((double)i*30*DXPI/360)*PRECISION);
}

void Create_Ripple( center_x, center_y, force, damp, wave_length)
{

for( i = 0 ; i < wave_length; i)
{
disp[i] = force * disp[i] / PRECISION;
}

dist_x, dist_y;
for(i = 0; i < SCREEN_HEIGHT; i)
{
for( j = 0; j< SCREEN_WIDTH; j)
{
dist_y = i - center_y;
dist_x = j - center_x;
dist[i][j] = _cast<>(sqrt(dist_x*dist_x + dist_y*dist_y) + 0.5) % wave_length;
}
}

}

渲染水波代码和原来代码
void Render_Ripple(LPDIRECTDRAWSURFACE7 lpdds)
{
DDSURFACEDESC2 ddsd = { (ddsd) };

(disp_index < 0) disp_index = 12;

--disp_index;

lpdds->Lock(NULL,&ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL);
* lpSrcBuffer = _cast<*>(pBmpBack->GetBitmapBuffer);

pitch = (ddsd.lPitch) >> 1;

* lpBuffer = _cast<*>(ddsd.lpSurface);

left,right,bottom,top;
k = 0,l = 0;
index_x,index_y;
x_off,y_off;
pos1,pos2;
for( i = 1; i < SCREEN_HEIGHT - 2; i)
for( j = 1; j < SCREEN_WIDTH - 2; j)
{
left = right = bottom = top = disp_index;

left dist[i][j -1];
(left > 12) left -= 12;
right dist[i][j+1];
(right >12) right -= 12;
bottom dist[i+1][j];
(bottom > 12) bottom -= 12;
top dist[i-1][j];
(top >12 ) top -= 12;

x_off = disp[left] - disp[right];
y_off = disp[top] - disp[bottom];

index_x = j + x_off;
index_y = i + y_off;

pos1 = i*pitch +j;
pos2 = index_y * 800 + index_x;
(pos2 < 0 || pos2 > 479999) ;

lpBuffer[pos1] = lpSrcBuffer[pos2];
}

pBmpBack->ReleaseBuffer;
lpdds->Unlock(NULL);
}

不知道这样大家都否看懂完整演示
QQ:184383129
有兴趣可以加我QQ细聊

Tags: 

延伸阅读

最新评论

发表评论