$fn = 64; // --- Parameters --- // Base plate dimensions base_width = 30; base_thick = 6; hole_dist = 80; // Distance between screw holes hole_dia = 5.5; // Screw hole diameter (M5) head_dia = 11; // Screw head diameter for countersink // Hook dimensions hook_dia = 14; // Main thickness of the hook hook_base_dia = 18; // Thickness where it joins the base tip_dia = 18; // Thickness of the end knob module leash_hook() { union() { // Base Plate with chamfered edge difference() { hull() { translate([0, hole_dist/2, 0]) cylinder(d=base_width, h=base_thick-1); translate([0, hole_dist/2, base_thick-1]) cylinder(d=base_width-2, h=1); translate([0, -hole_dist/2, 0]) cylinder(d=base_width, h=base_thick-1); translate([0, -hole_dist/2, base_thick-1]) cylinder(d=base_width-2, h=1); } // Top screw hole (countersunk) translate([0, hole_dist/2, -1]) cylinder(d=hole_dia, h=base_thick+2); translate([0, hole_dist/2, base_thick - 3]) cylinder(d1=hole_dia, d2=head_dia, h=3.1); // Bottom screw hole (countersunk) translate([0, -hole_dist/2, -1]) cylinder(d=hole_dia, h=base_thick+2); translate([0, -hole_dist/2, base_thick - 3]) cylinder(d1=hole_dia, d2=head_dia, h=3.1); } // Curved Hook difference() { union() { // Base to stem (angles UP and OUT to create a secure pocket) hull() { translate([0, -20, 0]) cylinder(d=hook_base_dia, h=base_thick); translate([0, -10, 25]) sphere(d=hook_dia); } // Stem extending further out and up hull() { translate([0, -10, 25]) sphere(d=hook_dia); translate([0, 5, 35]) sphere(d=hook_dia); } // Curve upwards hull() { translate([0, 5, 35]) sphere(d=hook_dia); translate([0, 15, 35]) sphere(d=hook_dia); } // Curve back towards the wall and finish with a stopper knob hull() { translate([0, 15, 35]) sphere(d=hook_dia); translate([0, 20, 25]) sphere(d=tip_dia); } } // Flatten the back to ensure it remains flush with the wall mounting surface translate([-50, -50, -50]) cube([100, 100, 50]); } } } // Render the hook leash_hook();