ep = 0.01; t = 3; // thickness w = 32; // width dt = 36; // door thickness hookDescent = 100; backDescent = dt / 2; module backSupport(descent, rakeAngle = 20, includeKicker = true) { topExt = sin(rakeAngle)*descent; difference() { union() { cube([t, descent, w]); if (includeKicker) { cube([topExt, t, w]); translate([topExt, -1, 0]) rotate([0, 0, rakeAngle]) translate([0, -t, 0]) cube([t, descent + t, w]); } } union() { translate([-ep, -2*t, -ep]) cube([topExt + 2*t, 2*t, w + 2*ep]); translate([topExt + 2*t/3, -ep, -ep]) cube([t, descent, w + 2*ep]); } } } module hookAndSupport(descent, hookSize = 32, angle = 45, debug=false) { hw = hookSize / 2; hookDist = hookSize * 2.5; hookOffsetX = sin(angle) * hookDist; hookOffsetY = cos(angle) * hookDist; fpr = 2/5; // frame attachment point ratio aBAF = (90 - angle)/2; l = hookDist; lAC = hookDist * fpr; lCG = lAC * sin(angle); lCD = hookOffsetX; lCE = lCG/cos(angle); lAF = lAC*cos(angle) / cos(aBAF); lGE = lCE*sin(angle); lGF = lAF*sin(aBAF); lCF = lCG + lGF; lEF = sqrt(lGE*lGE + lGF*lGF); lCI = lCF*cos(angle); lFI = lCF*sin(angle); lDI = lCD - lCI; lDF = sqrt(lDI*lDI + lEF*lEF); aGEF = atan(lGF/lGE); aCAE = 90 - angle; aCEF = aCAE + aGEF; aEDF = atan(lFI/lDI) + 1; phi = (90 - angle)/2; g0 = l*fpr; g1 = g0*sin(angle); g2 = (g0 * cos(angle) * sin(phi))/cos(phi); o = (g0 * cos(angle))/cos(phi); p1 = (g0 * sin(angle))/cos(angle); translate([t/4, descent - t, 0]) union() { color("Salmon") translate([-hookOffsetX, -hookOffsetY, 0]) sphere(hookSize / 2); translate([0, 0, -hw/2]) union() { color("LightBlue") rotate([0, 0, 270 - angle]) translate([-t/2, -t/2, 0]) cube([hookDist + t, t, hw]); color("LightGreen") translate([0, -lAC, 0]) rotate([0, 0, 180 - angle]) translate([-t/2, -t/2, 0]) cube([lCF + t/2, t, hw]); color("Orange") rotate([0, 0, aBAF + 180]) translate([-t/2, -t/2, 0]) cube([lAF + t/2, t, hw]); color("Plum") translate([-lCD, -g0 -t/2, 0]) cube([lCD + t/2, t, hw]); color("Turquoise") translate([-lCE, -lAC, 0]) rotate([0, 0, aCEF]) translate([-t/2, -t/2, 0]) cube([lEF + t/2, t, hw]); color("SlateBlue") translate([-lCD + t/2, -lAC, 0]) rotate([0, 0, aEDF]) translate([-t/2, -t/2, 0]) cube([lDF + t/2, t, hw]); color("Linen") translate([-lCD, -2*lAC, 0]) cube([t, lAC, hw]); $fn=32; color("DodgerBlue") linear_extrude(height=hw) circle(r = t); translate([-lCI, -lAC + lFI, 0]) color("DodgerBlue") linear_extrude(height=hw) circle(r = t); translate([-lCD + t/2, -lAC, 0]) color("DodgerBlue") linear_extrude(height=hw) circle(r = t); } // Point Labels if (debug) { color("Red") translate([0, 0, w/2+1]) union() { translate([-t/2, 0, 0]) rotate([180, 0, 0]) linear_extrude(height=1) text(text = "A",size = 4); translate([-hookOffsetX + t/2, -hookOffsetY + t/2, 0]) rotate([0, 0, 180]) linear_extrude(height=1) text(text = "B",size = 4); translate([t/2, -lAC + t/2, 0]) rotate([0, 0, 180]) linear_extrude(height=1) text(text = "C",size = 4); translate([-hookOffsetX + t/2, -lAC, 0]) union() { translate([0, -hookOffsetY + lAC, 0]) cube([0.5, hookOffsetY - lAC, 1]); translate([0, t/2, 0]) rotate([0, 0, 180]) linear_extrude(height=1) text(text = "D",size = 4); } translate([-lCE + t/2, -lAC + t/2, 0]) rotate([0, 0, 180]) linear_extrude(height=1) text(text = "E",size = 4); translate([-t/2, 0, 0]) rotate([0, 0, aBAF]) translate([-lAF + t/2, 0, 0]) rotate([0, 0, 180 - aBAF]) linear_extrude(height=1) text(text = "F",size = 4); translate([0, -lAC + t/2, 0]) rotate([0, 0, -angle]) translate([-lCG + t/2, 0, 0]) rotate([0, 0, 180 + angle]) linear_extrude(height=1) text(text = "G",size = 4); translate([-lCE, 0, 0]) union() { rotate([0, 0, 180]) linear_extrude(height=1) text(text = "H",size = 4); translate([0, -lAC, 0]) cube([0.5, lAC, 1]); cube([lCE, 0.5, 1]); } union() { translate([-lCI - t, -lAC + t/2, 0]) rotate([0, 0, 180]) linear_extrude(height=1) text(text = "I",size = 4); translate([-lCI, -lAC, 0]) cube([0.5, lFI, 1]); } } } } } union() { translate([0, 0, -w/2]) union() { color("Moccasin") translate([t, 0, 0]) cube([dt + 2*ep, t, w]); color("WhiteSmoke") cube([t, hookDescent, w]); color("WhiteSmoke") translate([dt + t, 0, 0]) backSupport(descent = backDescent, rakeAngle = 36, includeKicker = false); } hookAndSupport(descent = hookDescent, hookSize = w, angle = 36, debug=false); }