c++画图程序 流体的实现
2015-04-27 12:34
393 查看
#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();
}
#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();
}
相关文章推荐
- NFA-DFA(c++实现代码c#实现画图)
- Android开发 通过JNI实现JAVA与C/C++程序间的调用和回调
- 【转载】C++实现在桌面创建程序的快捷方式
- PAT程序设计考题——甲级1094(The largest generation) C++实现
- 从易到难编写C++程序,(8)问题:实现一个矩阵类
- C++中map容器实现单词转换的程序
- 采用C++的ACE库实现的一个通用的C/S架构通信程序
- init.rc文件里面启动c++程序,通过jni调用java实现
- 基于KMP算法的路径下文本查询程序的c++实现2.0版
- PAT程序设计考题——甲级1066(Root of AVL Tree ) C++实现
- C++实现五子棋小程序
- C++ 实现多语言程序开发研究与Xtreme ToolkitPro的使用(一)
- C++程序的编写和实现
- C++程序代写实现HashSet class
- Ping程序C++实现
- DSP 2812: 使用C++实现的SCI从动站程序框架
- C++--如何实现SDI程序使用CSplitterWnd创建的多个视图的动态地显示和关闭视图
- 兴趣学习: opencv 实现画图程序
- C++之程序时间统计类实现
- 采用C++的ACE库实现的一个通用的C/S架构通信程序(最终版)