Skip to content

Instantly share code, notes, and snippets.

@BrianRossmajer
Created January 1, 2023 16:50
Show Gist options
  • Save BrianRossmajer/7d10900732a2c046881fb28d7b626234 to your computer and use it in GitHub Desktop.
Save BrianRossmajer/7d10900732a2c046881fb28d7b626234 to your computer and use it in GitHub Desktop.
Support V4
const jscad = require('@jscad/modeling')
const { torus, cuboid, roundedCuboid, cylinder } = jscad.primitives
const { translate, translateX, scale, rotate, rotateY, rotateZ } = jscad.transforms
const { measureDimensions, measureCenter } = jscad.measurements
const { union, intersect, subtract } = jscad.booleans
const { hull } = require('@jscad/modeling').hulls
const getParameterDefinitions = () => [
{ name: 'body', type: 'group', caption: 'Visible Body' },
{ name: 'bulkHeight', type: 'float', initial: 14, min: 10, max: 100.0, step: 1, caption: 'Visible body height:' },
{ name: 'bulkRadius', type: 'float', initial: 2, min: 0, max: 5, step: .1, caption: 'Radius of ouside rounding:' },
{ name: 'arm', type: 'group', caption: 'Arm' },
{ name: 'armLength', type: 'float', initial: 60, min: 0, max: 170.0, step: 1, caption: 'Length:' },
{ name: 'armRadius', type: 'float', initial: 40, min: 10, max: 170.0, step: 1, caption: 'Torus radius:' },
{ name: 'armThickness', type:'float', initial: 6, min: 1, max:20, step:0.25, caption:'Thickness'},
{ name: 'armSegmentsInner', type: 'int', initial: 18, min: 6, max: 170.0, step: 6, caption: 'Inner segments:' },
{ name: 'armSegmentsOuter', type: 'int', initial: 18, min: 6, max: 170.0, step: 6, caption: 'Outer segments:' },
{ name: 'insert', type: 'group', caption: 'In-post support' },
{ name: 'postInset', type: 'float', initial: 1.5, min: 0, max: 10.0, step: .1, caption: 'Support inset:' }
];
const main = (params) => {
const fullWidth = 57;
const poleWidth = fullWidth-params.postInset*2;
const radiusBig = params.armRadius;
const radiusSmall = 7.5;
const poleDepth = 23;
const poleCornerIndent=10;
const bulkRadius = params.bulkRadius;
const armOverlap = bulkRadius;
// smaller for speed, larger to print, multiples of 6
const innerSegments = params.armSegmentsInner;
const outerSegments = params.armSegmentsOuter;
let fullTorus = torus({ innerRadius: params.armThickness, innerSegments: innerSegments, outerRadius: radiusBig, outerSegments: outerSegments*2, startAngle: 0 });
let fullTorusHeight = measureDimensions(fullTorus)[2];
let bigTorus = scale([1,1,fullWidth/fullTorusHeight],fullTorus);
let ama = torus({ innerRadius: 2.25, innerSegments: innerSegments, outerRadius: radiusSmall, outerSegments: outerSegments, startAngle: 0 });
let amaHeight = measureDimensions(ama)[2];
let halfBigTorus = intersect( bigTorus,
cuboid({size: [(radiusBig+radiusSmall)*2,radiusBig+radiusSmall,fullWidth],
center: [0,0-(radiusBig+radiusSmall)/2,0]}) );
// the offset of 3 in the center calculation above lets the arm extend into the support
// torus (the "ama") so when we attach them we're going to subtract out the antiAma which is
// the shape of the hole in the middle
let amaInPlace = translate([radiusBig,radiusSmall,0],scale([1,1,fullWidth/amaHeight],ama));
let filledAma = cylinder({radius:radiusSmall,height:fullWidth, center: measureCenter(amaInPlace)});
let antiAma = subtract(filledAma,amaInPlace);
let support = subtract(union(halfBigTorus,amaInPlace),antiAma);
// the -bulkRadius is to allow the arm edge to extend past the radius of the
let supportInPlace = intersect( rotateZ(params.armLength/params.armRadius,support),
cuboid({size: [radiusBig*3,radiusBig*2,fullWidth],
center: [0,radiusBig-bulkRadius,0]}));
// centers are 45.5mm apart
let capInsertOffset = 45.5 / 2;
let capInsertDepth = 14;
let capInsert = translateX( (params.bulkHeight-capInsertDepth)/2, rotateY( Math.PI / 2, union(
cuboid( {size: [ 8, 14, capInsertDepth ], center: [ -capInsertOffset, 0, 0 ] } ),
cuboid( {size: [ 14, 8, capInsertDepth ], center: [ 0, -capInsertOffset, 0 ] } ),
cuboid( {size: [ 8, 14, capInsertDepth ], center: [ capInsertOffset, 0, 0 ] } ),
cuboid( {size: [ 14, 8, capInsertDepth ], center: [ 0, capInsertOffset, 0 ] } )
)) );
// bulk is the visible part over the post; it's a rounded cuboid with the rounding
// on the top and bottom removed so it transitions relatively seamlessly into the
// post and cap
let bulk = intersect(
roundedCuboid({size: [params.bulkHeight+bulkRadius*2,fullWidth,fullWidth],
roundRadius: bulkRadius, center: [radiusBig,-fullWidth/2,0]}) ,
cuboid({size: [params.bulkHeight,fullWidth,fullWidth],
center: [radiusBig,-fullWidth/2,0]})
);
let bulkBottomX = radiusBig - params.bulkHeight/2;
let bulkTopX = radiusBig + params.bulkHeight/2;
let bulkCenter = measureCenter(bulk);
let inPolePart = rotateY(Math.PI / 2, subtract(
cuboid({size:[poleWidth,poleWidth,poleDepth]}),
cylinder({radius: poleCornerIndent, height: poleDepth, center:[-poleWidth/2,-poleWidth/2,0]}),
cylinder({radius: poleCornerIndent, height: poleDepth, center:[-poleWidth/2, poleWidth/2,0]}),
cylinder({radius: poleCornerIndent, height: poleDepth, center:[ poleWidth/2,-poleWidth/2,0]}),
cylinder({radius: poleCornerIndent, height: poleDepth, center:[ poleWidth/2, poleWidth/2,0]})
));
let inPole = translate([bulkBottomX-(poleDepth/2),-fullWidth/2+((fullWidth-poleWidth)*0),0],inPolePart);
return rotate([-Math.PI/2,-Math.PI/2,Math.PI/2],translate([-bulkCenter[0],-bulkCenter[1],0],
subtract(union(supportInPlace, bulk, inPole ), translate(bulkCenter, capInsert)) ) );
};
module.exports = { main, getParameterDefinitions };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment