【问题标题】:How to find all squares of a certain size inside a circle grid如何在圆形网格内找到一定大小的所有正方形
【发布时间】:2026-02-08 02:55:01
【问题描述】:

我正在尝试在画布的圆形区域中绘制各种不重叠的正方形。

最初我尝试在圆圈内的随机位置创建正方形并检查它们是否重叠,但一段时间后我意识到它太低效且太复杂,无法满足我的需要。

我想要一个使用圆心坐标、圆半径和正方形网格大小的算法,并返回一个坐标数组,用于表示网格上每个正方形的位置,该网格具有所有边缘圈内。

【问题讨论】:

  • 请提供某种形式的部分实现?帮助我们帮助你! :) 编辑:- 有很多方法可以实现这一点。
  • 通过“get all squares”你的意思是它应该找到给定大小的圆圈中的最大网格正方形数吗?如果您认为这是一个算法问题,请提供输入格式和精确的问题定义以及所需的输出。

标签: javascript algorithm html5-canvas


【解决方案1】:

我假设您希望圆圈中有未填充的空间,而不是用部分正方形填充它?如果是这样,则有效的正方形将是所有四个角都在圆内的正方形,因此一个简单的循环将为您找到它们。下面的代码应该可以做到这一点,尽管为了清楚起见,我已经将其拆分,您可能需要进一步压缩它。

const size = 4; // The size of each square.
const squareCoords = []; // The top-left corners of each valid square.
const circle = [10, 10, 10]; // The circle, in the form [centerX, centerY, radius]

function DistanceSquared(x1, y1, x2, y2) {
    return (x2-x1) ** 2 + (y2-y1) ** 2;
}
function isInsideCircle(x, y, cx, cy, r) {
    return (DistanceSquared(x, y, cx, cy) <= r ** 2);
}

let topLeftInside = false, bottomRightInside = false, topRightInside = false, bottomLeftInside = false;
for (let xx = circle[0] - circle[2]; xx < circle[0] + circle[2]; xx += size) {
    for (let yy = circle[1] - circle[2]; yy < circle[1] + circle[2]; yy += size) {
        topLeftInside = isInsideCircle(xx, yy, circle[0], circle[1], circle[2]);
        bottomRightInside = isInsideCircle(xx + size, yy + size, circle[0], circle[1], circle[2]);
        bottomLeftInside = isInsideCircle(xx, yy + size, circle[0], circle[1], circle[2]);
        topRightInside = isInsideCircle(xx + size, yy, circle[0], circle[1], circle[2]);
        if (topLeftInside && bottomRightInside && bottomLeftInside && topRightInside) {
            squareCoords.push([xx, yy]);
        }
    }
}

【讨论】:

  • 您的代码在圆 [2, 2, 2] 中找到 0 个边为 2 的正方形。
  • @jal_a 嗯。另一种选择是检查每个像素,只有在匹配时才跳到size 像素,但这似乎效率低下。也许我的整个方法都不是最好的?
  • 这个问题没有明确定义。您的方法将圆形和正方形置于预定义的坐标中,从而限制了匹配正方形的数量。虽然它可能适用于 OP,但如果算法需要最大数量的平方,那么它需要一种不同的方法。
  • "我想要一个使用圆心坐标、圆半径和正方形网格大小的算法,并返回网格上每个正方形位置的坐标数组那是在圈子里面。”在我看来,他想要正方形的坐标,而不是最大数;并且给定一个指定大小的网格会将这些正方形限制为只有一个可能的覆盖集。
  • 最好添加一个预过滤器来识别那些适合圆内最大内接正方形的正方形。这可以通过减少必要的数学运算量来加速操作。