see bottom for more license info */
/* spin thing that erin likes */
-$fn = 50;
+$fn = 75;
layer_height = 0.35;
weight = "penny";
// weight = "608zz";
-bearing = "608zz";
+
+//bearing = "608zz";
+bearing = "sr188";
+// bearing = "625rs";
+
weight_lip_overhang = 0.3;
bearing_lip_overhang = weight_lip_overhang;
wall = 3;
penny_thickness = 1.52;
penny_radius = 19.05 / 2;
+sr188_radius = 12.74 / 2; // 0.5 / 2
+sr188_inner_radius = 6.3 / 2; // 0.2470 / 2
+sr188_thickness = 4.8; // 0.1895 inch
+sr188_cover_radius = sr188_radius;
+sr188_cap_footprint_radius = 12 / 2;
+
_608zz_radius = 22 / 2;
_608zz_inner_radius = 8.1 / 2;
-_608zz_cover_radius = 19.4 / 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 : 1/0;
-bearing_inner_radius = (bearing == "608zz") ? _608zz_inner_radius : 1/0;
-bearing_cover_radius = (bearing == "608zz")
- ? _608zz_cover_radius + wall
- : 1/0;
+bearing_radius =
+ (bearing == "608zz") ? _608zz_radius
+ : (bearing == "625rs") ? _625rs_radius
+ : (bearing == "sr188") ? sr188_radius
+ : 1/0;
+bearing_window_radius = bearing_radius - bearing_lip_overhang - 1;
+bearing_inner_radius =
+ (bearing == "608zz") ? _608zz_inner_radius
+ : (bearing == "625rs") ? _625rs_inner_radius
+ : (bearing == "sr188") ? sr188_inner_radius
+ : 1/0;
+bearing_cover_radius =
+ (bearing == "608zz") ? _608zz_cover_radius
+ : (bearing == "625rs") ? _625rs_cover_radius
+ : (bearing == "sr188") ? sr188_cover_radius
+ : 1/0;
bearing_cap_footprint_radius =
- (bearing == "608zz") ? _608zz_cap_footprint_radius : 1/0;
-bearing_thickness = (bearing == "608zz") ? _608zz_thickness : 1/0;
+ (bearing == "608zz") ? _608zz_cap_footprint_radius
+ : (bearing == "625rs" ) ? _625rs_cap_footprint_radius
+ : (bearing == "sr188" ) ? sr188_cap_footprint_radius
+ : 1/0;
+bearing_thickness =
+ (bearing == "608zz") ? _608zz_thickness
+ : (bearing == "625rs") ? _625rs_thickness
+ : (bearing == "sr188") ? sr188_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) {
- footprint_height = 1.6;
- footprint_radius_safety = 0.25;
+ bearing_thickness,
+ bearing_window_radius) {
+ footprint_height = 4.5;
+ footprint_radius_safety = 0.2;
cap_height = 3;
- bearing_cover_radius_safety = 0.75;
- bearing_thickness_safety = 0.2;
+ bearing_thickness_safety = 0.6;
+ finger_spot_height = cap_height * 2 / 3;
+ stripes = 3;
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); } }
+ circle(bearing_inner_radius + 0.1); } }
translate([0, 0, -0.01]) {
- cylinder(r1 = bearing_inner_radius + tan(30) * (cap_height - 1),
- r2 = bearing_inner_radius,
- h = cap_height - 1); } } }
+ cylinder(r1 = bearing_inner_radius,
+ r2 = bearing_inner_radius - tan(30) * finger_spot_height,
+ h = finger_spot_height);
+ for(stripe = [0 : stripes - 1]) {
+ rotate((stripe / stripes) * 360) {
+ linear_extrude(height = finger_spot_height) {
+ polygon([[0, 0],
+ [bearing_cover_radius * 2, 0],
+ [cos(3 + 360 / (stripes * 2))
+ * bearing_cover_radius * 2,
+ sin(3 + 360 / (stripes * 2))
+ * bearing_cover_radius * 2]]); } } } } } }
module donut(height, footprint_radius) {
bread_radius = height / 2;
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
// 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));
+ bearing_xy = [0, 0];
+ weight_xy = [a, 0];
joiner_xy = [cos_C, sin_C] * b;
for(arm = [0 : arms - 1]) {
translate(joiner_xy) {
circle(joiner_radius); } } } } } }
+module spin_cosine_slice(weight_radius,
+ bearing_radius,
+ round_extra,
+ wall,
+ arms) {
+ /* in order to make a smooth transition from one arm to the next,
+ follow the path of a circle just barely touching both arms and
+ the center circle. this is referred to as the joiner circle.
+
+ the joiner circle's radius and position are calculated using
+ geometry. the center of the bearing, weight and joiner circle
+ create a triangle.
+
+ a = side between bearing and weight centers
+ b = side between bearing and joiner centers
+ c = side between joiner and weight centers
+
+ A = angle opposite a, inside joiner
+ B = angle opposite b, inside weight
+ C = angle opposite c, inside bearing
+ */
+
+ r0 = bearing_radius;
+ r1 = weight_radius;
+ // slightly cheated. calculated using 3 arms, C = 60.
+ r2 = ((pow(r0, 2)
+ + r0 * wall
+ + r0 * r1
+ + pow(wall, 2)
+ + 2 * r1 * wall
+ + r0 * round_extra
+ - wall * round_extra
+ - 3 * r1 * round_extra)
+ / (3 * r1 + wall - r0));
+
+ joiner_radius = r2;
+
+ // a = side along x axis
+ a = r0 + wall + r1;
+ // b = side from center to joiner
+ b = r0 + round_extra + r2;
+ // c = side between joiner and arm center
+ c = r1 + round_extra + r2;
+
+ bearing_xy = [0, 0];
+ weight_xy = [a, 0];
+ joiner_xy = [cos(60), sin(60)] * b;
+
+ translate(bearing_xy) {
+ circle(bearing_radius + round_extra); }
+ for(arm = [0 : arms - 1]) {
+ rotate(arm * (360 / arms)) {
+ translate(weight_xy) {
+ circle(weight_radius + round_extra); }
+ mirrored([0, 1]) {
+ difference() {
+ polygon([bearing_xy, weight_xy, joiner_xy]);
+ translate(joiner_xy) {
+ circle(joiner_radius); } } } } } }
+
module spin_slices(weight_radius,
weight_thickness,
bearing_radius,
/* add one to have some thickness all around weight holes
for first layer */
- new_start = old_end / 8 + 1;
+ new_start = old_end / 16 + 1;
new_end = old_end;
old_range = old_end - old_start;
cylinder(h = actual_height + 0.1,
r = bearing_radius - bearing_lip_overhang,
center = true);
- cylinder(h = bearing_thickness + 0.1,
- r = bearing_radius + 0.1,
+ cylinder(h = bearing_thickness + 0.05,
+ r = bearing_radius + 0.15,
center = true);
for(arm = [0 : arms - 1]) {
rotate(arm * (360 / arms)) {
cylinder(h = actual_height + 0.1,
r = weight_radius - weight_lip_overhang,
center = true);
- cylinder(h = weight_thickness + 0.1,
- r = weight_radius + 0.1,
+ cylinder(h = weight_thickness + 0.05,
+ r = weight_radius + 0.15,
center = true); } } } } }
+module equilateral_triangle(radius){
+ polygon([[cos(0) * radius, sin(0) * radius],
+ [cos(120) * radius,
+ sin(120) * radius],
+ [cos(240) * radius,
+ sin(240) * radius]]); }
+
+module spin_cosine(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_cosine_slice(weight_radius,
+ bearing_radius,
+ round_extra,
+ wall,
+ arms); } } } }
+ // bearing window hole
+ /*cylinder(h = actual_height + 0.1,
+ r = bearing_radius - bearing_lip_overhang,
+ center = true);*/
+ linear_extrude(height = actual_height + 0.1, center = true) {
+ intersection() {
+ equilateral_triangle(1.8 * bearing_radius);
+ circle(bearing_radius + 0.1); } }
+ // bearing cavity
+ cylinder(h = bearing_thickness + 0.05,
+ r = bearing_radius + 0.15,
+ center = true);
+ // arm holes
+ for(arm = [0 : arms - 1]) {
+ rotate(arm * (360 / arms)) {
+ translate([bearing_radius + wall + weight_radius, 0]) {
+ // weight window hole
+ mirrored([0, 0, 1]) {
+ translate([0, 0, (weight_thickness + 0.05) / 2]) {
+ linear_extrude(height = wall + 0.1) {
+ intersection(){
+ equilateral_triangle(1.8 * weight_radius);
+ circle(weight_radius + 0.2); } } } }
+ // weight cavity
+ cylinder(h = weight_thickness + 0.05,
+ r = weight_radius + 0.20,
+ 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.