For reasons not relevant here, I was tapped to replace the plastic parts attaching the handle to a garden cart:

The owner tried to contact the “manufacturer” to no avail; repair parts are simply not available, even if the name painted on the cart had a meaningful relationship to anything else.

Well, I can fix *that*:

Fortunately, another cart in the fleet provided the missing bits so I could reverse-engineer their measurements.

The solid model looks about like you’d expect:

Printing the two halves with those nice (yellow) bosses in place wasn’t feasible. They were exactly 1 inch in diameter, so I just parted two cookies from the end of a stout acetal rod after drilling a hole for the 2-¼ inch 5/16-18 bolt.

The two pieces took nigh onto three hours with five perimeters and 50% infill:

While delivering and installing the parts, I got volunteered to haul plants to cars with one of the carts during the upcoming Spring Plant Sale. That’ll teach me to stay in the Basement Shop …

The OpenSCAD source code as a GitHub Gist:

// Garden Cart Handle Pivot | |

// Ed Nisley KE4ZNU 2022-05 | |

Layout = "Show"; // [Show,Build] | |

/* [Hidden] */ | |

ThreadThick = 0.25; | |

ThreadWidth = 0.40; | |

HoleWindage = 0.2; | |

Protrusion = 0.1; // make holes end cleanly | |

inch = 25.4; | |

function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit); | |

ID = 0; | |

OD = 1; | |

LENGTH = 2; | |

//---------- | |

// Dimensions | |

// Handle lies along X axis | |

HandleOD = (7/8) * inch; | |

BoltOD = (5/16) * inch; | |

Washer = [BoltOD,1.0 * inch,2.0]; // just for Show | |

Disk = [BoltOD,62.0,(3/16) * inch]; | |

ClampBase = [(1 + 7/8)*inch,(1 + 1/8)*inch,2.0]; | |

Kerf = 2.0; | |

CornerRadius = 1.0; | |

PivotOA = [Disk[OD],Disk[OD],HandleOD + 2*ClampBase.z + 2*Disk[LENGTH]]; | |

//---------------------- | |

// Useful routines | |

module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes | |

Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2); | |

FixDia = Dia / cos(180/Sides); | |

cylinder(d=(FixDia + HoleWindage),h=Height,$fn=Sides); | |

} | |

//---------------------- | |

// Set up parts | |

module Handle() { | |

translate([-2*PivotOA.x,0,0]) | |

rotate([0,90,0]) | |

PolyCyl(HandleOD,4*PivotOA.x,24); | |

} | |

module Bolt() { | |

translate([0,0,-PivotOA.z]) | |

PolyCyl(BoltOD,2*PivotOA.z,12); | |

} | |

module Pivot() { | |

difference() { | |

union() { | |

hull() | |

for (i=[-1,1], j=[-1,1]) // rounded block | |

translate([i*(ClampBase.x/2 - CornerRadius),j*(ClampBase.y/2 - CornerRadius),-PivotOA.z/2]) | |

cylinder(r=CornerRadius,h=PivotOA.z,$fn=4*8); | |

for (k=[-1,1]) | |

translate([0,0,k*(PivotOA.z/2 - Disk[LENGTH]/2)]) | |

rotate(180/36) | |

cylinder(d=Disk[OD],h=Disk[LENGTH],$fn=36,center=true); | |

} | |

Handle(); | |

Bolt(); | |

cube([2*ClampBase.x,2*ClampBase.y,Kerf],center=true); // slice through center | |

} | |

} | |

//---------- | |

// Build them | |

if (Layout == "Show") { | |

rotate([90,-45,0]) { | |

Pivot(); | |

color("Green") | |

translate([2*PivotOA.x - PivotOA.x/2,0,0]) | |

Handle(); | |

color("Red") | |

Bolt(); | |

color("Yellow") | |

for (k=[-1,1]) | |

translate([0,0,k*(PivotOA.z/2 + Washer[LENGTH])]) | |

rotate(180/36) | |

cylinder(d=Washer[OD],h=Washer[LENGTH],$fn=36,center=true); | |

} | |

} | |

if (Layout == "Build") { | |

Offset = 5.0; | |

intersection() { | |

translate([-(PivotOA.x/2 + Offset),0,PivotOA.z/2]) | |

Pivot(); | |

translate([-2*PivotOA.x,-2*PivotOA.y,0]) | |

cube([4*PivotOA.x,4*PivotOA.y,PivotOA.z/2],center=false); | |

} | |

intersection() { | |

translate([(PivotOA.x/2 + Offset),0,PivotOA.z/2]) | |

rotate([180,0,0]) | |

Pivot(); | |

translate([-2*PivotOA.x,-2*PivotOA.y,0]) | |

cube([4*PivotOA.x,4*PivotOA.y,PivotOA.z/2],center=false); | |

} | |

} | |