OpenJsCad demo: Parametric S hook
Source code
Below is the OpenJsCad script for this demo. To build your own models, create a .jscad script and use the
OpenJsCad parser
. For more information see the
OpenJsCad documentation
.
// Here we define the user editable parameters: function getParameterDefinitions() { return [ { name: 'topdiameter', caption: 'Inner diameter of top hook:', type: 'float', default: 10 }, { name: 'clampfactor', caption: 'Snugness of top hook (0 - 100):', type: 'float', default: 20 }, { name: 'cliplength', caption: 'Top hook clip length:', type: 'float', default: 5 }, { name: 'bottomdiameter', caption: 'Inner diameter of bottom hook:', type: 'float', default: 15 }, { name: 'height', caption: 'Outer height of the hook:', type: 'float', default: 50 }, { name: 'thickness', caption: 'Thickness:', type: 'float', default: 5 }, { name: 'width', caption: 'Width:', type: 'float', default: 10 }, { name: 'rounded', type: 'choice', caption: 'Rounded edges', values: [0, 1], captions: ["No", "Yes (rendering will take a long time!)"], default: 0, }, { name: 'roundness', caption: 'Diameter of rounded edges (if enabled):', type: 'float', default: 1 }, ]; } function main(params) { var pathresolution = 16; var expandresolution = 16; // construct the 2D path: var topradius = params.topdiameter/2; var bottomradius = params.bottomdiameter/2; var halfthickness = params.thickness/2; topradius += halfthickness; bottomradius += halfthickness; var roundness = params.roundness; if(params.rounded == 0) { roundness = 0; } roundness = Math.min(roundness, halfthickness-0.1, params.width/2-0.1); if(roundness < 0) roundness = 0; var clampfactor = params.clampfactor / 100; if(clampfactor < 0) clampfactor = 0; if(clampfactor >= 1) clampfactor = 1; clampfactor *= (topradius-halfthickness)/topradius; var topstartangle = - 180 * Math.acos(1 - 2*clampfactor) / Math.PI; var tophookcenter = new CSG.Vector2D(topradius, 0); var tophookstart = tophookcenter.plus(CSG.Vector2D.fromAngleDegrees(topstartangle).times(topradius)); var circledistance = params.height - topradius - bottomradius - 2 * params.thickness; if(circledistance < 0) circledistance = 0; var bottomhookcenter = new CSG.Vector2D(-bottomradius, -circledistance); var gravityangle = 90 - tophookcenter.minus(bottomhookcenter).angleDegrees(); var path = new CSG.Path2D(); // top hook curve: if(params.cliplength > 0) { var clipstart = new CSG.Vector2D([0, -1]).times(params.cliplength).plus(tophookstart); path = path.appendPoint(clipstart); } var topcurvepath = CSG.Path2D.arc({ center: tophookcenter, radius: topradius, startangle: topstartangle, endangle: 180, resolution: pathresolution, maketangent: true, }); path = path.concat(topcurvepath); // straight middle part: if(circledistance > 0) { path = path.appendPoint([0, -circledistance]); } // bottom hook curve: var bottomcurvepath = CSG.Path2D.arc({ center: bottomhookcenter, radius: bottomradius, startangle: 0, endangle: -180-gravityangle, resolution: pathresolution, maketangent: true, }); path = path.concat(bottomcurvepath); // center around origin, and rotate as it would hang under gravity: var centerpoint = tophookcenter.plus(bottomhookcenter).times(0.5); var matrix = CSG.Matrix4x4.translation(centerpoint.negated().toVector3D(0)); matrix = matrix.multiply(CSG.Matrix4x4.rotationZ(gravityangle)); path = path.transform(matrix); // extrude the path to create a 3D solid var result = path.rectangularExtrude(2*(halfthickness-roundness), params.width-2*roundness, pathresolution, true); result = result.translate([0, 0, -params.width/2+roundness]); // expand to create rounded corners: if(roundness > 0) { result = result.expand(roundness, expandresolution); } return result; }