|

用代码描述自然系统-简单粒子系统01

前面的文章中实现了基本力,并模拟了物体的基本运动规律,本篇博文将基于前面的文章,构建一个简单的粒子系统。

粒子系统

粒子系统在很多领域都有大量应用,小到游戏开发,大到宇宙模拟,本质上都是对最小粒子的模拟,所以实现简单的例子系统非常有用。

本篇博文实现一个简单的系统,初始世界中会随机生成一定数量的粒子,这些粒子满足几点规则:

  • 粒子距离大于 100 时,粒子之间表现为引力;
  • 粒子距离小于 100 时,粒子之间表现为斥力;
  • 整个粒子系统会施加一定的阻力,阻碍粒子的运动;

基于以上规则,实现粒子系统,最终的静止效果如下图所示:

代码实现

有了之前的博文打基础,这个示例实现起来比较简单,就不一一解释了,直接贴代码:

const PWidth = 800, PHeight = 500;
const count = 100;
const radius = 160;
const balls = [];

class Ball {
  constructor(mass) {
    this.mass = mass;
    this.position = createVector(random(PWidth), random(PHeight));
    this.velocity = createVector(0, 0);
    this.color = color(random(180, 255), random(100, 200));
  }

  setColor(color) {
    this.color = color;
  }

  setPosition(position) {
    this.position = position;
  }

  addFore(f) {
    this.velocity.add(f);
  }

  update() {
    this.position.add(this.velocity);
  }

  display() {
    fill(this.color);
    noStroke();
    ellipse(this.position.x, this.position.y, this.mass * 200);
  }
}

function setup() {
  createCanvas(PWidth, PHeight);
  for (let i = 0; i < count; i++) {
    const ball = new Ball(random(0.02, 0.1));
    ball.setColor(color(255, 255, 18, random(100, 255)));
    balls.push(ball);
  }
}

function draw() {
  background(10);
  balls.forEach(ball => {
    const f = ball.velocity.copy().normalize().mult(-0.15 * ball.velocity.mag());
    balls.forEach(op => {
      if (ball === op) return;
      const dist = p5.Vector.dist(op.position, ball.position);
      const force = p5.Vector.sub(op.position, ball.position).normalize().mult((dist - radius) * ball.mass / radius);
      ball.addFore(force);
    });
    ball.addFore(f);
    ball.update();
    ball.display();
  });
}

function mouseClicked() {
  balls[parseInt(random(count))].addFore(p5.Vector.random2D().mult(random(20, 50)));
}

运行效果如下:

单击鼠标左键,可以增加随机扰动。

可以 点击这里 打开新窗口查看效果。

亦或是随机颜色的效果:

可以 点击这里 打开新窗口查看效果。

类似文章