p5.js 代码示例:模拟树木生长
这段代码使用 p5.js 库模拟树木生长,通过粒子系统和递归算法,实现简单的树木分支结构。
- 定义粒子类 Particle,包括粒子位置 pos 和速度 vel 两个属性,以及 update 方法用于更新粒子位置。
class Particle {
constructor(x, y) {
this.pos = createVector(x, y);
this.vel = createVector(0, 0);
}
update() {
this.pos.add(this.vel);
}
}
- 定义树节点类 Node,包括节点位置 pos 和粒子 particle 两个属性,以及 addChild 方法用于添加子节点。
class Node {
constructor(x, y, particle) {
this.pos = createVector(x, y);
this.particle = particle;
this.children = [];
}
addChild(child) {
this.children.push(child);
}
}
- 定义树类 Tree,包括根节点 root 和 addNode 方法用于添加新的节点。
class Tree {
constructor(x, y, particle) {
this.root = new Node(x, y, particle);
}
addNode(parent, child) {
parent.addChild(child);
}
}
- 初始化树和粒子,以及定义生长规则。这里的生长规则是:每个粒子在每一帧被施加一个向上的力,同时如果粒子的速度小于一定值,就会生成一个新的粒子作为子节点,同时将速度清零。
let tree;
let particles = [];
function setup() {
createCanvas(400, 400);
let rootParticle = new Particle(width / 2, height);
tree = new Tree(width / 2, height, rootParticle);
particles.push(rootParticle);
}
function draw() {
background(220);
let newParticles = [];
for (let i = 0; i < particles.length; i++) {
let particle = particles[i];
// 施加向上的力
particle.vel.add(createVector(0, -0.1));
// 更新粒子位置
particle.update();
if (particle.vel.mag() < 1) {
// 生成新的粒子作为子节点
let childParticle = new Particle(particle.pos.x, particle.pos.y);
let childNode = new Node(particle.pos.x, particle.pos.y, childParticle);
tree.addNode(tree.root, childNode);
// 将速度清零
particle.vel.mult(0);
childParticle.vel.mult(0);
newParticles.push(childParticle);
}
}
particles = particles.concat(newParticles);
// 绘制树
stroke(0);
noFill();
drawTree(tree.root);
}
function drawTree(node) {
for (let i = 0; i < node.children.length; i++) {
let child = node.children[i];
line(node.pos.x, node.pos.y, child.pos.x, child.pos.y);
drawTree(child);
}
}
这个代码需要在 p5.js 的开发环境中运行,可以在以下链接中找到 p5.js 的编辑器:https://editor.p5js.org/
原文地址: https://www.cveoy.top/t/topic/oj6s 著作权归作者所有。请勿转载和采集!