kcl-samples → shepherds-hook-bolt
shepherds-hook-bolt

KCL
// Shepherd’s Hook Bolt
// A bent bolt with a curved hook, typically used for hanging or anchoring loads. The threaded end allows secure attachment to surfaces or materials, while the curved hook resists pull-out under tension.
// Set units in millimeters (mm)
@settings(defaultLengthUnit = mm, kclVersion = 1.0)
// Define bolt geometry parameters
boltDiameter = 5
hookRadius = 12
shankLength = 5
threadedEndLength = 30
nutDistance = 20
hookStartAngle = 290
hookEndAngle = 150
approximatePitch = boltDiameter * 0.15
threadDepth = 0.6134 * approximatePitch
innerRadius = boltDiameter / 2 - threadDepth
boltNumberOfRevolutions = threadedEndLength / approximatePitch
// Helper values for computing geometry transitions between straight shaft and hook arc
hypotenuse = hookRadius / cos(hookStartAngle - 270)
side = sqrt(pow(hypotenuse, exp = 2) - pow(hookRadius, exp = 2))
shankOffset = hypotenuse + side
// Converts polar coordinates to cartesian points for drawing arcs
fn polarToCartesian(radius, angle) {
x = radius * cos(angle)
y = radius * sin(angle)
return [x, y]
}
// Create the hook and shank profile path
// Includes straight segment and two connected arcs forming the hook
hookProfilePlane = startSketchOn(XZ)
hookProfileShape = startProfile(hookProfilePlane, at = [0, -shankOffset - shankLength])
|> line(endAbsolute = [0, -shankOffset])
|> tangentialArc(endAbsolute = polarToCartesian(radius = hookRadius, angle = hookStartAngle))
|> tangentialArc(endAbsolute = polarToCartesian(radius = hookRadius, angle = hookEndAngle), tag = $hook)
// Create the circular cross-section used for sweeping along the hook path
hookSectionPlane = offsetPlane(XY, offset = -shankOffset - shankLength)
hookSectionShape = circle(hookSectionPlane, center = [0, 0], radius = boltDiameter / 2)
// Sweep the section along the hook profile to form the main body of the hook bolt
hookBody = sweep(hookSectionShape, path = hookProfileShape, sectional = true)
// Add a cylindrical tip at the hook end
tipPlane = startSketchOn(hookBody, face = END)
tipShape = circle(
tipPlane,
center = [hookRadius, 0],
radius = boltDiameter / 2,
tag = $seg01,
)
tipBody = extrude(
tipShape,
length = hookRadius * 0.5,
tagStart = $startTag,
tagEnd = $capEnd001,
)
|> fillet(
radius = boltDiameter / 4,
tags = [
getCommonEdge(faces = [seg01, capEnd001])
],
)
// Create the threaded end of the bolt
// Construct the triangular profile for thread cutting
boltThreadSectionPlane = startSketchOn(XZ)
boltThreadSectionShapeForRevolve = startProfile(
boltThreadSectionPlane,
at = [
innerRadius,
-shankOffset - shankLength - threadedEndLength
],
)
|> line(end = [threadDepth, approximatePitch / 2])
|> line(end = [-threadDepth, approximatePitch / 2])
|> patternLinear2d(axis = [0, 1], instances = boltNumberOfRevolutions, distance = approximatePitch)
|> xLine(length = -innerRadius * 0.9)
|> yLine(length = -threadedEndLength)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
// Create a revolved solid representing the thread geometry by repeating and revolving the profile around the shaft
boltThreadRevolve = revolve(boltThreadSectionShapeForRevolve, angle = 360, axis = Y)