You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript实现Penrose铺砌代码性能优化咨询

Penrose铺砌JavaScript代码优化方案

1. 预计算固定角度的三角函数值

Penrose铺砌依赖五边形相关的固定角度(36°、72°、108°等),提前计算并缓存这些角度的sin/cos值,彻底避免重复调用Math.sin()和Math.cos():

// 预计算核心角度的三角函数(弧度制)
const ANGLE_36 = Math.PI / 5;
const ANGLE_72 = 2 * Math.PI / 5;

const SIN_36 = Math.sin(ANGLE_36);
const COS_36 = Math.cos(ANGLE_36);
const SIN_72 = Math.sin(ANGLE_72);
const COS_72 = Math.cos(ANGLE_72);

// 补全反向/补角的三角函数(直接复用已有值)
const SIN_NEG_36 = -SIN_36;
const COS_NEG_36 = COS_36;
const SIN_108 = SIN_72; // sin(180-72)=sin72
const COS_108 = -COS_72; // cos(180-72)=-cos72

2. 用配置化替代冗余条件判断

把每种Tile的绘制规则、衍生逻辑封装到配置对象中,新增Tile只需扩展配置,无需修改大量if-else分支:

// Tile类型配置映射,统一管理绘制与衍生规则
const TILE_CONFIGS = {
  'cyan-pentagon': {
    draw: (pos, size) => {
      const vertices = [];
      for (let i = 0; i < 5; i++) {
        const angle = i * ANGLE_72;
        vertices.push([
          pos[0] + size * Math.cos(angle),
          pos[1] + size * Math.sin(angle)
        ]);
      }
      drawPolygon(vertices, 'cyan');
    },
    derivatives: [
      { type: 'yellow-rhombus', offset: [size => size * COS_36, size => size * SIN_36], scale: 0.8 }
    ]
  },
  'gray-pentagon': {
    draw: (pos, size) => drawPolygon(getPentagonVertices(pos, size), 'gray'),
    derivatives: [
      { type: 'red-pentagon', offset: [size => size * COS_72, size => size * SIN_72], scale: 0.6 },
      { type: 'red-pentagon', offset: [size => size * COS_NEG_36, size => size * SIN_NEG_36], scale: 0.6 },
      { type: 'half-star', offset: [() => 0, () => 0], scale: 1 }
    ]
  }
  // 新增Tile类型直接追加配置
};

// 通用Tile创建函数
function spawnTile(type, pos, size) {
  const config = TILE_CONFIGS[type];
  if (!config) return;

  // 绘制当前Tile
  config.draw(pos, size);

  // 生成衍生Tile
  config.derivatives.forEach(deriv => {
    const derivPos = [
      pos[0] + deriv.offset[0](size),
      pos[1] + deriv.offset[1](size)
    ];
    spawnTile(deriv.type, derivPos, size * deriv.scale);
  });
}

// 通用多边形顶点生成函数(复用逻辑)
function getPentagonVertices(pos, size) {
  const vertices = [];
  for (let i = 0; i < 5; i++) {
    const angle = i * ANGLE_72;
    vertices.push([
      pos[0] + size * Math.cos(angle),
      pos[1] + size * Math.sin(angle)
    ]);
  }
  return vertices;
}

3. 精简变量与复用逻辑

  • 用数组解构简化坐标传递,避免单独声明x/y临时变量:
// 原写法
let x = pos[0];
let y = pos[1];
let newX = x * COS_36 - y * SIN_36;
let newY = x * SIN_36 + y * COS_36;
spawnTile('yellow-rhombus', [newX, newY], size);

// 简化后
const [newX, newY] = rotatePoint(pos[0], pos[1], '36');
spawnTile('yellow-rhombus', [newX, newY], size);
  • 封装通用坐标变换函数,避免重复编写旋转/平移代码:
function rotatePoint(x, y, angleKey) {
  const [sin, cos] = {
    '36': [SIN_36, COS_36],
    '-36': [SIN_NEG_36, COS_NEG_36],
    '72': [SIN_72, COS_72],
    '108': [SIN_108, COS_108]
  }[angleKey];
  return [x * cos - y * sin, x * sin + y * cos];
}

4. 优化碰撞检测与数量统计

  • 用全局Map存储所有已生成的Tile,通过唯一ID避免重复创建,同时快速统计数量:
const activeTiles = new Map();

function spawnTile(type, pos, size) {
  // 生成唯一标识(可优化为更高效的哈希)
  const tileId = `${type}-${pos[0].toFixed(2)}-${pos[1].toFixed(2)}-${size.toFixed(2)}`;
  if (activeTiles.has(tileId)) return;

  // 碰撞检测:复用预计算的Tile边界
  const bounds = getTileBounds(type, pos, size);
  for (const [, existingBounds] of activeTiles) {
    if (isOverlapping(bounds, existingBounds)) return;
  }

  // 绘制与衍生逻辑...

  activeTiles.set(tileId, bounds);
}

// 按类型统计Tile数量
function countTilesByType(type) {
  return Array.from(activeTiles.keys()).filter(id => id.startsWith(type)).length;
}
  • 预计算每种Tile的边界规则,避免每次碰撞检测时重新计算顶点:
function getTileBounds(type, pos, size) {
  // 根据Tile类型返回预定义的边界框(比如五边形的外接矩形)
  return {
    minX: pos[0] - size,
    maxX: pos[0] + size,
    minY: pos[1] - size,
    maxY: pos[1] + size
  };
}

// 简化的轴对齐碰撞检测
function isOverlapping(b1, b2) {
  return b1.minX < b2.maxX && b1.maxX > b2.minX && b1.minY < b2.maxY && b1.maxY > b2.minY;
}

5. 代码精简建议

  • 移除未使用的变量,合并重复的逻辑片段;
  • 用箭头函数简化简短的回调(比如配置中的draw方法);
  • 把重复的顶点计算、颜色设置等逻辑抽成通用工具函数。

内容的提问来源于stack exchange,提问作者visionary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 05:04:49