Skip to content

Instantly share code, notes, and snippets.

@felipesabino
Last active August 4, 2025 10:58
Show Gist options
  • Save felipesabino/4c9a2f677b783624ee5695de1147d7bc to your computer and use it in GitHub Desktop.
Save felipesabino/4c9a2f677b783624ee5695de1147d7bc to your computer and use it in GitHub Desktop.
replicad-tables-demo.js
// workbench: https://studio.replicad.xyz/workbench#code=UEsDBAoAAAAIAAh5A1v1i531AwQAAOoLAAAHAAAAY29kZS5qc81WS2%252FjNhC%252B61cMcpI3Wj%252FS7B7sboHUMLpbLBDDDtqD4QMj0RYbRjJIuc428H%252FvkENSlJwWWPTSHGJx%252BM3HeZN5XekGXqFQ7LRU9R88b0RdZdB%252Bz9kzVyyziAwaxSotWcPhDJ9A8YMUOStmSZJbooLv2FE2S6bYs0bAawIg%252Bf53UTTlFD5ktPzMxb5spnA7NgLNWeMAH4PAQ6zKXoliLf7iU5iMLULVJ42LG%252FOd1zJ867KOvJjCjknN%252FcYvyDJFB46cKBr0wsgWkj%252FzqtF%252B7zxzzjwzUaEPqcrgEBw6D%252BDTT%252BhXghwAoxF85Xttv0lJIghd1CmpDL33nmMY%252FA%252BSEIDBzJOuURSRmpMNKu1rdDiIdmD1AIYhVen7vtroJoM3hX0bnUX2n%252BRoSMkOHI3ZHTW%252FkzLdyAz0FlEWIXYQLHQBH9gSMH99VZPUeX0QXKd2KxxukhsWJrth4esggvaTOHAWn1u7e1a19dHapnhzVBUc8Lf51gLIMM8IHIupr2IR%252FsjE5s4UUJLgx%252FJu9bBOkt2xsmyQl0woLJcU%252Bwgz16bdkrpMuyiZbksplUMpKv5Qp5txBqdtT3Z6Wzbuy8aRLJe15p5cP%252FEmL%252B%252BrpWRVEPIXbIWCp1SRXVfPkUe20P%252FFG9xHXzp%252Bh%252FKk3KW3H%252BIzfHEcasmUqw4kyeA2OmF0M%252BizvLc0sWm2XeyB1h7H%252F%252F8J69mWyGox%252F7JcrP34dO6boWOjrd2woeZTXONsNaPA7m3G21ni%252BgpLGwcxTyeD4a5WC5aXqSteTwCtOn0MzWFRhZ%252FjPBBkRqVMtkUpCfZlmOdjhZNMsUIcW2tJ45Fp7q2NptE4wGcByqq9NNgfPo5hRKR2ptBu7k%252FdWI%252FRQ0hNQASKxjP8%252BdGpgLi%252B9l1NSsPDUZepscTkx6TCl4yAd3QsjYxz6zxpdpxvh1XkOw0qmlDtaCL6Xih6Hrj4PNYvIT6P6EAhqv3P9UuLyHGkcYUYAx3Sqhe0dcMPK4rcyBj0xvbcbRtLO%252FFTFD%252BF8bOqoNrwBVBOoNwGGQkgb0FUlya67gagaetD4EF2LPq4q3fBsEHYj0slCKmnQvt0Oz6iWWUuUBlsJtiQGUy2b6nkrcq8qzK5UGnLVWGdtNnNo5W7GC6uhu9y5%252FsOcr%252Fdn36lR1fgP1S1uZxW978u5g9f7kN%252F9y6%252FUOj9rv6PVZvXqrK7G2tlhMGBlqFl1yQ72ffNBWYSY0p6SF2AbrYeUfADsUR9l9sXLVpQ8dPFQzcl%252BwZDWddPd01KjNGoeoU%252FhRaPEnNUiqLglX0Jd9%252FPYTpaSnoeuTSQ168Uv6mjwMutUfUTf%252FhmZFdF3eirDCrUxtVnOuUrXjn6Cs5ZlyAY49C%252F0boD35qs%252Fw1QSwECFAAKAAAACAAIeQNb9Yud9QMEAADqCwAABwAAAAAAAAAAAAAAAAAAAAAAY29kZS5qc1BLBQYAAAAAAQABADUAAAAoBAAAAAA%253D
// instagram: https://www.instagram.com/p/DM0_5q2qa01/
const { drawProjection, ProjectionCamera, draw, translate } = replicad;
const defaultParams = {
legWidth: 5,
legHeight: 40,
seatWidth: 60,
seatHeight: 5,
gridSize: 100,
rows: 12,
cols: 12,
showProjection: true,
showGrid: true,
rotateGridElements: true,
};
const main = (r, params = {}) => {
// Legs
const l = legs(params.legWidth, params.legHeight, params.seatWidth);
// Seat
const s = seat(params.seatWidth, params.seatHeight)
.translate(-params.seatWidth/2, -params.seatWidth/2, params.legHeight);
let shape = fuseAll([l, s]);
if (params.showGrid) {
shape = fuseAll(gridCopies(shape, params.rows, params.cols, params.gridSize, params.rotateGridElements));
}
if (params.showProjection) {
return prettyProjection(shape);
} else {
return shape;
}
//
};
// PARTS
function chairLeg(w, h, seatWidth) {
const shape = draw()
.lineTo([0, w])
.lineTo([w, w])
.lineTo([w, 0])
.lineTo([0, 0])
.close()
.sketchOnPlane()
.extrude(h);
return shape;
}
function legs(w, h, seatWidth) {
const leg = chairLeg(w, h)
.rotate(45);
return fuseAll(polarCopies(leg, 4, seatWidth/2))
.rotate(-45);
}
function seat(w, h) {
return draw()
.lineTo([0, w])
.lineTo([w, w])
.lineTo([w, 0])
.lineTo([0, 0])
.close()
.sketchOnPlane()
.extrude(h);
}
// RECIPES
const fuseAll = (shapes) => {
let result = shapes[0];
shapes.slice(1).forEach((shape) => {
result = result.fuse(shape);
});
return result;
};
const polarCopies = (shape, count, radius) => {
const base = shape.translate(0, radius);
const angle = 360 / count;
const copies = [];
for (let i = 0; i < count; i++) {
copies.push(base.clone().rotate(i * angle));
}
return copies;
};
const gridCopies = (shape, rows, cols, gridSize, rotate) => {
const copies = [];
const bbox = shape.boundingBox;
const center = bbox.center;
const angleStepR = 360/rows;
const angleStepC = 360/cols;
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
let base;
if (rotate) {
// .rotate(r*angleStep)
base = shape
.clone()
.rotate(r*angleStepR, center, [1, 0, 1])
.rotate(c*angleStepC, center, [1, 1, 1])
.translate(r * gridSize, c * gridSize);
} else {
base = shape
.clone()
.translate(r * gridSize, c * gridSize);
}
copies.push(base);
}
}
return copies;
};
// PROJECTIO
const prettyProjection = (shape) => {
const bbox = shape.boundingBox;
const center = bbox.center;
const corner = [
bbox.center[0],// + bbox.width,
bbox.center[1],// + bbox.height,
bbox.center[2] + bbox.depth,
];
const camera = new ProjectionCamera(corner).lookAt(center);
const { visible, hidden } = drawProjection(shape, camera);
return [
{ shape: hidden, strokeType: "dots", name: "Hidden Lines" },
{ shape: visible, name: "Visible Lines" },
];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment