1 Star 7 Fork 0

陈一墉 / 整花活_粒子

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
particle.c 6.40 KB
一键复制 编辑 原始数据 按行查看 历史
陈一墉 提交于 2024-04-27 19:00 . 计算排斥力部分微小优化
#include "include.h"
void par_init(void)
{
int __x = 0;
int __y = 15;
for (int i = 0; i < par_num; i++)
{
// 顺序排列
__x += 15;
if (__x + 15 > WIN_W)
{
__x = 15;
__y += 15;
}
particles[i].x = __x; // 随机初始化x坐标
particles[i].y = __y; // 随机初始化y坐标
particles[i].vx = 0; // 随机初始化x方向速度
particles[i].vy = 0; // 随机初始化y方向速度
particles[i].ax = 0; // 初始化x方向加速度
particles[i].ay = 0; // 初始化y方向加速度
particles[i].R = (rand() % 200) / 256.0f; // 随机初始化颜色R
particles[i].G = (rand() % 200) / 256.0f; // 随机初始化颜色G
particles[i].B = (rand() % 200) / 256.0f; // 随机初始化颜色B
}
}
struct regional regionals[REGIONAL_Y][REGIONAL_X];
void calculate_regional_acc(void)
{
int x, y;
struct regional *p;
p = &regionals[0][0];
memset(regionals, 0, sizeof(regionals));
for (int i = 0; i < par_num; i++)
{
x = particles[i].x / GridRatio;
y = particles[i].y / GridRatio;
if (x >= 0 && x <= REGIONAL_X - 1 &&
y >= 0 && y <= REGIONAL_Y - 1)
{
regionals[y][x].par_num++;
}
}
for (int j = 0; j < sizeof(regionals) / sizeof(struct regional); j++)
{
if (p[j].par_num == 0)
{
continue;
}
for (int i = 0; i < sizeof(regionals) / sizeof(struct regional); i++)
{
int jx, jy;
int ix, iy;
int dx, dy;
float dis_2;
if (!p[i].par_num || j == i)
{
continue;
}
jy = j / REGIONAL_X;
jx = j % REGIONAL_X;
iy = i / REGIONAL_X;
ix = i % REGIONAL_X;
dx = (jx - ix) * GridRatio;
dy = (jy - iy) * GridRatio;
dis_2 = dx * dx + dy * dy;
p[i].ax += p[j].par_num * -5 * dx / dis_2;
p[i].ay += p[j].par_num * -5 * dy / dis_2;
}
}
}
void calculate_exclusion(float dx, float dy, float distance_2, float distance, Particle *particle)
{
float exclude_ax; // 排斥作用的加速度x
float exclude_ay; // 排斥作用的加速度y
if (distance_2 < distance * distance) // 距离比对
{ // 只计算小于distance距离内的粒子
double dis_8 = pow(distance_2, 4); // 计算距离的8次方
exclude_ax = 20000000000 * dx / dis_8; // 计算x排斥力
exclude_ay = 20000000000 * dy / dis_8; // 计算y排斥力
exclude_ax = LIMIT(exclude_ax, -MAX_A, MAX_A); // 限制x排斥力大小
exclude_ay = LIMIT(exclude_ay, -MAX_A, MAX_A); // 限制y排斥力大小
particle->ax += exclude_ax; // 合并x排斥力加速度
particle->ay += exclude_ay; // 合并y排斥力加速度
}
}
void calculate_acceleration(int start, int end)
{
for (int j = start; j < end; j++)
{
float dx; // 两个粒子之间的x距离
float dy; // 两个粒子之间的y距离
float distance_2; // 两个粒子之间距离的平方
particles[j].ax = xa_g; // 初始x加速度
particles[j].ay = ya_g; // 初始y加速度
for (int i = 0; i < par_num; i++)
{
if (i == j) // 跳过计算相同的粒子
{
continue;
}
// 计算加速度
dx = particles[j].x - particles[i].x; // 计算两个粒子之间的x距离
dy = particles[j].y - particles[i].y; // 计算两个粒子之间的y距离
distance_2 = dx * dx + dy * dy; // 计算两个粒子之间距离的平方
if (distance_2 < 0.01) // 防止两个球距离太近
{ // 和防止两个球位置一样导致排斥力与吸引力无穷大的尴尬情况
particles[j].x += 0.01 * ((rand() % 100) + 10); // 微小随机偏移x位置
particles[j].y += 0.01 * ((rand() % 100) + 10); // 微小随机偏移y位置
dx = particles[j].x - particles[i].x; // 重新计算x的差距
dy = particles[j].y - particles[i].y; // 重新计算y的差距
distance_2 = dx * dx + dy * dy; // 计算距离的平方
} // 距离太近时两个球会出现类似炸开的效果 (离谱)
particles[j].ax += -5 * dx / distance_2; // 计算x吸引力
particles[j].ay += -5 * dy / distance_2; // 计算y吸引力
calculate_exclusion(dx, dy, distance_2, 30, &particles[j]); // 计算排斥力
}
dx = particles[j].x; // 计算粒子到左边界的距离
dy = 0; // 留空
distance_2 = dx * dx + dy * dy; // 计算距离的平方
calculate_exclusion(dx, dy, distance_2, 30, &particles[j]); // 计算排斥力
dx = particles[j].x - WIN_W; // 计算粒子到右边界的距离
dy = 0; // 留空
distance_2 = dx * dx + dy * dy; // 计算距离的平方
calculate_exclusion(dx, dy, distance_2, 30, &particles[j]); // 计算排斥力
dx = 0; // 留空
dy = particles[j].y; // 计算粒子到上边界的距离
distance_2 = dx * dx + dy * dy; // 计算距离的平方
calculate_exclusion(dx, dy, distance_2, 30, &particles[j]); // 计算排斥力
dx = 0; // 留空
dy = particles[j].y - WIN_H; // 计算粒子到下边界的距离
distance_2 = dx * dx + dy * dy; // 计算距离的平方
calculate_exclusion(dx, dy, distance_2, 30, &particles[j]); // 计算排斥力
}
}
void calculate_location(void)
{
// 遍历所有粒子
for (int j = 0; j < par_num; j++)
{
// 处理边界碰撞
// 如果粒子在边界内部,则保持原速度与加速度方向不变;如果粒子在边界外部,则速度与加速度方向取反
particles[j].vx = ((particles[j].x < 0 && particles[j].vx < 0) || particles[j].x > WIN_W && particles[j].vx > 0) ? (-particles[j].vx) : (particles[j].vx);
particles[j].vy = ((particles[j].y < 0 && particles[j].vy < 0) || particles[j].y > WIN_H && particles[j].vy > 0) ? (-particles[j].vy) : (particles[j].vy);
particles[j].ax = ((particles[j].x < 0 && particles[j].ax < 0) || particles[j].x > WIN_W && particles[j].ax > 0) ? (-particles[j].ax) : (particles[j].ax);
particles[j].ay = ((particles[j].y < 0 && particles[j].ay < 0) || particles[j].y > WIN_H && particles[j].ay > 0) ? (-particles[j].ay) : (particles[j].ay);
// 模拟粒子运动
// 根据加速度更新速度,再根据速度更新位置
particles[j].vx += particles[j].ax * TIME_DT; // 计算速度
particles[j].vy += particles[j].ay * TIME_DT; // 计算速度
particles[j].vx *= 0.995; // 添加阻尼,减小速度
particles[j].vy *= 0.995; // 添加阻尼,减小速度
particles[j].x += particles[j].vx * TIME_DT; // 计算位置
particles[j].y += particles[j].vy * TIME_DT; // 计算位置
}
}
C
1
https://gitee.com/cyyforchenyiyong/whole-flower-activity-particle.git
git@gitee.com:cyyforchenyiyong/whole-flower-activity-particle.git
cyyforchenyiyong
whole-flower-activity-particle
整花活_粒子
master

搜索帮助