add 3030 dampener feet
[ozzloy@gmail.com/3d-printables] / spin-data.scad
CommitLineData
818dd661 1/* GNU AGPLv3 (or later at your option)
2 see bottom for more license info */
3
4/* spin thing that erin likes */
0c7b5029 5$fn = 75;
cc410ed6 6
5f8325d2 7layer_height = 0.35;
818dd661 8
9weight = "penny";
10// weight = "608zz";
0c7b5029 11
3e3691aa 12bearing = "608zz";
0c7b5029 13// bearing = "625rs";
14
cc410ed6 15weight_lip_overhang = 0.3;
16bearing_lip_overhang = weight_lip_overhang;
cc410ed6 17wall = 3;
2645ef26 18penny_thickness = 1.52;
818dd661 19penny_radius = 19.05 / 2;
7f1519fb 20
21_608zz_radius = 22 / 2;
22_608zz_inner_radius = 8.1 / 2;
8d55712b 23_608zz_cover_radius = _608zz_radius;
7f1519fb 24_608zz_cap_footprint_radius = 12 / 2;
25_608zz_thickness = 7;
26
0c7b5029 27_625rs_radius = 16 / 2;
28_625rs_inner_radius = 5 / 2;
29_625rs_thickness = 5;
30_625rs_cover_radius = _625rs_radius;
31_625rs_cap_footprint_radius = _625rs_inner_radius + 1;
32
818dd661 33weight_radius = (weight == "penny") ? penny_radius : _608zz_radius;
2645ef26 34weight_thickness = (weight == "penny") ?
35 penny_thickness * 5 : _608zz_thickness;
7f1519fb 36
0c7b5029 37bearing_radius =
38 (bearing == "608zz") ? _608zz_radius
39 : (bearing == "625rs") ? _625rs_radius
40 : 1/0;
3381230e 41bearing_window_radius = bearing_radius - bearing_lip_overhang - 1;
0c7b5029 42bearing_inner_radius =
43 (bearing == "608zz") ? _608zz_inner_radius
04db4766 44 : (bearing == "625rs") ? _625rs_inner_radius
0c7b5029 45 : 1/0;
46bearing_cover_radius =
47 (bearing == "608zz") ? _608zz_cover_radius
48 : (bearing == "625rs") ? _625rs_cover_radius
49 : 1/0;
7f1519fb 50bearing_cap_footprint_radius =
0c7b5029 51 (bearing == "608zz") ? _608zz_cap_footprint_radius
52 : (bearing == "625rs" ) ? _625rs_cap_footprint_radius
53 : 1/0;
54bearing_thickness =
55 (bearing == "608zz") ? _608zz_thickness
56 : (bearing == "625rs") ? _625rs_thickness
57 : 1/0;
7f1519fb 58
59spinner_height = penny_thickness * 5 + 2;
818dd661 60arms = 3;
61
7f1519fb 62module cap(bearing_inner_radius,
63 bearing_cap_footprint_radius,
64 bearing_cover_radius,
3381230e 65 bearing_thickness,
66 bearing_window_radius) {
67 footprint_height = 4.5;
68 footprint_radius_safety = 0.2;
7f1519fb 69 cap_height = 3;
3381230e 70 bearing_thickness_safety = 0.6;
23616d65 71 finger_spot_height = cap_height * 2 / 3;
72 stripes = 3;
7f1519fb 73
74 difference() {
75 union() {
76 cylinder(r1 = bearing_cover_radius - tan(30) * cap_height,
77 r2 = bearing_cover_radius,
78 h = cap_height);
3381230e 79 linear_extrude(height = cap_height
80 + footprint_height
81 - 1.05) {
82 circle(bearing_window_radius - 1); }
7f1519fb 83 linear_extrude(height = cap_height + footprint_height) {
84 circle(bearing_cap_footprint_radius - footprint_radius_safety); }
85 linear_extrude(height = cap_height
86 + footprint_height
87 + bearing_thickness / 2
88 - bearing_thickness_safety) {
23616d65 89 circle(bearing_inner_radius + 0.1); } }
7f1519fb 90 translate([0, 0, -0.01]) {
3381230e 91 cylinder(r1 = bearing_inner_radius,
92 r2 = bearing_inner_radius - tan(30) * finger_spot_height,
23616d65 93 h = finger_spot_height);
94 for(stripe = [0 : stripes - 1]) {
95 rotate((stripe / stripes) * 360) {
96 linear_extrude(height = finger_spot_height) {
97 polygon([[0, 0],
98 [bearing_cover_radius * 2, 0],
99 [cos(3 + 360 / (stripes * 2))
100 * bearing_cover_radius * 2,
101 sin(3 + 360 / (stripes * 2))
102 * bearing_cover_radius * 2]]); } } } } } }
7f1519fb 103
d4c56d9d 104module donut(height, footprint_radius) {
105 bread_radius = height / 2;
106 rotate_extrude() {
107 translate([footprint_radius, 0]) {
108 circle(bread_radius); } } }
109
110module donut_hole(height, footprint_radius) {
111 difference() {
112 cylinder(r = footprint_radius, h = height, center = true);
113 donut(height, footprint_radius); } }
114
115module jelly_filled(height, footprint_radius) {
116 cylinder(r = footprint_radius, h = height, center = true);
117 donut(height, footprint_radius); }
118
cc410ed6 119module fillet(r) {
120 offset(r = -r) { offset(delta = r) { children(); } } }
121
cc410ed6 122module mirrored(axis) {
123 children();
124 mirror(axis) children(); }
2645ef26 125
5f8325d2 126module spin_slice(weight_radius,
127 bearing_radius,
128 round_extra,
129 wall,
130 arms) {
131 joiner_radius = (bearing_radius + weight_radius) / 2;
132
5f8325d2 133 // a = side along x axis
134 a = bearing_radius + weight_radius + wall;
135 // b = side from center to joiner
136 b = bearing_radius + joiner_radius + round_extra;
137 // c = side between joiner and arm center
138 c = joiner_radius + weight_radius + round_extra;
139
5f8325d2 140 cos_C = (pow(a, 2) + pow(b, 2) - pow(c, 2)) / (2 * a * b);
141 sin_C = sqrt(1 - pow(cos_C, 2));
142
85cda07f 143 bearing_xy = [0, 0];
144 weight_xy = [a, 0];
5f8325d2 145 joiner_xy = [cos_C, sin_C] * b;
146
147 for(arm = [0 : arms - 1]) {
148 rotate(arm * (360 / arms)) {
149 difference() {
150 union() {
151 translate(bearing_xy) {
152 circle(bearing_radius + round_extra); }
153 translate(weight_xy) {
154 circle(weight_radius + round_extra); }
155 mirrored([0, 1]) {
156 polygon([bearing_xy, weight_xy, joiner_xy]); } }
157 mirrored([0, 1]) {
158 translate(joiner_xy) {
159 circle(joiner_radius); } } } } } }
160
85cda07f 161module spin_cosine_slice(weight_radius,
162 bearing_radius,
163 round_extra,
164 wall,
165 arms) {
166 /* in order to make a smooth transition from one arm to the next,
167 follow the path of a circle just barely touching both arms and
168 the center circle. this is referred to as the joiner circle.
169
170 the joiner circle's radius and position are calculated using
171 geometry. the center of the bearing, weight and joiner circle
172 create a triangle.
173
174 a = side between bearing and weight centers
175 b = side between bearing and joiner centers
176 c = side between joiner and weight centers
177
178 A = angle opposite a, inside joiner
179 B = angle opposite b, inside weight
180 C = angle opposite c, inside bearing
181 */
182
183 r0 = bearing_radius;
184 r1 = weight_radius;
185 // slightly cheated. calculated using 3 arms, C = 60.
186 r2 = ((pow(r0, 2)
187 + r0 * wall
188 + r0 * r1
189 + pow(wall, 2)
190 + 2 * r1 * wall
191 + r0 * round_extra
192 - wall * round_extra
193 - 3 * r1 * round_extra)
194 / (3 * r1 + wall - r0));
195
196 joiner_radius = r2;
197
198 // a = side along x axis
199 a = r0 + wall + r1;
200 // b = side from center to joiner
201 b = r0 + round_extra + r2;
202 // c = side between joiner and arm center
203 c = r1 + round_extra + r2;
204
205 bearing_xy = [0, 0];
206 weight_xy = [a, 0];
207 joiner_xy = [cos(60), sin(60)] * b;
208
209 translate(bearing_xy) {
210 circle(bearing_radius + round_extra); }
211 for(arm = [0 : arms - 1]) {
212 rotate(arm * (360 / arms)) {
213 translate(weight_xy) {
214 circle(weight_radius + round_extra); }
215 mirrored([0, 1]) {
216 difference() {
217 polygon([bearing_xy, weight_xy, joiner_xy]);
218 translate(joiner_xy) {
219 circle(joiner_radius); } } } } } }
220
5f8325d2 221module spin_slices(weight_radius,
222 weight_thickness,
223 bearing_radius,
224 bearing_thickness,
225 weight_lip_overhang = 0.3,
226 bearing_lip_overhang = 0.3,
227 wall = 3,
228 arms = 3,
229 layer_height = 0.15) {
cc410ed6 230 thicker_thickness = (bearing_thickness > weight_thickness) ?
231 bearing_thickness : weight_thickness;
232 calculated_height = thicker_thickness + 2 * wall;
233 layers = 2 * ceil(ceil(calculated_height / layer_height) / 2);
234 actual_height = layers * layer_height;
235 round_radius = actual_height / 2;
236
5f8325d2 237 /* rounding the outside edge of the spinner with a semi-circle leads
238 to a shape that an overhang on the second layer several times the
239 thickness of a printed extrusion width.
240
241 rather than using a full semi-circle, this code aims to use just the
242 portion in the middle, where the overhang is less severe */
e1a02727 243 old_start = 0;
244 old_end = (layers / 2) - 1;
245
5f8325d2 246 /* add one to have some thickness all around weight holes
247 for first layer */
5fdbde1b 248 new_start = old_end / 16 + 1;
e1a02727 249 new_end = old_end;
250
251 old_range = old_end - old_start;
252 new_range = new_end - new_start;
253
254 factor = new_range / old_range;
255
5f8325d2 256 /* initial adjacent is adjusted to (new start - 1) to allow some
257 thickness all around weight holes on first layer */
258 initial_adjacent = round_radius - ((new_start - 1) * layer_height);
e1a02727 259 initial_angle = acos(initial_adjacent / round_radius);
260 initial_round_extra = initial_adjacent * tan(initial_angle);
5f8325d2 261
262 difference() {
263 mirrored([0, 0, 1]) {
264 for(layer = [0 : (layers / 2) - 1]) {
265 translate([0, 0, layer * layer_height - actual_height / 2]) {
266 linear_extrude(height = layer_height) {
267 new_layer = (layer - old_start) * factor + new_start;
268 adjacent = round_radius - (new_layer * layer_height);
269 angle = acos(adjacent / round_radius);
270 round_extra = adjacent * tan(angle) - initial_round_extra;
271 spin_slice(weight_radius,
272 bearing_radius,
273 round_extra,
274 wall,
275 arms); } } } }
85cda07f 276 cylinder(h = actual_height + 0.1,
277 r = bearing_radius - bearing_lip_overhang,
278 center = true);
279 cylinder(h = bearing_thickness + 0.05,
280 r = bearing_radius + 0.15,
281 center = true);
282 for(arm = [0 : arms - 1]) {
283 rotate(arm * (360 / arms)) {
284 translate([bearing_radius + wall + weight_radius, 0]) {
285 cylinder(h = actual_height + 0.1,
286 r = weight_radius - weight_lip_overhang,
287 center = true);
288 cylinder(h = weight_thickness + 0.05,
289 r = weight_radius + 0.15,
290 center = true); } } } } }
291
292module spin_cosine(weight_radius,
293 weight_thickness,
294 bearing_radius,
295 bearing_thickness,
296 weight_lip_overhang = 0.3,
297 bearing_lip_overhang = 0.3,
298 wall = 3,
299 arms = 3,
300 layer_height = 0.15) {
301 thicker_thickness = (bearing_thickness > weight_thickness) ?
302 bearing_thickness : weight_thickness;
303 calculated_height = thicker_thickness + 2 * wall;
304 layers = 2 * ceil(ceil(calculated_height / layer_height) / 2);
305 actual_height = layers * layer_height;
306 round_radius = actual_height / 2;
307
308 /* rounding the outside edge of the spinner with a semi-circle leads
309 to a shape that an overhang on the second layer several times the
310 thickness of a printed extrusion width.
311
312 rather than using a full semi-circle, this code aims to use just the
313 portion in the middle, where the overhang is less severe */
314 old_start = 0;
315 old_end = (layers / 2) - 1;
316
317 /* add one to have some thickness all around weight holes
318 for first layer */
319 new_start = old_end / 16 + 1;
320 new_end = old_end;
321
322 old_range = old_end - old_start;
323 new_range = new_end - new_start;
324
325 factor = new_range / old_range;
326
327 /* initial adjacent is adjusted to (new start - 1) to allow some
328 thickness all around weight holes on first layer */
329 initial_adjacent = round_radius - ((new_start - 1) * layer_height);
330 initial_angle = acos(initial_adjacent / round_radius);
331 initial_round_extra = initial_adjacent * tan(initial_angle);
332
333 difference() {
334 mirrored([0, 0, 1]) {
335 for(layer = [0 : (layers / 2) - 1]) {
336 translate([0, 0, layer * layer_height - actual_height / 2]) {
337 linear_extrude(height = layer_height) {
338 new_layer = (layer - old_start) * factor + new_start;
339 adjacent = round_radius - (new_layer * layer_height);
340 angle = acos(adjacent / round_radius);
341 round_extra = adjacent * tan(angle) - initial_round_extra;
342 spin_cosine_slice(weight_radius,
343 bearing_radius,
344 round_extra,
345 wall,
346 arms); } } } }
baad6cfa 347 // bearing window hole
348 /*cylinder(h = actual_height + 0.1,
5f8325d2 349 r = bearing_radius - bearing_lip_overhang,
baad6cfa 350 center = true);*/
351 linear_extrude(height = actual_height + 0.1, center = true) {
352 intersection() {
353 polygon([[bearing_radius + 3 * wall, 0],
354 [cos(120) * (bearing_radius + 3 * wall),
355 sin(120) * (bearing_radius + 3 * wall)],
356 [cos(240) * (bearing_radius + 3 * wall),
357 sin(240) * (bearing_radius + 3 * wall)]]);
358 circle(bearing_radius + 0.1); } }
359 // bearing cavity
5fdbde1b 360 cylinder(h = bearing_thickness + 0.05,
361 r = bearing_radius + 0.15,
5f8325d2 362 center = true);
baad6cfa 363 // arm holes
5f8325d2 364 for(arm = [0 : arms - 1]) {
365 rotate(arm * (360 / arms)) {
366 translate([bearing_radius + wall + weight_radius, 0]) {
baad6cfa 367 // weight window hole
368 mirrored([0, 0, 1]) {
369 translate([0, 0, (weight_thickness + 0.05) / 2]) {
370 linear_extrude(height = wall + 0.1) {
371 intersection(){
372 polygon([[cos(0) * (weight_radius + 2.5 * wall),
373 sin(0) * (weight_radius + 2.5 * wall)],
374 [cos(120) * (weight_radius + 2.5 * wall),
375 sin(120) * (weight_radius + 2.5 * wall)],
376 [cos(240) * (weight_radius + 2.5 * wall),
377 sin(240) * (weight_radius + 2.5 * wall)]]);
378 circle(weight_radius + 0.2); } } } }
379 // weight cavity
5fdbde1b 380 cylinder(h = weight_thickness + 0.05,
baad6cfa 381 r = weight_radius + 0.20,
5f8325d2 382 center = true); } } } } }
818dd661 383
1dc634e1 384module spin_donut(weight_radius,
385 weight_thickness,
386 bearing_radius,
387 bearing_thickness,
388 weight_lip_overhang,
389 bearing_lip_overhang,
390 wall,
391 arms) {
392 thicker_thickness = (bearing_thickness > weight_thickness)
393 ? bearing_thickness : weight_thickness;
394 height = thicker_thickness + wall * 2;
395
396 center_to_arm_center = bearing_radius + wall + weight_radius;
397
398 jelly_filled(height, bearing_radius);
399 for(arm = [0 : arms]) {
400 rotate(arm * (360 / arms)) {
401 translate([center_to_arm_center, 0, 0]) {
402 jelly_filled(height, weight_radius); } } } }
403
818dd661 404/*
405 This file is part of 3d-printables.
406
407 3d-printables is free software: you can redistribute it and/or modify
408 it under the terms of the GNU Affero General Public License as published by
409 the Free Software Foundation, either version 3 of the License, or
410 (at your option) any later version.
411
412 3d-printables is distributed in the hope that it will be useful,
413 but WITHOUT ANY WARRANTY; without even the implied warranty of
414 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
415 GNU Affero General Public License for more details.
416
417 You should have received a copy of the GNU Affero General Public License
418 along with challenge-bot. If not, see <http://www.gnu.org/licenses/>.
419*/