如何实现圆内带间隙矩形平铺计数的JavaScript工具?
硅晶圆矩形平铺问题修复方案
你的代码目前只筛选了中心区域的矩形,导致圆边缘的剩余空间没有被利用,核心问题在于矩形是否完全在圆内的判断逻辑错误,以及圆的尺寸没有根据输入动态调整。下面是修复后的完整代码和问题解析:
问题分析
- 圆尺寸固定:现有
.circle的宽高是固定100mm,没有根据用户输入的直径动态调整,导致输入不同直径时显示错误。 - 矩形入圆判断错误:用矩形左上角到圆心的距离来判断,且减去了矩形对角线的一半,这会把很多本来可以放入圆内的矩形排除在外,正确的判断应该是矩形的四个顶点都在圆内。
- 未清空旧矩形:每次点击计算按钮时,之前生成的矩形没有被清除,导致多次点击后叠加显示。
修复后的代码
<!DOCTYPE html> <html> <head> <title>硅晶圆矩形切割估算工具</title> <style> .circle { border-radius: 50%; background-color: lightgray; position: relative; margin-top: 20px; } .rectangle { position: absolute; box-sizing: border-box; border: 1px solid #333; /* 方便查看间隙 */ } .form-group { margin-bottom: 10px; } </style> <script> function calculate() { // 获取输入值并转为数字类型 const circleDiameter = parseFloat(document.getElementById("circle-diameter").value); const rectWidth = parseFloat(document.getElementById("rectangle-width").value); const rectHeight = parseFloat(document.getElementById("rectangle-height").value); const gap = parseFloat(document.getElementById("gap").value); // 清空之前生成的矩形 const circle = document.querySelector(".circle"); circle.innerHTML = ""; // 动态设置圆的尺寸 circle.style.width = circleDiameter + "mm"; circle.style.height = circleDiameter + "mm"; const circleRadius = circleDiameter / 2; const centerX = circleRadius; const centerY = circleRadius; // 计算每行每列的间隔(矩形尺寸+间隙) const rowStep = rectHeight + gap; const colStep = rectWidth + gap; // 计算最大可能的行数和列数(覆盖整个圆范围) const maxRowCount = Math.floor((circleDiameter + rowStep) / rowStep); const maxColCount = Math.floor((circleDiameter + colStep) / colStep); let count = 0; // 遍历所有可能的矩形位置 for (let i = 0; i < maxRowCount; i++) { // 计算当前行矩形的顶部位置(居中对齐) const rectTop = centerY - (maxRowCount - 1) * rowStep / 2 + i * rowStep; // 矩形的底部Y坐标 const rectBottom = rectTop + rectHeight; // 快速判断当前行是否完全在圆外,跳过循环 const rowDistance = Math.abs(rectTop + rectHeight/2 - centerY); if (rowDistance + rectHeight/2 > circleRadius) continue; for (let j = 0; j < maxColCount; j++) { // 计算当前列矩形的左侧位置(居中对齐) const rectLeft = centerX - (maxColCount - 1) * colStep / 2 + j * colStep; // 矩形的右侧X坐标 const rectRight = rectLeft + rectWidth; // 判断矩形是否完全在圆内:四个顶点到圆心的距离都不超过半径 const isInside = Math.hypot(rectLeft - centerX, rectTop - centerY) <= circleRadius && Math.hypot(rectRight - centerX, rectTop - centerY) <= circleRadius && Math.hypot(rectLeft - centerX, rectBottom - centerY) <= circleRadius && Math.hypot(rectRight - centerX, rectBottom - centerY) <= circleRadius; if (isInside) { const rectangle = document.createElement("div"); rectangle.classList.add("rectangle"); rectangle.style.width = rectWidth + "mm"; rectangle.style.height = rectHeight + "mm"; rectangle.style.top = rectTop + "mm"; rectangle.style.left = rectLeft + "mm"; // 随机背景色区分 const r = Math.floor(Math.random() * 256); const g = Math.floor(Math.random() * 256); const b = Math.floor(Math.random() * 256); rectangle.style.backgroundColor = `rgb(${r}, ${g}, ${b})`; circle.appendChild(rectangle); count++; } } } // 显示计数结果 console.log(`可容纳矩形数量:${count}`); alert(`可容纳矩形数量:${count}`); } </script> </head> <body> <div class="form-group"> <label for="circle-diameter">晶圆直径:</label> <input type="number" id="circle-diameter" value="100" step="0.1"> mm </div> <div class="form-group"> <label for="rectangle-width">矩形宽度:</label> <input type="number" id="rectangle-width" value="7" step="0.1"> mm </div> <div class="form-group"> <label for="rectangle-height">矩形高度:</label> <input type="number" id="rectangle-height" value="9" step="0.1"> mm </div> <div class="form-group"> <label for="gap">间隙:</label> <input type="number" id="gap" value="0.1" step="0.01"> mm </div> <button onclick="calculate()">计算并可视化</button> <div class="circle"></div> </body> </html>
关键改进点
- 动态调整圆尺寸:根据用户输入的直径实时设置圆的宽高,确保显示准确。
- 正确的入圆判断逻辑:检查矩形四个顶点是否都在圆内,避免遗漏边缘可放置的矩形。
- 清空旧元素:每次计算前清空圆内的旧矩形,避免叠加。
- 优化循环效率:提前判断整行是否在圆外,减少不必要的计算。
- 输入步长优化:给输入框添加
step属性,支持小数输入(符合晶圆切割的精度需求)。
内容的提问来源于stack exchange,提问作者Nosivadnomis
相关产品推荐
相关产品推荐

