当前位置: 首页 > news >正文

p5.js:模拟 n个彩色小球在一个3D大球体内部弹跳

 向 豆包 提问:编写一个 p5.js 脚本,模拟 42 个彩色小球在一个3D大球体内部弹跳。每个小球都应留下一条逐渐消失的轨迹。大球体应缓慢旋转,并显示透明的轮廓线。请确保实现适当的碰撞检测,使小球保持在球体内部。

cd p5-demo
copy .\node_modules\p5\lib\p5.min.js .
编写  p5_3d_42_balls.html  如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3D Bouncing Balls in Sphere</title>
    <script src="p5.min.js"></script>
</head>

<body>
<script>
    let balls = [];
    let sphereRadius = 200;
    let rotationSpeed = 0.01;

    function setup() {
        createCanvas(800, 600, WEBGL);
        for (let i = 0; i < 42; i++) {
            balls.push(new Ball());
        }
    }

    function draw() {
        background(0);
        rotateX(frameCount * rotationSpeed);
        rotateY(frameCount * rotationSpeed);

        // 绘制大球体
        stroke(255, 100);
        noFill();
        sphere(sphereRadius);

        // 更新并绘制小球
        for (let ball of balls) {
            ball.update();
            ball.display();
        }
    }

    class Ball {
        constructor() {
            this.pos = p5.Vector.random3D().mult(random(0, sphereRadius));
            this.vel = p5.Vector.random3D().mult(random(1, 3));
            this.color = color(random(255), random(255), random(255));
            this.trail = [];
            this.trailLength = 20;
        }

        update() {
            this.pos.add(this.vel);

            // 碰撞检测
            let distanceToCenter = this.pos.mag();
            if (distanceToCenter > sphereRadius) {
                let normal = this.pos.copy().normalize();
                this.vel.reflect(normal);
                // 确保小球回到球体内
                this.pos = normal.mult(sphereRadius - 0.1); 
            }

            // 更新轨迹
            this.trail.push(this.pos.copy());
            if (this.trail.length > this.trailLength) {
                this.trail.shift();
            }
        }

        display() {
            // 绘制轨迹
            for (let i = 0; i < this.trail.length; i++) {
                let alpha = map(i, 0, this.trail.length, 255, 0);
                stroke(this.color.levels[0], this.color.levels[1], this.color.levels[2], alpha);
                if (i > 0) {
                    line(this.trail[i - 1].x, this.trail[i - 1].y, this.trail[i - 1].z, this.trail[i].x, this.trail[i].y, this.trail[i].z);
                }
            }

            // 绘制小球
            fill(this.color);
            noStroke();
            push();
            translate(this.pos.x, this.pos.y, this.pos.z);
            sphere(5);
            pop();
        }
    }
</script>
</body>
</html>

双击打开 p5_3d_42_balls.html 


交互式分形树

  • 描述: 创建一个分形树,用户可以通过鼠标或键盘控制树的生长角度、分支长度等参数。

  • 编写 p5_branch.html  如下

  • <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>p5 branch Example</title>
       <script src="p5.min.js"></script>
    </head>
    <body>
    <script>
    // 创建分形树,用户可以通过鼠标控制树的生长角度、分支长度等参数。
      function setup() {
        createCanvas(800, 600);
        angleMode(DEGREES);
      }
      
      function draw() {
        background(50);
        stroke(255);
        translate(width/2, height);
        branch(map(mouseX, 0, width, 50, 150));
      }
      
      function branch(len) {
        line(0, 0, 0, -len);
        translate(0, -len);
      
        if (len > 4) {
          push();
          rotate(map(mouseY, 0, height, 20, 60));
          branch(len * 0.67);
          pop();
          push();
          rotate(-map(mouseY, 0, height, 20, 60));
          branch(len * 0.67);
          pop();
        }
      }
    </script>
    </body>
    </html>
    

    双击打开 p5_branch.html 


动态波形生成器

  • 描述: 创建一个动态波形,用户可以通过鼠标或键盘控制波形的频率、振幅或颜色。

  • 编写 p5_wave.html  如下

  • <!DOCTYPE html>
    <html lang="en">
    <head>
       <meta charset="UTF-8">
       <meta name="viewport" content="width=device-width, initial-scale=1.0">
       <title>p5 wave Example</title>
       <script src="p5.min.js"></script>
    </head>
    <body>
    <script>
      let angle = 0;
      let amplitude = 100;
      let frequency = 0.02;
      
      function setup() {
        createCanvas(windowWidth, windowHeight);
      }
      
      function draw() {
        background(0);
        noFill();
        stroke(255);
        strokeWeight(2);
      
        beginShape();
        for (let x = 0; x < width; x += 10) {
          let y = height / 2 + sin(angle + x * frequency) * amplitude;
          vertex(x, y);
        }
        endShape();
      
        angle += 0.05;
      }
      
      function mouseMoved() {
        amplitude = map(mouseY, 0, height, 50, 200);
        frequency = map(mouseX, 0, width, 0.01, 0.1);
      }
    </script>
    </body>
    </html>
    

    双击打开 p5_wave.html 

相关文章:

  • MySQL如何给其他账号分配权限?
  • Java基础系列:深入理解八大基本数据类型及避坑指南
  • python 程序一次启动有两个进程的问题(flask)
  • Jetpack Compose — 入门实践
  • 完全日期(日期枚举问题)--- 数学性质题型
  • Linux系统重置密码
  • Kubernetes中的微服务
  • 报表DSL优化,享元模式优化过程,优化效果怎么样?
  • SpringCloud——Consul服务注册与发现
  • powershell@宝塔面板批量建站脚本@批量设置@批量部署伪静态设置
  • 【AD】5-12 Object元素的隐藏与显示
  • c语言操作符
  • 前端项目中export和import的作用
  • 网安知识点
  • 从Manus到OpenManus:多智能体协作框架如何重构AI生产力?
  • 【Linux内核系列】:深入解析输出以及输入重定向
  • 分布式锁—7.Curator的分布式锁一
  • Java为什么是跨平台的
  • 《深度剖析架构蒸馏与逻辑蒸馏:探寻知识迁移的差异化路径》
  • PCB孔的类型及设计规则
  • 格泰网站建设/深圳全网营销系统
  • 国外网站建设素材/关键词优化怎么弄
  • 谷歌英文网站推广/安卓内核级优化神器
  • 苏州 规划建设局网站/怎么制作小程序
  • 网站广告案例/会计培训机构排名
  • dede网站管理系统演示/百度知道官网入口