// box to hold the battery // as I found duct tape didnt really stick to the pla. // the part with the tab holes is the bottom, hence the battery // is 'standoff' height above the base. // the boat can take on water through the rudder post, so it is better // if the electronics are slightly off the ground. // all dims are inside dims, as that is what matters for the thing length=106; height=20; width=35; tabwidth=16; tabextraheight=6; // height of the tab supports (extra thickness at base of tab) thickness=1.6; // thickness of tabs. tried 0.8mm, were under-extruded and way too thin. standoff=8; // height of base holewidth=4; // size of the clip hole, should it ever be used by a lid module tab( offx, offy, rotz ) { translate([offx,offy,0]) rotate([0,0,rotz]) translate([-tabwidth/2,0,0]) { difference() { union() { translate([0,thickness,-tabextraheight/2]) // smaller outer tab hull(){ cube([tabwidth,thickness,tabextraheight+thickness]); translate([0,-thickness,-thickness]) cube([tabwidth,thickness,thickness]); } hull()// main tab { cube([tabwidth,thickness,height-thickness]); translate([0,0,height-thickness]) cube([tabwidth,thickness*0.01,thickness]); } } // subtract clip holes translate([tabwidth/2-sin(45)*holewidth,-1,height/2]) rotate([0,45,0]) cube([holewidth,holewidth,holewidth]); } } } module tab2( offx, offy, rotz ) { translate([offx,offy,0]) rotate([0,0,rotz]) translate([-tabwidth/2,0,0]) { difference() { union() { translate([0,thickness,-tabextraheight/2]) // smaller outer tab hull(){ cube([tabwidth,thickness,tabextraheight+thickness]); translate([0,-0.5*thickness,-thickness]) cube([tabwidth,0.5*thickness,thickness]); } cube([tabwidth,thickness,height/2-tabextraheight/2-0.5]); // main tab // add clip holes hull() { translate([tabwidth/2-sin(45)*holewidth*0.8,0,height/2-standoff]) rotate([0,45,0]) cube([holewidth*0.8,thickness,holewidth*0.8]); translate([tabwidth/2-sin(45)*holewidth*0.5,-thickness*0.5,height/2-standoff]) rotate([0,45,0]) cube([holewidth*0.5,thickness*0.5,holewidth*0.5]); } } } } } // bottom box translate([0,-width/2-thickness*3,standoff+thickness]) difference() { union() { translate([-length/2-thickness,-width/2-thickness,-thickness-standoff]) cube([length+thickness*2,width+thickness*2,thickness+standoff]); // tabs on the long sides, three per side tab(-length/3,width/2,0); // one side tab(0,width/2,0); tab(length/3,width/2,0); tab(-length/3,-width/2,180); // opp side tab(0,-width/2,180); tab(length/3,-width/2,180); // tabs on the short sides tab(length/2,0,90+180); tab(-length/2,0,90); } // and subtract the base translate([-length/2,-width/2,-thickness-standoff-1]) cube([length,width,thickness+standoff]); translate([-length/2+standoff,-width/2+standoff,-thickness-1]) cube([length-standoff*2,width-standoff*2,thickness+standoff]); } // top box translate([0,(width/2+thickness*4)*1,standoff+thickness]) union() { // tabs on the long sides, three per side tab2(-length/3,width/2+thickness*2,0); // one side tab2(0,width/2+thickness*2,0); tab2(length/3,width/2+thickness*2,0); tab2(-length/3,-width/2,180); // opp side tab2(0,-width/2,180); tab2(length/3,-width/2,180); // tabs on the short sides tab2(length/2+thickness*1,thickness,90+180); tab2(-length/2-thickness,thickness,90); scale(1.01) // hack to make up for printer scaling issues difference() { union() { translate([-length/2-thickness*2,-width/2-thickness*1,-thickness-standoff]) cube([length+thickness*4,width+thickness*4,thickness+standoff]); } // and subtract the base translate([-length/2-thickness*1,-width/2+thickness*0,-standoff-1]) cube([length+thickness*2,width+thickness*2,thickness+standoff]); translate([-length/2+standoff-thickness,-width/2+standoff,-standoff-thickness-1]) cube([length-standoff*2+thickness*2,width-standoff*2+thickness*2,thickness+standoff]); } }