カンバスたれ、計算機

スポンジ

※立方体に穴がぽこぽこ開いていきます(集合体恐怖症の人向けの警告)

はい、今日は有名なフラクタル立体のメンガーのスポンジを作ってみます。

まずは 13 に縮小するための変換行列を定義します

6
7
<a-assets>
    <a-mixin id="to1_3" scale="0.33333 0.33333 0.33333"></a-mixin>

次に、最初の立方体を用意します。色は適当に用意したmixinを付けます

9
    <a-box mixin="white"></a-box>

最後に、元の立方体を削除しつつ 13 に縮小した立方体を並べます。 並べ方は 3x3x3 の 27個のうち20個を残し、それぞれの軸で真ん中をぶち抜くように穴を開けるかたちです。

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
function to3(box) {
    let parent = box.parentElement; // 変換行列の定義された a-entity オブジェクト
    parent.removeChild(box); // 元の立方体を削除
    for (var x = 1; x >= -1; x--) {
        for (var y = 1; y >= -1; y--) {
            for (var z = 1; z >= -1; z--) {
                if ([x, y, z].filter(n=>n==0).length < 2) { // 並べ方の定義
                    var coord = [x, y, z].map(n=>n/3.0).join(" ");
                    var b = boxEntity(); // to1_3 変換行列と、立方体
                    b.setAttribute('position', coord);
                    parent.appendChild(b);
                }
            }
        }
    }
}

この最後の処理を再帰的に適用することで、どんどん細かい穴が開いていくのですが、まあブラウザの処理限界にすぐ達するので三段階くらいで止めてあります。

冷静に計算すると 20 * 20 * 20 で 8,000 個のオブジェクトがあるのでな……再帰こわい

(ちなみに、立方体のリストを得るために最初 querySelectorAll の代わりに getElementsByTagName を使ったらリストが更新されて制御が戻ってこなくなりました)

querySelectorAll() メソッドは、与えられた CSS セレクターに一致する文書中の要素のリストを示す静的な (生きていない) NodeList を返します。

https://developer.mozilla.org/ja/docs/Web/API/Document/querySelectorAll

返されたHTMLCollectionis はライブで、つまり document.getElementsByTagName() をもう一度呼び出さなくてもDOMツリーと自動的に同期を保つよう自分自身を更新します。

https://developer.mozilla.org/ja/docs/Web/API/Document/getElementsByTagName