【问题标题】:How to divide a block into smaller blocks of 4?如何将一个块分成 4 个更小的块?
【发布时间】:2022-10-13 03:31:35
【问题描述】:

我想将一个块分成 n 个较小的块,分组为 4s。像这样的东西:

我不确定我是否应该使用某种循环或递归,但算法的规则类似于:

  • 如果 1 不分裂
  • 如果 2 分成两半
  • 如果 3 个分成两半,然后再将其中 1 个分成两半
  • 如果 4 分成两半,然后再将两半分成两半
  • 如果 5 分成两半,然后再将两半分成两半,则 将其中一个四分之一分成两半

【问题讨论】:

  • 你是否试图重塑四叉树?
  • 也许?你能帮忙解答吗?
  • 不,不是真的。第一个问题:我不想花时间写一个好的解释。第二:四叉树是众所周知的,如果你仔细看的话,网络和教科书都充满了很好的描述和代码。第三:您自己承认您不确定四叉树是否是您正在寻找的,因此您需要自己做更多的研究。
  • @grabury 看起来你有点知道你需要做什么。您的决策步骤很明确,是的,递归将是解决此问题的好方法。如果是您不确定的实现,我建议您总体上查看trees。如上所述,您可能会得到某种形式的四叉树。

标签: algorithm


【解决方案1】:

这可以通过队列来完成——迭代地——就像你对广度优先遍历所做的那样。具体一点是,您希望先将一个块拆分为 4 个较小的块,然后再移动到另一个块。这意味着您将在 fifo 队列(双端队列)上进行循环,其中一个块将从双端队列中弹出,三个较小的块将被推送到它。只有当分割数小于 3 时,您才需要生成更少的块。

下面是一个可运行的 JavaScript 实现,其中块由 Rectangle 类的实例表示(带有左上角的坐标及其尺寸)。拆分将从一个实例创建两个新实例。一旦执行了请求的拆分次数,此 sn-p 将绘制每个矩形:

class Rectangle {
    constructor(left, top, width, height) {
        Object.assign(this, {left, top, width, height});
    }
    splitVertically() {
        const width = this.width / 2;
        return [
            new Rectangle(this.left, this.top, width, this.height),
            new Rectangle(this.left + width, this.top, width, this.height)
        ];
    }
    splitHorizontally() {
        const height = this.height / 2;
        return [
            new Rectangle(this.left, this.top, this.width, height),
            new Rectangle(this.left, this.top + height, this.width, height)
        ];
    }
    draw(ctx) {
        ctx.rect(this.left+0.5, this.top+0.5, this.width, this.height);
        ctx.stroke();
    }
}

function splitBlock(n, rect) {
    let deque = [rect];
    while (n-- > 0) {
        const rect = deque.shift();
        const arr = rect.splitVertically();
        if (n-- > 0) arr.push(...arr.shift().splitHorizontally());
        if (n-- > 0) arr.push(...arr.shift().splitHorizontally());
        deque.push(...arr);
    }
    return deque;
}

// Example run
const numSplits = 11;
const blocks = splitBlock(numSplits, new Rectangle(0, 0, 180, 180))
// Output the result on a canvas
const ctx = document.querySelector("canvas").getContext("2d");
for (const block of blocks) block.draw(ctx);
<canvas width="181" height="181"></canvas>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多