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

如何实现圆内带间隙矩形平铺计数的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 18:40:00