kcl-samples → ball-joint-rod-end
ball-joint-rod-end

KCL
// ball joint rod end
// A ball joint rod end is a mechanical linkage component that consists of a spherical ball housed within a socket, connected to a threaded rod, allowing rotational movement in multiple directions while providing a secure connection point between two parts of a mechanical system. Commonly used in steering systems and suspension components.
// Set Units
@settings(defaultLengthUnit = in, kclVersion = 1.0)
// variables
ballBoltLength = 6
ballRadius = 8
sketchStartAngle = asin(ballBoltLength / ballRadius)
housingThicknessHalf = 4.5
housingR1 = 11
housingR2 = 8
tolerance = 0.1
shaftR = 8
distanceBetweenEyeAndShaftEnd = 36
radiusToFlat = 12
flatsWidth = 14
tapperInAng = 45
holeDForM8Tap = 6.8
holdDepth = 18
// calculated variables
retainingLoopSketchAngle1 = asin(housingThicknessHalf / housingR1)
retainingLoopSketchAngle2 = asin(housingThicknessHalf / housingR2)
pointOnRingPolar = polar(angle = retainingLoopSketchAngle2 + 90, length = housingR2 + tolerance)
polarY = pointOnRingPolar[1]
intersectPoint = sqrt(pow(housingR1, exp = 2) - pow(shaftR, exp = 2))
// start modeling section
// start with inner ball
ballSketch = startSketchOn(YZ)
ballProfile = startProfile(ballSketch, at = polar(angle = sketchStartAngle + 90, length = ballRadius))
|> arc(angleStart = sketchStartAngle + 90, angleEnd = 90 - sketchStartAngle, radius = ballRadius)
|> yLine(endAbsolute = 4)
|> xLine(endAbsolute = -ballBoltLength)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
ballRevolve = revolve(ballProfile, angle = 360, axis = X)
|> appearance(%, color = "#519afb")
// next the retaining loop that keep the ball in place
retainingLoopSketch = startSketchOn(YZ)
retainingLoopProfile = startProfile(retainingLoopSketch, at = polar(angle = retainingLoopSketchAngle1 + 90, length = housingR1))
|> arc(angleStart = retainingLoopSketchAngle1 + 90, angleEnd = 90 - retainingLoopSketchAngle1, radius = housingR1)
|> yLine(endAbsolute = polarY)
|> arc(angleStart = -retainingLoopSketchAngle2 + 90, angleEnd = 90 + retainingLoopSketchAngle2, radius = housingR2)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
retainingLoopRevolve = revolve(retainingLoopProfile, angle = 360, axis = X)
intersectPoint2 = polar(angle = -5, length = housingR1 - 0.08)
// the shaft is modeled in two parts, and intersected together
// starting with a revolve
threadedShaftBodyRevolveSketch = startSketchOn(XZ)
threadedShaftBodyRevolveProfile = startProfile(threadedShaftBodyRevolveSketch, at = [0, -distanceBetweenEyeAndShaftEnd])
|> xLine(length = shaftR - 0.07, tag = $seg05) // 0.07 dither to make CSG work
|> yLine(endAbsolute = -intersectPoint, tag = $kink)
|> arc(interiorAbsolute = intersectPoint2, endAbsolute = [housingR1 - 0.08, 0])
// |> line(endAbsolute = [housingR1, 0])
|> xLine(endAbsolute = 0)
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
threadedShaftBodyRevolve = revolve(threadedShaftBodyRevolveProfile, angle = 360, axis = Y)
// second part of the shalft is a extrude that will add the flats and the filleted taper to get to the retaining ring width
threadedShaftBodySketch = startSketchOn(-YZ)
threadedShaftBodyProfile = startProfile(threadedShaftBodySketch, at = [0, -distanceBetweenEyeAndShaftEnd - 1])
|> xLine(length = flatsWidth / 2)
|> yLine(endAbsolute = -intersectPoint - 2.5 - 0.11, tag = $longflats)
|> angledLine(tag = $seg01, angle = tapperInAng + 90, endAbsoluteX = housingThicknessHalf - 0.1)
|> yLine(endAbsolute = 0, tag = $seg02)
|> xLine(endAbsolute = -housingThicknessHalf + 0.15)
|> yLine(length = -segLen(seg02), tag = $seg03)
|> angledLine(angle = tapperInAng, endAbsoluteX = -flatsWidth / 2, tag = $seg04)
|> yLine(length = -segLen(longflats))
|> line(endAbsolute = [profileStartX(%), profileStartY(%)])
|> close()
threadedShaftBodyFlats = extrude(threadedShaftBodyProfile, length = 40)
|> translate(x = 20, y = 0, z = 0)
|> fillet(radius = 1.9, tags = [getCommonEdge(faces = [seg01, seg02])])
|> fillet(radius = 1.5, tags = [getCommonEdge(faces = [seg03, seg04])])
solid001 = intersect([
threadedShaftBodyRevolve,
threadedShaftBodyFlats
])
sketch005 = startSketchOn(-XZ)
profile005 = circle(sketch005, center = [0, 0], radius = ballRadius - 2)
extrude002 = extrude(profile005, length = 100)
|> translate(x = 0, y = -50, z = 0)
solid002 = subtract([solid001], tools = [extrude002])
// Join the thread body with the retaining loop for the balljoint
solid003 = union([solid002, retainingLoopRevolve])
plane001 = offsetPlane(XY, offset = -distanceBetweenEyeAndShaftEnd - 1)
sketch001 = startSketchOn(plane001)
profile001 = circle(sketch001, center = [0, 0], radius = holeDForM8Tap / 2)
threadedRodHole = extrude(profile001, length = holdDepth + 1)
// cut hole for threaded rod
solid004 = subtract([solid003], tools = [threadedRodHole])