/* GNU AGPLv3 (or later at your option) see bottom for more license info */ /* spin thing that erin likes */ $fn = 75; layer_height = 0.35; weight = "penny"; // weight = "608zz"; bearing = "608zz"; // bearing = "625rs"; weight_lip_overhang = 0.3; bearing_lip_overhang = weight_lip_overhang; wall = 3; penny_thickness = 1.52; penny_radius = 19.05 / 2; _608zz_radius = 22 / 2; _608zz_inner_radius = 8.1 / 2; _608zz_cover_radius = _608zz_radius; _608zz_cap_footprint_radius = 12 / 2; _608zz_thickness = 7; _625rs_radius = 16 / 2; _625rs_inner_radius = 5 / 2; _625rs_thickness = 5; _625rs_cover_radius = _625rs_radius; _625rs_cap_footprint_radius = _625rs_inner_radius + 1; weight_radius = (weight == "penny") ? penny_radius : _608zz_radius; weight_thickness = (weight == "penny") ? penny_thickness * 5 : _608zz_thickness; bearing_radius = (bearing == "608zz") ? _608zz_radius : (bearing == "625rs") ? _625rs_radius : 1/0; bearing_window_radius = bearing_radius - bearing_lip_overhang - 1; bearing_inner_radius = (bearing == "608zz") ? _608zz_inner_radius : (bearing == "625rs") ? _608zz_inner_radius : 1/0; bearing_cover_radius = (bearing == "608zz") ? _608zz_cover_radius : (bearing == "625rs") ? _625rs_cover_radius : 1/0; bearing_cap_footprint_radius = (bearing == "608zz") ? _608zz_cap_footprint_radius : (bearing == "625rs" ) ? _625rs_cap_footprint_radius : 1/0; bearing_thickness = (bearing == "608zz") ? _608zz_thickness : (bearing == "625rs") ? _625rs_thickness : 1/0; spinner_height = penny_thickness * 5 + 2; arms = 3; module cap(bearing_inner_radius, bearing_cap_footprint_radius, bearing_cover_radius, bearing_thickness, bearing_window_radius) { footprint_height = 4.5; footprint_radius_safety = 0.2; cap_height = 3; bearing_thickness_safety = 0.6; finger_spot_height = cap_height / 10; difference() { union() { cylinder(r1 = bearing_cover_radius - tan(30) * cap_height, r2 = bearing_cover_radius, h = cap_height); linear_extrude(height = cap_height + footprint_height - 1.05) { circle(bearing_window_radius - 1); } linear_extrude(height = cap_height + footprint_height) { circle(bearing_cap_footprint_radius - footprint_radius_safety); } linear_extrude(height = cap_height + footprint_height + bearing_thickness / 2 - bearing_thickness_safety) { circle(bearing_inner_radius); } } translate([0, 0, -0.01]) { cylinder(r1 = bearing_inner_radius, r2 = bearing_inner_radius - tan(30) * finger_spot_height, h = finger_spot_height); } } } module donut(height, footprint_radius) { bread_radius = height / 2; rotate_extrude() { translate([footprint_radius, 0]) { circle(bread_radius); } } } module donut_hole(height, footprint_radius) { difference() { cylinder(r = footprint_radius, h = height, center = true); donut(height, footprint_radius); } } module jelly_filled(height, footprint_radius) { cylinder(r = footprint_radius, h = height, center = true); donut(height, footprint_radius); } module fillet(r) { offset(r = -r) { offset(delta = r) { children(); } } } module mirrored(axis) { children(); mirror(axis) children(); } module spin_slice(weight_radius, bearing_radius, round_extra, wall, arms) { joiner_radius = (bearing_radius + weight_radius) / 2; bearing_xy = [0, 0]; // a = side along x axis a = bearing_radius + weight_radius + wall; // b = side from center to joiner b = bearing_radius + joiner_radius + round_extra; // c = side between joiner and arm center c = joiner_radius + weight_radius + round_extra; weight_xy = [a, 0]; cos_C = (pow(a, 2) + pow(b, 2) - pow(c, 2)) / (2 * a * b); sin_C = sqrt(1 - pow(cos_C, 2)); joiner_xy = [cos_C, sin_C] * b; for(arm = [0 : arms - 1]) { rotate(arm * (360 / arms)) { difference() { union() { translate(bearing_xy) { circle(bearing_radius + round_extra); } translate(weight_xy) { circle(weight_radius + round_extra); } mirrored([0, 1]) { polygon([bearing_xy, weight_xy, joiner_xy]); } } mirrored([0, 1]) { translate(joiner_xy) { circle(joiner_radius); } } } } } } module spin_slices(weight_radius, weight_thickness, bearing_radius, bearing_thickness, weight_lip_overhang = 0.3, bearing_lip_overhang = 0.3, wall = 3, arms = 3, layer_height = 0.15) { thicker_thickness = (bearing_thickness > weight_thickness) ? bearing_thickness : weight_thickness; calculated_height = thicker_thickness + 2 * wall; layers = 2 * ceil(ceil(calculated_height / layer_height) / 2); actual_height = layers * layer_height; round_radius = actual_height / 2; /* rounding the outside edge of the spinner with a semi-circle leads to a shape that an overhang on the second layer several times the thickness of a printed extrusion width. rather than using a full semi-circle, this code aims to use just the portion in the middle, where the overhang is less severe */ old_start = 0; old_end = (layers / 2) - 1; /* add one to have some thickness all around weight holes for first layer */ new_start = old_end / 16 + 1; new_end = old_end; old_range = old_end - old_start; new_range = new_end - new_start; factor = new_range / old_range; /* initial adjacent is adjusted to (new start - 1) to allow some thickness all around weight holes on first layer */ initial_adjacent = round_radius - ((new_start - 1) * layer_height); initial_angle = acos(initial_adjacent / round_radius); initial_round_extra = initial_adjacent * tan(initial_angle); difference() { mirrored([0, 0, 1]) { for(layer = [0 : (layers / 2) - 1]) { translate([0, 0, layer * layer_height - actual_height / 2]) { linear_extrude(height = layer_height) { new_layer = (layer - old_start) * factor + new_start; adjacent = round_radius - (new_layer * layer_height); angle = acos(adjacent / round_radius); round_extra = adjacent * tan(angle) - initial_round_extra; spin_slice(weight_radius, bearing_radius, round_extra, wall, arms); } } } } cylinder(h = actual_height + 0.1, r = bearing_radius - bearing_lip_overhang, center = true); cylinder(h = bearing_thickness + 0.05, r = bearing_radius + 0.15, center = true); for(arm = [0 : arms - 1]) { rotate(arm * (360 / arms)) { translate([bearing_radius + wall + weight_radius, 0]) { cylinder(h = actual_height + 0.1, r = weight_radius - weight_lip_overhang, center = true); cylinder(h = weight_thickness + 0.05, r = weight_radius + 0.15, center = true); } } } } } module spin_donut(weight_radius, weight_thickness, bearing_radius, bearing_thickness, weight_lip_overhang, bearing_lip_overhang, wall, arms) { thicker_thickness = (bearing_thickness > weight_thickness) ? bearing_thickness : weight_thickness; height = thicker_thickness + wall * 2; center_to_arm_center = bearing_radius + wall + weight_radius; jelly_filled(height, bearing_radius); for(arm = [0 : arms]) { rotate(arm * (360 / arms)) { translate([center_to_arm_center, 0, 0]) { jelly_filled(height, weight_radius); } } } } /* This file is part of 3d-printables. 3d-printables is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 3d-printables is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with challenge-bot. If not, see . */