位置: 文档库 > JavaScript > p5.js 毕达哥拉斯树的实现代码

p5.js 毕达哥拉斯树的实现代码

小确幸2025 上传于 2020-01-02 05:02

YPE html>

《p5.js毕达哥拉斯树的实现代码》

毕达哥拉斯树(Pythagoras Tree)是一种基于毕达哥拉斯定理的递归分形结构,通过不断迭代正方形和直角三角形的组合形成树状图案。这种几何图形不仅具有数学美感,还能通过编程实现动态可视化效果。本文将详细介绍如何使用p5.js库实现毕达哥拉斯树的绘制,涵盖从基础结构到交互优化的完整过程。

一、毕达哥拉斯树的数学原理

毕达哥拉斯树的核心构造基于直角三角形的边长关系。假设初始正方形边长为s,在其上方构造一个等腰直角三角形,两条直角边长度均为s,斜边长度为s√2。在斜边两端分别构造两个新正方形,其边长通过相似三角形比例计算得出:

新正方形边长 = s * (√2 - 1) ≈ 0.414s

递归过程持续对每个新正方形重复上述操作,形成层次分明的树状结构。数学上可表示为:

  • 初始层:1个正方形
  • 第n层:2^(n-1)个正方形
  • 总正方形数:2^n - 1

二、p5.js基础环境配置

p5.js是Processing语言的JavaScript实现,适合创建交互式图形。首先需要引入库文件:


或通过npm安装:

npm install p5

创建基础HTML结构:


  毕达哥拉斯树


  


三、核心实现代码

1. 坐标系与初始参数

在p5.js中,坐标系原点默认在左上角,x向右增长,y向下增长。需要调整坐标系使y轴向上增长:

function setup() {
  createCanvas(800, 800);
  angleMode(DEGREES); // 使用角度制
  translate(width/2, height); // 移动原点到画布底部中央
  scale(1, -1); // y轴反转
}

2. 递归函数实现

定义绘制单个正方形的函数:

function drawSquare(x, y, size, angle) {
  push();
  translate(x, y);
  rotate(angle);
  rect(0, 0, size, size);
  pop();
}

完整递归实现:

function drawPythagorasTree(x, y, size, depth, maxDepth) {
  if (depth > maxDepth) return;
  
  // 绘制当前正方形
  drawSquare(x, y, size, 0);
  
  // 计算新正方形位置
  const newSize = size * (Math.sqrt(2) - 1);
  const hypotenuse = size * Math.sqrt(2);
  
  // 左侧分支
  const leftX = x - size/2;
  const leftY = y - size;
  drawPythagorasTree(leftX, leftY, newSize, depth + 1, maxDepth);
  
  // 右侧分支
  const rightX = x + size/2;
  const rightY = y - size;
  drawPythagorasTree(rightX, rightY, newSize, depth + 1, maxDepth);
}

3. 完整绘制函数

整合坐标系调整与递归调用:

function draw() {
  background(255);
  translate(width/2, height);
  scale(1, -1);
  
  const startSize = 100;
  const maxDepth = 8;
  
  drawPythagorasTree(0, 0, startSize, 0, maxDepth);
}

四、优化与增强

1. 颜色渐变效果

根据深度设置不同颜色:

function getColor(depth, maxDepth) {
  const ratio = depth / maxDepth;
  const r = map(ratio, 0, 1, 50, 255);
  const g = map(ratio, 0, 1, 150, 50);
  const b = map(ratio, 0, 1, 200, 100);
  return color(r, g, b);
}

// 修改drawSquare函数
function drawSquare(x, y, size, angle, depth, maxDepth) {
  push();
  translate(x, y);
  rotate(angle);
  fill(getColor(depth, maxDepth));
  noStroke();
  rect(0, 0, size, size);
  pop();
}

2. 交互控制

添加鼠标控制递归深度:

let currentDepth = 5;

function mouseMoved() {
  currentDepth = map(mouseX, 0, width, 2, 12);
  currentDepth = constrain(currentDepth, 2, 12);
}

// 修改draw函数中的调用
drawPythagorasTree(0, 0, startSize, 0, currentDepth);

3. 动画效果

使用帧计数实现生长动画:

let frameCount = 0;
const growthSpeed = 0.05;

function draw() {
  background(255);
  translate(width/2, height);
  scale(1, -1);
  
  const maxDepth = 10;
  const effectiveDepth = min(maxDepth, frameCount * growthSpeed);
  
  drawPythagorasTree(0, 0, 100, 0, effectiveDepth);
  frameCount++;
}

五、完整优化代码

let currentDepth = 5;
let frameCount = 0;
const growthSpeed = 0.05;

function setup() {
  createCanvas(800, 800);
  angleMode(DEGREES);
  textAlign(CENTER);
}

function draw() {
  background(255);
  translate(width/2, height);
  scale(1, -1);
  
  const startSize = 100;
  const maxDepth = 12;
  const effectiveDepth = min(maxDepth, frameCount * growthSpeed);
  
  drawPythagorasTree(0, 0, startSize, 0, effectiveDepth);
  
  // 显示当前深度
  push();
  translate(0, -height/2 + 20);
  scale(1, -1);
  fill(0);
  text(`当前深度: ${floor(effectiveDepth)}`, 0, 0);
  pop();
  
  frameCount++;
}

function mouseMoved() {
  currentDepth = map(mouseX, 0, width, 2, 12);
  currentDepth = constrain(currentDepth, 2, 12);
}

function getColor(depth, maxDepth) {
  const ratio = depth / maxDepth;
  const r = map(ratio, 0, 1, 50, 255);
  const g = map(ratio, 0, 1, 150, 50);
  const b = map(ratio, 0, 1, 200, 100);
  return color(r, g, b);
}

function drawSquare(x, y, size, angle, depth, maxDepth) {
  push();
  translate(x, y);
  rotate(angle);
  fill(getColor(depth, maxDepth));
  noStroke();
  rect(0, 0, size, size);
  pop();
}

function drawPythagorasTree(x, y, size, depth, maxDepth) {
  if (depth > maxDepth) return;
  
  drawSquare(x, y, size, 0, depth, maxDepth);
  
  const newSize = size * (Math.sqrt(2) - 1);
  
  // 左侧分支
  const leftX = x - size/2;
  const leftY = y - size;
  drawPythagorasTree(leftX, leftY, newSize, depth + 1, maxDepth);
  
  // 右侧分支
  const rightX = x + size/2;
  const rightY = y - size;
  drawPythagorasTree(rightX, rightY, newSize, depth + 1, maxDepth);
}

六、性能优化建议

1. 递归深度控制:超过12层可能导致性能下降,建议根据设备性能调整

2. 缓存计算结果:对重复使用的数学计算进行缓存

3. 使用Web Workers:将计算密集型任务移至后台线程

4. 简化渲染:减少每帧的重绘区域

七、扩展应用方向

1. 3D毕达哥拉斯树:使用Three.js实现立体版本

2. 音乐可视化:根据音频频谱调整分支生长

3. 生成艺术:结合随机参数创建独特变体

4. 教育工具:用于几何教学互动演示

关键词:p5.js、毕达哥拉斯树、分形几何、递归算法、JavaScript可视化、交互式图形、数学艺术

简介:本文详细介绍了使用p5.js库实现毕达哥拉斯树的完整过程,涵盖数学原理、基础实现、颜色渐变、交互控制和动画优化等技术要点,提供了从简单结构到复杂交互的渐进式代码示例,适合JavaScript开发者学习分形图形编程。

《p5.js 毕达哥拉斯树的实现代码.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档