source-academy / modules

Modules that can be imported by programs in Source Academy, an online experiential environment for computational thinking
Apache License 2.0
8 stars 28 forks source link

[CSG] Add Empty Shape #290

Closed joeng03 closed 5 months ago

joeng03 commented 5 months ago

Description

Fixes #289

Note: yarn lint --fix was run so some of the CSG files were also linted accordingly.

Type of change

How Has This Been Tested?

// Menger sponge, see
// https://en.wikipedia.org/wiki/Menger_sponge

import { union, subtract,intersect, translate, rotate, scale, render, 
         cube, blue,rounded_cube, empty_shape }
from 'csg';

const c = cube('#88ccff');

const d = scale(cube(blue), 1.5, 1.5, 1.5);

const empty = empty_shape();

function beside(s1, s2) {
    return union(scale(s1, 0.5, 1, 1),
                 translate(scale(s2, 0.5, 1, 1),
                           0.5, 0, 0));
}
function beside_frac(f, s1, s2) {
    return union(scale(s1, f, 1, 1),
                 translate(scale(s2, 1 - f, 1, 1),
                           f, 0, 0));
}
function before(s1, s2) {
    return union(scale(s1, 1, 0.5, 1),
                 translate(scale(s2, 1, 0.5, 1),
                           0, 0.5, 0));
}
function before_frac(f, s1, s2) {
    return union(scale(s1, 1, f, 1),
                 translate(scale(s2, 1, 1 - f, 1),
                           0, f, 0));
}

function below(s1, s2) {
    return union(scale(s1, 1, 1, 0.5),
                 translate(scale(s2, 1, 1, 0.5),
                           0, 0, 0.5));
}
function below_frac(f, s1, s2) {
    return union(scale(s1, 1, 1, f),
                 translate(scale(s2, 1, 1, 1 - f),
                           0, 0, f));
}

function menger(s, n) {
    if (n === 1) {
       return s;
    } else {
       const f = 1/3;
       const m = menger(s, n - 1);
       const outer_row = before_frac(f, m,
                               before(m, m));
       const inner_row = before_frac(f, m,
                               before(empty, m));
       const outer_layer = beside_frac(f, outer_row,
                                 beside(inner_row,
                                        outer_row));
       const inner_layer = beside_frac(f, inner_row,
                                 beside(empty,
                                        inner_row));

       return below_frac(f, outer_layer,
                         below(inner_layer, 
                               outer_layer));
    }
}

const menger_sponge = menger(c, 4);

render(menger_sponge);

Checklist: