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); | |
| } | |
| } | |