You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于C与CSFML的粒子引擎:生成扩散圆形的数学函数咨询

实现粒子向外圆形扩张的数学方案与代码示例

嗨,这个需求用极坐标转笛卡尔坐标的思路就能完美解决——核心就是借助三角函数(正弦sin()和余弦cos())为每个粒子生成不同方向的运动向量,让它们从出生点向圆周的各个方向飞散,自然形成圆形扩张的效果。

核心原理

每个粒子需要一个随机的角度值(范围是0到2π,对应360度),结合你设定的粒子速度,就能计算出X/Y方向的运动分量:

  • 角度theta:决定粒子飞出去的方向
  • 速度speed:控制粒子扩张的快慢
  • 运动向量计算:
    velocity.x = speed * cos(theta)
    velocity.y = speed * sin(theta)
    

完整代码示例(结合CSFML)

首先定义你的粒子结构体,把需求里的属性都封装进去:

#include <SFML/Graphics.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

typedef struct {
    sfVector2f position;    // 粒子位置
    float lifetime;         // 当前剩余生命周期
    float max_lifetime;     // 总生命周期
    sfVector2f velocity;    // 运动向量
} Particle;

// 自定义随机数函数(你原来的my_rand可以替换这里的逻辑)
int my_rand(int a, int b) {
    return a + rand() % (b - a + 1);
}

// 生成count个圆形扩张的粒子
void spawn_circular_particles(Particle particles[], int count, sfVector2f spawn_pos, float min_speed, float max_speed, float max_lifetime) {
    // 初始化随机数种子(只需要在程序开头调用一次,这里放进来是为了示例完整)
    static int seed_initialized = 0;
    if (!seed_initialized) {
        srand(time(NULL));
        seed_initialized = 1;
    }

    for (int i = 0; i < count; i++) {
        // 生成0~2π之间的随机角度
        float theta = (float)rand() / RAND_MAX * 2 * M_PI;
        // 给速度加一点随机变化,让效果更自然
        float speed = (float)rand() / RAND_MAX * (max_speed - min_speed) + min_speed;

        // 初始化粒子属性
        particles[i].position = spawn_pos;
        particles[i].max_lifetime = max_lifetime;
        particles[i].lifetime = max_lifetime;
        // 计算运动向量
        particles[i].velocity.x = speed * cos(theta);
        particles[i].velocity.y = speed * sin(theta);
    }
}

// 更新粒子状态(每一帧调用)
void update_particles(Particle particles[], int count, float delta_time) {
    for (int i = 0; i < count; i++) {
        if (particles[i].lifetime <= 0.f) continue;

        // 根据运动向量更新位置
        particles[i].position.x += particles[i].velocity.x * delta_time;
        particles[i].position.y += particles[i].velocity.y * delta_time;

        // 减少生命周期
        particles[i].lifetime -= delta_time;
    }
}

// 绘制粒子(用CSFML的Vertex数组批量绘制)
void draw_particles(sfRenderWindow* window, Particle particles[], int count) {
    sfVertex vertices[1000]; // 假设最多1000个粒子,根据你的需求调整
    int vertex_count = 0;

    for (int i = 0; i < count; i++) {
        if (particles[i].lifetime <= 0.f) continue;

        // 设置粒子的位置和颜色(这里用生命周期控制透明度,更有层次感)
        float alpha = particles[i].lifetime / particles[i].max_lifetime;
        vertices[vertex_count].position = particles[i].position;
        vertices[vertex_count].color = sfColor_fromRGBA(255, 200, 50, (sfUint8)(alpha * 255));
        vertex_count++;
    }

    // 绘制所有活跃粒子
    sfRenderWindow_drawPrimitives(window, vertices, vertex_count, sfPoints, NULL);
}

额外优化建议

  • 如果想要粒子扩张时带有“爆炸”的层次感,可以让角度的随机分布更密集,或者给不同角度的粒子设置不同的速度衰减;
  • 可以给粒子的运动向量加一点微小的随机扰动,让效果更自然,不会显得太规整;
  • 注意M_PI的定义:有些编译器需要定义_USE_MATH_DEFINES才能使用这个宏,你可以在包含math.h之前加一行#define _USE_MATH_DEFINES。

内容的提问来源于stack exchange,提问作者Navalex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:14:10