// -*- C -*- include module FArcSegment_mask(beta) { for (i=[0 : 0.75 : 3]) { rotate(i*beta/4) polygon([[0, 0], [1, 0], [cos(beta/4), sin(beta/4)]]); } } module FArcSegment(xc,yc,inrad,outrad,alpha,delta) { translate([xc,yc]) { intersection() { difference() { circle(r=outrad); circle(r=inrad); } rotate(alpha) scale(outrad*2) { FArcSegment_mask(delta); } } } } tubeheight = 30; tubewidth = 15; mainthick = 4; clipthick = 2; clipang = 120; stemlen = 50; topwidth = 30; hookinrad = 7.5; hookcurl = 60; hookwidth = 4; tuberad = tubewidth/2; bend = atan(tuberad/stemlen); mainoutrad = tuberad + mainthick; hookoutrad = hookinrad + hookwidth; hookcy = -(stemlen - hookoutrad); eltop = [topwidth/2, -tuberad + tubeheight + mainthick + 1]; elmid = [topwidth/2, -tuberad]; ellow = tangent_intersect_b([0,hookcy], hookinrad, elmid); ellowextra = 180 - tangent_intersect_beta([0,hookcy], hookinrad, elmid); module Plan(){ dy = tubeheight - tuberad*2; FArcSegment(0, dy, tuberad, mainoutrad, -1, 181); FArcSegment(0, 0, tuberad, mainoutrad, -bend, bend+1); translate([tuberad, 0]) square(center=false, size=[mainthick,dy]); FArcSegment(0, 0, tuberad, tuberad + clipthick, 360-clipang, clipang+1); rotate(-bend) translate([tuberad, 0]) mirror([0,1]) square(center=false, size=[mainthick, stemlen/cos(bend)]); } module ElevationCore(){ FArcSegment(0, hookcy, hookinrad, hookoutrad, 180 - ellowextra, 90 + hookcurl); translate([-hookoutrad*sqrt(0.5), -(stemlen+10)]) mirror([1,0]) square(center=false, size=[topwidth, stemlen + tubeheight + 20]); polygon([[-hookoutrad, ellow[1]], reflect_in_y(eltop), eltop, elmid, ellow]); } intersection(){ translate([0,1, -(topwidth+10)/2]) linear_extrude(height=topwidth+10) Plan(); translate([50,0]) rotate([0,-90,0]) linear_extrude(height=100) ElevationCore(); }