c++画图程序 流体的实现



#include <graphics.h>
#include <math.h>
#include <time.h>


#define WIDTH  1024  // 屏幕宽
#define HEIGHT  576   // 屏幕高
#define NUM_MOVERS 600   // 小球数量
#define FRICTION 0.96f  // 摩擦力


// 定义小球结构
struct Mover
{
 COLORREF color;   // 颜色
 float  x,  y;   // 坐标
 float  vX, vY;   // 速度
};


// 定义全局变量
Mover movers[NUM_MOVERS];   // 小球数组
int  mouseX,  mouseY;   // 当前鼠标坐标
int  mouseVX, mouseVY;  // 鼠标速度
int  prevMouseX, prevMouseY;  // 上次鼠标坐标
bool isMouseDown;    // 鼠标左键是否按下
DWORD* pBuffer;     // 显存指针


// 初始化
void init()
{
 // 初始化小球数组
 for (int i = 0; i < NUM_MOVERS; i++)
 {
  movers[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
  movers[i].x   = WIDTH * 0.5;
  movers[i].y   = HEIGHT * 0.5;
  movers[i].vX  = float(cos(float(i))) * (rand() % 34);
  movers[i].vY  = float(sin(float(i))) * (rand() % 34);
 }
 
 // 初始化鼠标变量
 mouseX = prevMouseX = WIDTH / 2;
 mouseY = prevMouseY = HEIGHT / 2;

 // 设置随机种子
 srand((unsigned int)time(NULL));

 // 获取显存指针
 pBuffer = GetImageBuffer(NULL);
}


// 全屏变暗50%
void darken()
{
 for(int i = WIDTH * HEIGHT - 1; i >= 0; i--)
  if (pBuffer[i] != 0)
   pBuffer[i] = RGB(GetRValue(pBuffer[i]) >> 1, GetGValue(pBuffer[i]) >> 1, GetBValue(pBuffer[i]) >> 1);
}


// 绝对延时
void delay(DWORD ms)
{
 static DWORD oldtime = GetTickCount();

 while(GetTickCount() - oldtime < ms)
  Sleep(1);

 oldtime = GetTickCount();
}


// 绘制动画(一帧)
void run()
{
 darken(); // 全屏变暗

 mouseVX    = mouseX - prevMouseX;
 mouseVY    = mouseY - prevMouseY;
 prevMouseX = mouseX;
 prevMouseY = mouseY;
 
 float toDist   = WIDTH * 0.86f;
 float stirDist = WIDTH * 0.125f;
 float blowDist = WIDTH * 0.5f;
 
 for(int i = 0; i < NUM_MOVERS; i++)
 {
  float x  = movers[i].x;
  float y  = movers[i].y;
  float vX = movers[i].vX;
  float vY = movers[i].vY;
  
  float dX = x - mouseX;
  float dY = y - mouseY;
  float d  = (float)sqrt(dX * dX + dY * dY);
  dX = d ? dX / d : 0;
  dY = d ? dY / d : 0;
  
  if (isMouseDown && d < blowDist)
  {
   float blowAcc = (1 - (d / blowDist)) * 14;
   vX += dX * blowAcc + 0.5f - float(rand()) / RAND_MAX;
   vY += dY * blowAcc + 0.5f - float(rand()) / RAND_MAX;
  }
  
  if (d < toDist)
  {
   float toAcc = (1 - (d / toDist)) * WIDTH * 0.0014f;
   vX -= dX * toAcc;
   vY -= dY * toAcc;   
  }
  
  if (d < stirDist)
  {
   float mAcc = (1 - (d / stirDist)) * WIDTH * 0.00026f;
   vX += mouseVX * mAcc;
   vY += mouseVY * mAcc;   
  }
  
  vX *= FRICTION;
  vY *= FRICTION;
  
  float avgVX = (float)fabs(vX);
  float avgVY = (float)fabs(vY);
  float avgV  = (avgVX + avgVY) * 0.5f;
  
  if (avgVX < 0.1) vX *= float(rand()) / RAND_MAX * 3;
  if (avgVY < 0.1) vY *= float(rand()) / RAND_MAX * 3;
  
  float sc = avgV * 0.45f;
  sc = max(min(sc, 3.5f), 0.4f);
  
  float nextX = x + vX;
  float nextY = y + vY;
  
  if  (nextX > WIDTH) { nextX = WIDTH; vX *= -1; }
  else if (nextX < 0)  { nextX = 0;  vX *= -1; }
  if  (nextY > HEIGHT){ nextY = HEIGHT; vY *= -1; }
  else if (nextY < 0)  { nextY = 0;  vY *= -1; }
  
  movers[i].vX = vX;
  movers[i].vY = vY;
  movers[i].x  = nextX;
  movers[i].y  = nextY;
  
  // 画小球
  setcolor(movers[i].color);
  setfillstyle(movers[i].color);
  fillcircle(int(nextX + 0.5), int(nextY + 0.5), int(sc + 0.5));
 }
}


// 主函数
void main()
{
 // 创建绘图窗口
 initgraph(WIDTH, HEIGHT);
 // 启用批绘图模式
 BeginBatchDraw();

 // 初始化
 init();

 // 鼠标消息变量
 MOUSEMSG m;

 while(true)
 {
  // 处理鼠标消息
  while(MouseHit())
  {
   m = GetMouseMsg();

   switch(m.uMsg)
   {
    case WM_MOUSEMOVE:  mouseX = m.x; mouseY = m.y; break;
    case WM_LBUTTONDOWN: isMouseDown = true;    break;
    case WM_LBUTTONUP:  isMouseDown = false;   break;
   }
  }

  // 绘制动画
  run();

  // 显示缓存的绘制内容
  FlushBatchDraw();

  // 延时20 毫秒
  delay(20);
 }

 // 关闭
 EndBatchDraw();
 closegraph();
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值