eps = 0.01; infty = 200; // 2x 10180 // batt_d_real = 10; // batt_l = 36 + 0.5; // 2x 18650 side by side batt_d_real = 18; batt_l = 65 + 1.5; batt_sep = 0.65; wall = 1; batt_d = batt_d_real + batt_sep; wire_sep = 1.5; wire_w = 3; wire_h = 1.5; body_h = 0.8*batt_d_real; cyl_center_h = batt_l/3; // z-offset from the widest point of the battery to the widest // point of the clip top_clip_h = 0.25*batt_d; spring_sep = 0.7; // outer part of the spring d_out = batt_d/2-spring_sep/2; // inner part of the spring d_in = d_out/2-wall/2-spring_sep/2; // batt_d/4-3*wall/4; // straight part length straight_l = batt_l + 3*wall/2 + d_out/2; module cyl_arc(d, h, beg, end) { difference() { cylinder(r = d/2+wall/2, h = h, $fn = 64); translate([0, 0, -eps]) cylinder(r = d/2-wall/2, h=h+2*eps, $fn = 64); if (end-beg > 180) { intersection() { rotate([0, 0, beg]) scale([1, -1, 1]) translate([-infty/2, 0, -eps]) cube(infty); rotate([0, 0, end]) translate([-infty/2, 0, -eps]) cube(infty); } } else { union() { rotate([0, 0, beg]) scale([1, -1, 1]) translate([-infty/2, 0, -eps]) cube(infty); rotate([0, 0, end-180]) scale([1, -1, 1]) translate([-infty/2, 0, -eps]) cube(infty); } } } } // main box module main_box() { difference() { translate([-batt_d/2-wall, 0, 0]) cube([batt_d + 2*wall, straight_l, body_h]); // upper part at the - pole translate([-batt_d/2, wall, batt_d/2]) cube([batt_d, (batt_l-cyl_center_h)/2, batt_d + 2*eps]); // the battery itself translate([0, wall, batt_d_real/2]) rotate([-90, 0, 0]) cylinder(r = batt_d/2, h = straight_l, $fn = 64); // upper part of the clip translate([0, wall, batt_d_real/2+2*top_clip_h]) rotate([-90, 0, 0]) cylinder(r = batt_d/2, h = straight_l, $fn = 64); // upper part at the + pole translate([-batt_d/2, wall+(batt_l-cyl_center_h)/2+cyl_center_h, batt_d/2]) cube([batt_d, (batt_l-cyl_center_h)/2, batt_d + 2*eps]); // at the clip - sides only translate([-batt_d/2, batt_l, -eps]) cube([batt_d, straight_l-batt_l+eps, batt_d + 2*eps]); } } // spring, x-axis cenered, to be connected by y-minus axis module spring() { for (x = [-1, 1]) scale([x, 1, 1]) { // outmost d_out arc translate([d_out/2+wall/2+spring_sep/2, 0, 0]) cyl_arc(d_out, body_h, 0-eps, 180+eps); // inner center d_in arc translate([spring_sep/2+wall/2+d_in/2, 0, 0]) cyl_arc(d_in, body_h, 180, 360+eps); // outer center d_in arc translate([spring_sep/2+wall/2+3*d_in/2, 0, 0]) cyl_arc(d_in, body_h, -eps, 180+eps); // innermost d_out arc translate([2*d_in+wall/2+spring_sep/2-d_out/2, 0, 0]) cyl_arc(d_out, body_h, 270-eps, 360+eps); } // center beam translate([-2*d_in-spring_sep/2-wall/2+d_out/2, -d_out/2-wall/2, 0]) cube([4*d_in+spring_sep+wall-d_out, wall, body_h]); } module holder() { difference() { union() { main_box(); translate([0, straight_l, 0]) spring(); } for (z = [batt_d_real/2-wire_h-wire_sep/2, batt_d_real/2+wire_sep/2]) { translate([-wire_w/2, -eps, z]) cube([wire_w, batt_l+2*wall+2*eps, wire_h]); } } } holder(); translate([batt_d+wall, straight_l + d_out/2, 0]) scale([1, -1, 1]) holder();