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

不规则/规则图形生成需求:边长单位转换与精准标注实现

图形生成与精准标注实现方案

需求梳理

  • 生成包含规则、不规则多边形的图形集合
  • 边长数值精准标注在对应边的合适位置
  • 单位从厘米(cm)转换为米(m)
  • 图形与标注布局协调,避免重叠或错位

优化后的实现代码

JavaScript 逻辑

// 生成单个随机图形(规则/不规则)
function generateSingleShape(isRegular = false) {
  const containerSize = 200;
  let svg = `<svg width="${containerSize}" height="${containerSize}" viewBox="0 0 ${containerSize} ${containerSize}" class="shape">`;
  const centerX = containerSize / 2;
  const centerY = containerSize / 2;
  const sides = Math.floor(Math.random() * 4) + 3; // 生成3-6条边的图形
  let points = [];
  let currentX = centerX;
  let currentY = centerY - 60;
  let currentAngle = -Math.PI / 2;

  // 生成边长:规则图形所有边等长,不规则图形用随机边长
  const baseLength = Math.floor(Math.random() * 20) + 15;
  const sideLengths = isRegular 
    ? Array(sides).fill(baseLength)
    : Array.from({length: sides}, () => Math.floor(Math.random() * 20) + 10);

  // 计算每个顶点坐标
  sideLengths.forEach(length => {
    points.push(`${currentX},${currentY}`);
    // 推导下一个顶点位置
    currentX += length * Math.cos(currentAngle);
    currentY += length * Math.sin(currentAngle);
    currentAngle += (Math.PI * 2) / sides;
  });

  // 闭合图形
  points.push(points[0]);
  svg += `<polygon points="${points.join(' ')}" />`;

  // 计算每条边的中点,标注转换单位后的边长
  for (let i = 0; i < sides; i++) {
    const [x1, y1] = points[i].split(',').map(Number);
    const [x2, y2] = points[i+1].split(',').map(Number);
    // 边的中点坐标
    const midX = (x1 + x2) / 2;
    const midY = (y1 + y2) / 2;
    // 计算标注偏移方向(向外偏移5px,避免遮挡图形)
    const dx = x2 - x1;
    const dy = y2 - y1;
    const len = Math.sqrt(dx*dx + dy*dy);
    const offsetX = (-dy / len) * 5;
    const offsetY = (dx / len) * 5;
    // 单位转换:cm转m,保留两位小数
    const lengthInM = (sideLengths[i] / 100).toFixed(2);
    svg += `<text x="${midX + offsetX}" y="${midY + offsetY}" class="side-number" text-anchor="middle">${lengthInM} m</text>`;
  }

  svg += `</svg>`;
  return svg;
}

// 生成图形数组并渲染到页面
function generateShapeArray(count = 4) {
  const container = document.getElementById("shape-container");
  container.innerHTML = '';
  // 混合生成规则与不规则图形
  for (let i = 0; i < count; i++) {
    const shapeWrapper = document.createElement('div');
    shapeWrapper.className = 'shape-wrapper';
    shapeWrapper.innerHTML = generateSingleShape(i % 3 === 0); // 每3个图形包含1个规则图形
    container.appendChild(shapeWrapper);
  }
}

// 页面加载时自动生成图形数组
window.onload = () => generateShapeArray();

CSS 样式

#shape-container {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  padding: 20px;
}

.shape-wrapper {
  width: 200px;
  height: 200px;
  border: 1px solid #ccc;
  display: flex;
  align-items: center;
  justify-content: center;
}

.shape {
  fill: #f0f8ff;
  stroke: #333;
  stroke-width: 2px;
}

.side-number {
  font-size: 12px;
  fill: #d63031;
  font-family: Arial, sans-serif;
}

HTML 结构

<body>
  <div id="shape-container"></div>
</body>

关键优化点

  • 精准边长匹配:重构顶点计算逻辑,让生成的随机边长与图形实际边长相匹配,解决原代码标注与实际边长不符的问题
  • 单位转换:将厘米数值除以100,保留两位小数后以米(m)为单位显示
  • 标注布局优化:计算每条边的中点,沿边的垂直方向向外偏移,确保标注紧贴边且不遮挡图形
  • 规则/不规则混合:通过参数控制生成规则图形(所有边等长),满足多样化需求
  • 图形数组支持:新增批量生成逻辑,可指定生成图形数量,自动横向排列布局

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 02:18:23