生成 p5.js 龙卷风模拟 html

2025-12-19
生成 p5.js 龙卷风模拟 html 展示
思考过程
**Developing a Simulation Plan** I'm now focusing on the particle system. My plan is to start with a basic swirl effect for the visuals. I'll then shape the swirl into a cone, with the bottom narrower. Randomness will be critical. I'm exploring dust and debris effects, too. Motion will include rotation and upward movement. **Analyzing Particle Behavior** I've decided to move forward with the WEBGL implementation, since it gives a more realistic look for the tornado. I'm now looking at how to make the particles behave. I'll need to define their angle, radius, height, speed, size and color. The `Particle` class is the correct solution for this. I'll also start with the most basic effects and add more layers of complexity. **Finalizing Implementation Details** The core structure is now in place. I'm focusing on the `Particle` class with angle, radius, height, speed, size, and color properties, alongside the `setup()` and `draw()` functions. I am now finalizing the calculations for the radius, angle, and height to achieve the desired conical shape and rotational movement. I'm adding `noise()` to the center for a wobble effect, and I have set the particle color to be blue-ish/brown-ish. The last thing to do is determine what to do when particles reach the top, and apply different speeds at varying distances.
这是一个使用 p5.js 实现的 3D 龙卷风模拟效果。它通过大量的粒子旋转、向上移动并逐渐扩大半径来模拟龙卷风的锥形动态,同时加入了简单的噪声(Noise)来模拟龙卷风的不规则摆动。 你可以将以下代码保存为 `index.html`,然后在浏览器中打开即可看到效果。 ```html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>p5.js 龙卷风模拟</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js"></script> <style> body { margin: 0; padding: 0; overflow: hidden; background-color: #111; } canvas { display: block; } .controls { position: absolute; top: 20px; left: 20px; color: white; font-family: sans-serif; pointer-events: none; text-shadow: 1px 1px 2px black; } </style> </head> <body> <div class="controls"> <h2>龙卷风模拟</h2> <p>鼠标移动改变视角</p> </div> <script> let particles = []; const numParticles = 1200; // 粒子数量 function setup() { createCanvas(windowWidth, windowHeight, WEBGL); // 初始化粒子 for (let i = 0; i < numParticles; i++) { particles.push(new Particle()); } } function draw() { background(20, 24, 30); // 轨道控制:根据鼠标位置旋转场景 rotateY(map(mouseX, 0, width, -PI, PI)); rotateX(map(mouseY, 0, height, PI/4, -PI/4)); // 绘制地面阴影感 push(); translate(0, 200, 0); rotateX(HALF_PI); fill(30, 30, 30, 150); noStroke(); ellipse(0, 0, 400, 400); pop(); // 更新和绘制粒子 for (let p of particles) { p.update(); p.show(); } } class Particle { constructor() { this.init(); } init() { // y 从底部 (200) 到顶部 (-400) this.y = random(200, -400); this.angle = random(TWO_PI); this.speed = random(0.05, 0.15); // 旋转速度 this.riseSpeed = random(1, 3); // 上升速度 this.noiseOffset = random(1000); // 颜色:灰褐色系 let c = random(100, 200); this.color = color(c, c - 10, c - 20, random(100, 200)); } update() { // 1. 向上移动 this.y -= this.riseSpeed; // 2. 旋转 this.angle += this.speed; // 3. 核心逻辑:半径随高度变化(锥形) // 越往上,半径越大。y越小(负值),半径越大。 let baseRadius = map(this.y, 200, -400, 10, 250); // 加入一点摆动 (Noise) let wiggle = noise(this.y * 0.01, frameCount * 0.02) * 50; this.currentRadius = baseRadius + wiggle; // 4. 计算 3D 坐标 this.x = cos(this.angle) * this.currentRadius; this.z = sin(this.angle) * this.currentRadius; // 5. 循环:如果飞出顶部,重置到底部 if (this.y < -400) { this.y = 200; this.angle = random(TWO_PI); } } show() { push(); translate(this.x, this.y, this.z); noStroke(); fill(this.color); // 粒子大小随高度微调 let sz = map(this.y, 200, -400, 2, 6); sphere(sz, 4, 4); // 使用简化的球体提高性能 pop(); } } function windowResized() { resizeCanvas(windowWidth, windowHeight); } </script> </body> </html> ``` ### 核心原理解析: 1. **3D 渲染 (`WEBGL`)**: 使用 p5.js 的 WEBGL 模式,可以方便地在三维空间中放置粒子,并实现视角的旋转。 2. **锥形结构**: * 龙卷风的形状是通过 `map(this.y, 200, -400, 10, 250)` 实现的。 * 底部(`y = 200`)半径较小(10像素)。 * 顶部(`y = -400`)半径较大(250像素)。 3. **粒子运动**: * **旋转**: 使用三角函数 `cos(angle)` 和 `sin(angle)` 结合不断增加的半径,使粒子产生螺旋上升的效果。 * **上升**: 每个粒子的 `y` 值不断减小,当到达一定高度后重置到底部,形成持续的流动感。 4. **动态摆动**: 使用 `noise()` 函数对每一层的半径进行偏移,模拟现实中龙卷风晃动、不稳定的质感。 5. **性能优化**: * 使用了 `sphere(sz, 4, 4)`,通过降低球体的细分数(只有4个分段)来保证在粒子数量较多时依然流畅。 ### 如何自定义: * **颜色**: 修改 `this.color` 可以改变龙卷风的颜色(例如改成沙尘暴的黄色或风暴的深蓝色)。 * **粒子数**: 修改 `numParticles`。数量越多效果越浓密,但对电脑性能要求越高。 * **形状**: 修改 `baseRadius` 的映射范围,可以改变龙卷风的“胖瘦”。