动态火焰模拟c程序,按要求修改及解释
时间:10-02
整理:3721RD
点击:
//改渐变为单色火焰,改单像素点为多个像素点组成的大像素点
#include <graphics.h>
#include <conio.h>
#include <time.h>
// 宏常量
#define WIDTH 640
#define HEIGHT 480
#define FIREWIDTH 480//320
#define FIREHEIGHT 300//180
// 全局变量
COLORREF g_Colors[193]; // 火焰色系中使用的全部颜色193?
BYTE g_Fire[FIREWIDTH]; // 火焰数据
BYTE g_Bits[FIREHEIGHT * FIREWIDTH]; // 火焰数据
// 火焰属性
int m_nDecay = 3; // 衰减度,范围 [1, 100],默认 5
int m_nFlammability = 385; // 易燃性,范围 [1, 399],默认 385
int m_nMaxHeat = 192; // 最高热度,范围 [0, 192],默认 192
int m_nSpreadRate = 1; // 传播速率,范围 [1, 100],默认 20
int m_nSize = 450; // 火源宽度,范围 [40, FIREWIDTH],默认 160
int m_nSmoothness = 1; // 平滑度,范围 [0, 5],默认 1
int m_nDistribution =10; // 分布,范围 [0, 10],默认 1
int m_nChaos = 50; // 混沌,范围 [1, 100],默认 50
// 初始化火焰
void InitFire()
{
// 初始化颜色
int r, g, b;
// 默认红色火焰。根据注释选择不同的火焰效果
b = 256+256+255; g = 256+255; r = 255; // 红色火焰
// r = 256+256+255; g = 256+255; b = 255; // 蓝色火焰
// g = 256+256+255; b = 256+255; r = 255; // 绿色火焰
// 生成火焰色系
for(int i = 192; i >= 0; i--)
{
g_Colors[i] = RGB((r > 255) ? 255 : r, (g > 255) ? 255 : g, (b > 255) ? 255 : b);
//g_Colors[i] = RGB( 255, 0, 0);//自己修改的,但是却是蓝色,为什么呢,不应该是红色么?
r = (r > 3) ? (r - 4) : 0;
g = (g > 3) ? (g - 4) : 0;
b = (b > 3) ? (b - 4) : 0;
}
// 置空火焰数组
memset(g_Fire, 0, FIREWIDTH);
memset(g_Bits, 0, FIREWIDTH * FIREHEIGHT);
}
// 画色系(不重要,可去,已屏蔽)
//void DrawColorScheme()
//{
// POINT s[8] = { {0, 450}, {580, 450}, {580, 420}, {610, 420},
// {610, 0}, {639, 0}, {639, 479}, {0, 479} };
// HRGN rgn1 = CreatePolygonRgn(s, 8, WINDING);
// HRGN rgn2 = CreateEllipticRgn(550, 390, 611, 451);
// CombineRgn(rgn1, rgn1, rgn2, RGN_DIFF);
// 定义裁剪区域
//setcliprgn(rgn1); // 设置区域 rgn 为裁剪区
//DeleteObject(rgn1);
//DeleteObject(rgn2);
// 剪裁区画色系
//int c, x, y;
//for (int i = 0; i < 1120; i++)
//{
// c = int(i / 5.8);
// x = (i <= 479 ? 639 : 639 - i + 479);
// y = (i <= 479 ? i : 479);
// setcolor(BGR(g_Colors[c]));
// line(0, 0, x, y);
// }
// 取消裁剪区域
// setcliprgn(NULL);
//}
// 计算火焰的每个点(这里不懂,(rand() & 1如何?究竟怎么实现的,怎么理解)
inline void BurnPoint(BYTE* pRow, BYTE* pNextRow)
{
BYTE* pTarget;
int off = rand() % (m_nDistribution + 1);//分布0-10,m_nDistribution=1,off是0-1随机数
int val = m_nDecay + 1;//m_nDecay衰减度+1即5+1=6
val = rand() % val;//产生0-5的随机数
val = *pNextRow - val;
pTarget = (rand() & 1) ? pRow + off : pRow - off;
*pTarget = (val > 0) ? (BYTE)val : 0;
}
// 计算火焰
void RenderFlame()
{
int xStart, xEnd, x, y;
BYTE* pRow;
BYTE* pNextRow;
xStart = (FIREWIDTH - m_nSize) / 2;//x轴起火点(480-火源宽度160)/2
xEnd = xStart + m_nSize +1;//结束点10+160+1
pRow = g_Bits;//火焰数据?
for (x = 0; x < FIREWIDTH; x++)
{
if (x < (xStart + m_nDistribution) || x >= (xEnd - m_nDistribution))//m_nDistribution分布=1
g_Fire[x] = 0;// g_Fire[FIREWIDTH]
*pRow++ = g_Fire[x];//火焰边缘修改
}
for (y = FIREHEIGHT - 1; y > 0; y--) // y = 0 火焰最大;y++ 火焰变小
{
pRow = (g_Bits + FIREWIDTH * y);
pNextRow = (g_Bits + FIREWIDTH * (y - 1));
if (rand() & 1)
{
for (x = 0; x < FIREWIDTH; x++)
{
BurnPoint(pRow, pNextRow);
pRow++;
pNextRow++;
}
}
else
{
pRow += FIREWIDTH - 1;
pNextRow += FIREWIDTH - 1;
for (x = 0; x < FIREWIDTH; x++)
{
BurnPoint(pRow, pNextRow);
pRow--;
pNextRow--;
}
}
}
if (rand() % (400 - m_nFlammability) == 0)//400-易燃性385=15,即0-14随机数
{
int off = m_nSize - 5;//火源宽度-5=160-5=155
off = rand() % off;//即0-154随机数
off += xStart;
for (x = off; x < off + 5; x++)
g_Fire[x] = 239;//239?
}
for (x = xStart; x < xEnd; x++)
{
if (g_Fire[x] < m_nMaxHeat)//最高热度
{
int val = rand() % m_nChaos + 1;//浑沌50?+1即产生0-50随机数
val -= m_nChaos / 2;
val += m_nSpreadRate;
val += g_Fire[x];//val=val-25+传播速度20+g_Fire[x]
if ( val > m_nMaxHeat)
g_Fire[x] = m_nMaxHeat;
else if (val < 0)
g_Fire[x] = 0;
else
g_Fire[x] = val;
}
else
g_Fire[x] = m_nMaxHeat;
}
if (m_nSmoothness > 0)//平滑度?
{
xStart += m_nSmoothness;
xEnd -= m_nSmoothness;
for (x = xStart; x < xEnd; x++)
{
int val = 0;
for (y = x - m_nSmoothness; y < x + 1 + m_nSmoothness; y++)
val += g_Fire[y];
g_Fire[x] = val / (2 * m_nSmoothness + 1);
}
}
}
// 显示火焰
void PaintFlame(int offset_x, int offset_y)
{
DWORD* pDst = GetImageBuffer(); // 获取显存指针
for(int y = 0; y < FIREHEIGHT; y++)
for(int x = 0; x < FIREWIDTH; x++)
{
COLORREF c = g_Colors[g_Bits[y * FIREWIDTH + x]];//如何设置大一点的像素点
pDst[(offset_y - y) * WIDTH + offset_x + x] = c;
}
FlushBatchDraw(); // 使显存操作生效
}
// 主函数
void main()
{
initgraph(WIDTH, HEIGHT); // 创建绘图窗口
srand((unsigned)time(NULL)); // 设置随机种子
InitFire(); // 初始化火焰
// DrawColorScheme(); // 绘制色系图
while(!kbhit()) // 按任意键退出
{
RenderFlame(); // 渲染火焰
PaintFlame(145, 320); // 显示火焰145,320
Sleep(33); // 延时
}
closegraph();
}
#include <graphics.h>
#include <conio.h>
#include <time.h>
// 宏常量
#define WIDTH 640
#define HEIGHT 480
#define FIREWIDTH 480//320
#define FIREHEIGHT 300//180
// 全局变量
COLORREF g_Colors[193]; // 火焰色系中使用的全部颜色193?
BYTE g_Fire[FIREWIDTH]; // 火焰数据
BYTE g_Bits[FIREHEIGHT * FIREWIDTH]; // 火焰数据
// 火焰属性
int m_nDecay = 3; // 衰减度,范围 [1, 100],默认 5
int m_nFlammability = 385; // 易燃性,范围 [1, 399],默认 385
int m_nMaxHeat = 192; // 最高热度,范围 [0, 192],默认 192
int m_nSpreadRate = 1; // 传播速率,范围 [1, 100],默认 20
int m_nSize = 450; // 火源宽度,范围 [40, FIREWIDTH],默认 160
int m_nSmoothness = 1; // 平滑度,范围 [0, 5],默认 1
int m_nDistribution =10; // 分布,范围 [0, 10],默认 1
int m_nChaos = 50; // 混沌,范围 [1, 100],默认 50
// 初始化火焰
void InitFire()
{
// 初始化颜色
int r, g, b;
// 默认红色火焰。根据注释选择不同的火焰效果
b = 256+256+255; g = 256+255; r = 255; // 红色火焰
// r = 256+256+255; g = 256+255; b = 255; // 蓝色火焰
// g = 256+256+255; b = 256+255; r = 255; // 绿色火焰
// 生成火焰色系
for(int i = 192; i >= 0; i--)
{
g_Colors[i] = RGB((r > 255) ? 255 : r, (g > 255) ? 255 : g, (b > 255) ? 255 : b);
//g_Colors[i] = RGB( 255, 0, 0);//自己修改的,但是却是蓝色,为什么呢,不应该是红色么?
r = (r > 3) ? (r - 4) : 0;
g = (g > 3) ? (g - 4) : 0;
b = (b > 3) ? (b - 4) : 0;
}
// 置空火焰数组
memset(g_Fire, 0, FIREWIDTH);
memset(g_Bits, 0, FIREWIDTH * FIREHEIGHT);
}
// 画色系(不重要,可去,已屏蔽)
//void DrawColorScheme()
//{
// POINT s[8] = { {0, 450}, {580, 450}, {580, 420}, {610, 420},
// {610, 0}, {639, 0}, {639, 479}, {0, 479} };
// HRGN rgn1 = CreatePolygonRgn(s, 8, WINDING);
// HRGN rgn2 = CreateEllipticRgn(550, 390, 611, 451);
// CombineRgn(rgn1, rgn1, rgn2, RGN_DIFF);
// 定义裁剪区域
//setcliprgn(rgn1); // 设置区域 rgn 为裁剪区
//DeleteObject(rgn1);
//DeleteObject(rgn2);
// 剪裁区画色系
//int c, x, y;
//for (int i = 0; i < 1120; i++)
//{
// c = int(i / 5.8);
// x = (i <= 479 ? 639 : 639 - i + 479);
// y = (i <= 479 ? i : 479);
// setcolor(BGR(g_Colors[c]));
// line(0, 0, x, y);
// }
// 取消裁剪区域
// setcliprgn(NULL);
//}
// 计算火焰的每个点(这里不懂,(rand() & 1如何?究竟怎么实现的,怎么理解)
inline void BurnPoint(BYTE* pRow, BYTE* pNextRow)
{
BYTE* pTarget;
int off = rand() % (m_nDistribution + 1);//分布0-10,m_nDistribution=1,off是0-1随机数
int val = m_nDecay + 1;//m_nDecay衰减度+1即5+1=6
val = rand() % val;//产生0-5的随机数
val = *pNextRow - val;
pTarget = (rand() & 1) ? pRow + off : pRow - off;
*pTarget = (val > 0) ? (BYTE)val : 0;
}
// 计算火焰
void RenderFlame()
{
int xStart, xEnd, x, y;
BYTE* pRow;
BYTE* pNextRow;
xStart = (FIREWIDTH - m_nSize) / 2;//x轴起火点(480-火源宽度160)/2
xEnd = xStart + m_nSize +1;//结束点10+160+1
pRow = g_Bits;//火焰数据?
for (x = 0; x < FIREWIDTH; x++)
{
if (x < (xStart + m_nDistribution) || x >= (xEnd - m_nDistribution))//m_nDistribution分布=1
g_Fire[x] = 0;// g_Fire[FIREWIDTH]
*pRow++ = g_Fire[x];//火焰边缘修改
}
for (y = FIREHEIGHT - 1; y > 0; y--) // y = 0 火焰最大;y++ 火焰变小
{
pRow = (g_Bits + FIREWIDTH * y);
pNextRow = (g_Bits + FIREWIDTH * (y - 1));
if (rand() & 1)
{
for (x = 0; x < FIREWIDTH; x++)
{
BurnPoint(pRow, pNextRow);
pRow++;
pNextRow++;
}
}
else
{
pRow += FIREWIDTH - 1;
pNextRow += FIREWIDTH - 1;
for (x = 0; x < FIREWIDTH; x++)
{
BurnPoint(pRow, pNextRow);
pRow--;
pNextRow--;
}
}
}
if (rand() % (400 - m_nFlammability) == 0)//400-易燃性385=15,即0-14随机数
{
int off = m_nSize - 5;//火源宽度-5=160-5=155
off = rand() % off;//即0-154随机数
off += xStart;
for (x = off; x < off + 5; x++)
g_Fire[x] = 239;//239?
}
for (x = xStart; x < xEnd; x++)
{
if (g_Fire[x] < m_nMaxHeat)//最高热度
{
int val = rand() % m_nChaos + 1;//浑沌50?+1即产生0-50随机数
val -= m_nChaos / 2;
val += m_nSpreadRate;
val += g_Fire[x];//val=val-25+传播速度20+g_Fire[x]
if ( val > m_nMaxHeat)
g_Fire[x] = m_nMaxHeat;
else if (val < 0)
g_Fire[x] = 0;
else
g_Fire[x] = val;
}
else
g_Fire[x] = m_nMaxHeat;
}
if (m_nSmoothness > 0)//平滑度?
{
xStart += m_nSmoothness;
xEnd -= m_nSmoothness;
for (x = xStart; x < xEnd; x++)
{
int val = 0;
for (y = x - m_nSmoothness; y < x + 1 + m_nSmoothness; y++)
val += g_Fire[y];
g_Fire[x] = val / (2 * m_nSmoothness + 1);
}
}
}
// 显示火焰
void PaintFlame(int offset_x, int offset_y)
{
DWORD* pDst = GetImageBuffer(); // 获取显存指针
for(int y = 0; y < FIREHEIGHT; y++)
for(int x = 0; x < FIREWIDTH; x++)
{
COLORREF c = g_Colors[g_Bits[y * FIREWIDTH + x]];//如何设置大一点的像素点
pDst[(offset_y - y) * WIDTH + offset_x + x] = c;
}
FlushBatchDraw(); // 使显存操作生效
}
// 主函数
void main()
{
initgraph(WIDTH, HEIGHT); // 创建绘图窗口
srand((unsigned)time(NULL)); // 设置随机种子
InitFire(); // 初始化火焰
// DrawColorScheme(); // 绘制色系图
while(!kbhit()) // 按任意键退出
{
RenderFlame(); // 渲染火焰
PaintFlame(145, 320); // 显示火焰145,320
Sleep(33); // 延时
}
closegraph();
}
请大家看看哦,交流交流,不太理解呢
COLORREF g_Colors[193]这句是设置一堆颜色变量么?那我修改g_Colors[i] = RGB( 255, 0, 0)不应该全是红色么?却是蓝色。g_Colors[i] = RGB( 255, 255, 0)把却是补了矩形框的颜色
由于想要模拟在led显示屏上的效果,所以想把单像素点变大,如何变呢,我不是怎么懂计算火焰每个点那里,我觉得应该在那里改,却不知道如何下手,或许也可以加渲染效果,用一排排小圆渲染,那有怎么办呢?
走过路过交流交流啦,改完之后回馈大家一起学习啦
c程序 相关文章: