Skip to content

Instantly share code, notes, and snippets.

@hrgdavor
Last active October 6, 2020 18:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hrgdavor/7419194097fc2ffd42d840f82fc83ca1 to your computer and use it in GitHub Desktop.
Save hrgdavor/7419194097fc2ffd42d840f82fc83ca1 to your computer and use it in GitHub Desktop.
openjscad V2 rounded top
/**
* Extrude rounded top From Slices
* @description Demonstrating the advanced extrusion using slices to create rounded top
* @tags extrude, slice, slices, extrudefromslices, callback
* @authors Davor Hrg
* @licence MIT License
*/
const { circle, square, roundedRectangle } = require('@jscad/modeling').primitives
const { translate } = require('@jscad/modeling').transforms
const { geom2 } = require('@jscad/modeling').geometries
const { extrudeFromSlices, slice } = require('@jscad/modeling').extrusions
const { mat4 } = require('@jscad/modeling').maths
const main = () => {
// demonstrates manipulating the original base through translation and scale to build a 3D geometry
const roundTop = (base, {height=4, r1=0.2, r1Percent=0, rx=0.1, ry=0, segments=1}) => {
if(r1Percent) r1 = r1Percent * height;
ry = ry || rx;
// radius is for one side, and scale factor is for both
rx = rx*2;
ry = ry*2;
var numberOfSlices = 2 + segments;
var step = 1/(numberOfSlices-1);
var angleDelta = Math.PI / (segments) / 2 ;
var angleDelta2 = 180 / (segments) / 2 ;
var startH = height - r1;
var baseSlice = slice.fromSides(geom2.toSides(base))
return extrudeFromSlices({
numberOfSlices,
callback: (progress, counter, baseSlice) => {
var h = progress * height;
let scaleX = 1;
let scaleY = 1;
if(progress == 1){ // top slice (counter = numSlices-1)
scaleX = 1 - rx;
scaleY = 1 - ry;
}else if(progress == step){ // first top slice (counter = 1)
h = startH;
}else if(progress > step){ // curve (counter = 2,3,4...)
var angle = (counter -1) * angleDelta;
h = height - r1 + (Math.sin(angle) * r1);
scaleX = 1 - rx + (Math.cos(angle) * rx);
scaleY = 1 - rx + (Math.cos(angle) * ry);
}else{
// bottom slice (counter = 0)
}
const scaleMatrix = mat4.fromScaling([scaleX, scaleY, 1])
const transformMatrix = mat4.fromTranslation([0, 0, h])
return slice.transform(mat4.multiply(scaleMatrix, transformMatrix), baseSlice)
}
}, baseSlice)
}
var circles = [3,5,8,32];
var ret = [
roundTop(square({size:4}), {height:4, r1Percent:0.2, rx:0.2, segments:1}),
translate( [8,0,0],
roundTop(roundedRectangle({size:[4,4], roundRadius:0.2*4, segments:4}), {height:4, r1Percent:0.2, rx:0.2, segments:1})
)
];
for(var j=0; j<circles.length; j++){
for(var i=0; i<4; i++){
ret.push(translate( [16+j*8,i*8,0],
roundTop(circle({radius:2.5, segments:circles[j]}), {height:4, r1Percent:0.2, rx:0.2, segments:(i*2 || 1)})
));
}
}
for(var i=1; i<4; i++){
ret.push(translate([0,i*8,0],
roundTop(square({size:4}), {height:4, r1Percent:0.2, rx:0.2, segments:i*2})
));
ret.push(translate( [8,i*8,0],
roundTop(roundedRectangle({size:[4,4], roundRadius:0.2*4, segments:i*2*4}), {height:4, r1Percent:0.2, rx:0.2, segments:i*2})
));
}
return ret;
}
module.exports = { main }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment