chiark / gitweb /
2e2a18ada5395078a65c416b236f7c6ad4cb2729
[reprap-play.git] / ksafe-base.scad
1 // -*- C -*-
2
3 // from actual ksafe
4 bolt_above = 8.50 - 0.50;
5 bolthole_height = 4.24 + 1.00;
6 wall_thick = 4.50;
7 bolthole_width = 16.62 + 2.00;
8 main_sz = 150.56 + 0.75;
9 cnr_rad = 13.5; // approx
10 lidinner_thick_allow = 20.78 + 0.50;
11 display_width = 69.81 - 0.50;
12
13 dpp3 = [ -5.5, 8.5 ];
14 dpp2 = [ -11.0, 7.0 ];
15 dpp1 = [ -34.0, 14.0 ];
16
17 // other parameters
18 web_thick = 4;
19 web_height = 20; // excluding wall and base thick
20 bolthole_rhs = 20;
21 bolthole_lhs = 20;
22 boltreinf_thick = 6;
23 anchor_wall_space = 25;
24 base_thick = 4;
25 space = 25;
26 anchor_thick = 4;
27 anchor_rad = 4;
28 bevel = 8;
29 string_slot = 3.0;
30 string_depth = 6.0;
31 thumbslot_depth = 5.0;
32 thumbslot_width = 15.0;
33 thumbslot_between = 10;
34 ksafecover_lip = 4.62;
35 display_rhs_secs = 15;
36 dcover_endthick = 3.0;
37 dcover_mainthick = 5.0;
38 dcover_slop_height = 0.35;
39 dcover_slop_depth = 0.25;
40 dcover_slop_inside = 1.50;
41 dcover_commonvertoff = 0.00; // slop_height or slop_inside is added too
42 dcover_edge_gap_more_width = 2.0; // each side
43
44 // ----- calculated -----
45
46 hsz = main_sz/2;
47
48 gppA = [0,0];
49 gppB = gppA - [ wall_thick, 0 ];
50
51 gppL = [ gppB[0], -(lidinner_thick_allow + space + base_thick) ];
52
53 yw1 = -web_thick/2;
54 yw2 = yw1 - bolthole_rhs;
55 yw3 = yw2 - anchor_thick;
56 yw4 = yw3 - anchor_wall_space;
57 yw5 = yw4 - wall_thick;
58 yw6 = -(hsz - cnr_rad + 0.1);
59
60 yw10 = web_thick/2;
61 yw11 = yw2 + anchor_wall_space;
62 yw12 = yw11 + wall_thick;
63 yw13 = -yw6;
64
65 cpp1 = dpp1 + [  dcover_slop_depth, dcover_slop_height ];
66 cpp2 = [ dpp2[0] - dcover_slop_depth, dpp3[1] + dcover_slop_height ];
67 cppH = cpp1 + [ 0, dcover_endthick ];
68 cppA = [ cpp2[0], dpp3[1] + dcover_slop_inside ];
69 cppK = cppA + [ 0, dcover_mainthick ];
70 cppZ = [ -ksafecover_lip, -dcover_commonvertoff ];
71 cppD = cppZ + [ 0, -dcover_slop_inside ];
72 cppE = cppD + [ 0, -dcover_mainthick ];
73 cppC = [ dcover_slop_inside, cppD[1] ];
74 cppF = cppC + dcover_mainthick * [1,-1];
75 cppB = [ cppC[0], cppA[1] ];
76 cppG = [ cppF[0], cppK[1] ];
77
78 // anchor
79
80 anchor_b = anchor_thick + anchor_rad;
81 appM = gppL + anchor_b * [1,1];
82
83 a_bevel = 2 * anchor_b * (1 + sqrt(0.5));
84
85 module upp_app_Vars(t_bevel){
86   $xppE = gppL + t_bevel * [0,1];
87   $xppF = gppL + t_bevel * [1,0];
88
89   $xppJ = $xppE + wall_thick * [ 1, tan(22.5) ];
90   $xppI = $xppF + base_thick * [ tan(22.5), 1 ];
91
92   // must pass a_bevel for t_bevel for these to be valid
93   $gppP = gppA + [0,-1] * lidinner_thick_allow;
94   $gppQ = $gppP + [1,-1] * web_height;
95   $gppR = $xppJ + [ 1, tan(22.5) ] * web_height;
96   $gppS = $xppI + [ tan(22.5), 1 ] * web_height;
97   $gppT = [ $gppQ[0], $xppE[1] ];
98
99   children();
100 }
101
102 module upp_app_Profile(){
103   polygon([ gppA,
104             gppB,
105             $xppE,
106             $xppF,
107             $xppF + [1,0],
108             $xppI + [1,0],
109             $xppJ ],
110           convexity=10);
111 }
112
113
114 module UsualProfile(){
115   upp_app_Vars(bevel) upp_app_Profile();
116 }
117
118 module NearAnchorProfile(){
119   upp_app_Vars(a_bevel) upp_app_Profile();
120 }
121
122 module AnchorProfile(){
123   upp_app_Vars(a_bevel) {
124
125     upp_app_Profile();
126
127     difference(){
128       hull(){
129         polygon([ $xppE,
130                   $xppF,
131                   $xppF + [0,1],
132                   $xppE + [1,0] ],
133           convexity=10);
134         translate(appM) circle(r= anchor_b);
135       }
136       translate(appM) circle(r= anchor_rad);
137     }
138   }
139 }
140
141 module AnchorWallProfile(){
142   UsualProfile();
143   NearAnchorProfile();
144   hull(){
145     for (bev = [bevel, a_bevel]) {
146       upp_app_Vars(bev) {
147         polygon([ $xppE,
148                   $xppF,
149                   $xppI,
150                   $xppJ ],
151           convexity=10);
152       }
153     }
154   }
155 }
156
157 module WebProfile(){
158   upp_app_Vars(a_bevel){
159     if ($gppR[1] <= $gppP[1]) {
160       polygon([ $gppP,
161                 $xppE,
162                 $gppT,
163                 $gppQ ]);
164       polygon([ $gppP,
165                 $xppE,
166                 $xppF,
167                 $gppS,
168                 $gppR ],
169           convexity=10);
170     } else {
171       polygon([ $gppP,
172                 $xppE,
173                 $xppF,
174                 $gppS,
175                 $gppP + web_height * [1,0] ],
176           convexity=10);
177     }
178     polygon([ $gppS,
179               $xppF,
180               $xppF + [1,0],
181               $gppS + [1,0] ],
182           convexity=10);
183   }
184 }
185
186 module SomeBaseProfile(I, F){
187   polygon([ I,
188             F,
189             [ hsz+1, F[1] ],
190             [ hsz+1, I[1] ] ]);
191 }
192
193 module BaseProfile(){
194   SomeBaseProfile($xppI, $xppF);
195 }
196
197 module DCoverProfileRaw(){
198   polygon([ cpp1,
199             cpp2,
200             cppA,
201             cppB,
202             cppC,
203             cppD,
204             cppE,
205             cppF,
206             cppG,
207             cppK,
208             cppH ],
209           convexity = 10);
210 }
211
212 module DCoverProfile(){
213   mirror([1,0])
214     translate(-cppZ)
215     DCoverProfileRaw();
216 }
217
218 module SWalls(ymin, ymax, t_bevel) {
219   upp_app_Vars(t_bevel) {
220     translate([0,ymin,0])
221       mirror([0,1,0])
222       rotate([90,0,0])
223       linear_extrude(height= ymax-ymin, convexity=10)
224       for (xm=[0,1])
225         mirror([xm,0])
226           translate([-hsz, 0])
227             children();
228   }
229 }
230
231 module AtTwoCorners(){
232   for (xm=[0,1]) {
233     mirror([xm,0,0]) 
234     translate((hsz - cnr_rad) * [1,1])
235     intersection(){
236       rotate_extrude(convexity=10)
237         translate([-cnr_rad,0])
238         children();
239       translate([0,0,-250])
240         cube([50,50,500]);
241     }
242   }
243 }
244
245 module Box(){
246   /// corners, and front and back of base
247   for (ym=[0,1]) mirror([0,ym,0]) {
248     AtTwoCorners(){
249       UsualProfile();
250     }
251     hull() AtTwoCorners(){
252       upp_app_Vars(bevel){
253         polygon([ $xppI,
254                   $xppF,
255                   $xppF + [0.1, 0],
256                   $xppI + [0.1, 0]
257                   ]);
258       }
259     }
260   }
261
262   // side walls and base
263   SWalls(yw6 , yw4 , bevel  ) { UsualProfile();      BaseProfile(); }
264   SWalls(yw5 , yw4 , a_bevel) { AnchorWallProfile(); BaseProfile(); }
265   SWalls(yw5 , yw12, a_bevel) { NearAnchorProfile(); BaseProfile(); }
266   SWalls(yw3 , yw2 , a_bevel) { AnchorProfile();     BaseProfile(); }
267   SWalls(yw11, yw12, a_bevel) { AnchorWallProfile(); BaseProfile(); }
268   SWalls(yw11, yw13, bevel  ) { UsualProfile();      BaseProfile(); }
269   SWalls(yw1,  yw10, a_bevel) { WebProfile(); SomeBaseProfile($gppS, $xppF); }
270
271   // front and rear walls
272   rotate([0,0,90]) SWalls(yw6, yw13, bevel) UsualProfile();
273 }
274
275 module DCover(){ ////toplevel
276   translate([ -display_width/2, -hsz, 0 ])
277     rotate([0,90,0])
278     rotate([0,0,90])
279     linear_extrude( display_width - display_rhs_secs, convexity = 10)
280     DCoverProfile();
281 }
282
283 module DCoverSupportAllowance(){
284   translate([0, -hsz, 0])
285     cube(center=true,
286          [ display_width + 2 * dcover_edge_gap_more_width,
287            wall_thick * 2,
288            dcover_slop_inside * 2 + 0.01 ]);
289 }
290
291 module KsafeBase(){ ////toplevel
292   cut = main_sz + 20;
293
294   DCover();
295
296   difference(){
297     Box();
298
299     // bolt holes
300     translate([0,0, -bolt_above -0.5 * bolthole_height])
301       cube(center=true, [ cut, bolthole_width, bolthole_height ]);
302
303     // string slot
304     translate([ -cut,
305                 -(bolthole_width/2 + bolthole_rhs),
306                 1 ])
307       mirror([0,1,0]) mirror([0,0,1])
308       cube([ cut*2,
309              string_slot,
310              lidinner_thick_allow + string_depth + 1 ]);
311
312     // thumb slots
313     for (mx=[0,1]) mirror([mx,0,0]) {
314       translate([ thumbslot_between/2,
315                   0,
316                   -thumbslot_depth ])
317         cube([ thumbslot_width,
318                cut,
319                thumbslot_depth+1 ]);
320     }
321
322     DCoverSupportAllowance();
323   }
324 }
325
326 module DemoProfiles(){ ////toplevel
327   translate([0,0,-2]) color("yellow") AnchorWallProfile();
328   color("red") AnchorProfile();
329   translate([0,0,2]) color("black") NearAnchorProfile();
330   translate([0,0,4]) color("blue") UsualProfile();
331   translate([0,0,-4]) color("pink") WebProfile();
332   translate([0,0,6]) color("purple") DCoverProfile();
333 }
334
335 module RimTest(){ ////toplevel
336   intersection(){
337     Box();
338     cube(center=true, [ main_sz*2, main_sz*2,
339                         2.5 ]);
340   }
341 }
342
343 module DCoverTest(){ ////toplevel
344   intersection(){
345     union(){
346       Box();
347       DCover();
348     }
349     translate([0,0,60])
350     cube(center=true, [ main_sz*2, main_sz*2,
351                         2 * (60 + 3.0) ]);
352   }
353 }
354
355 module BoltTest(){ ////toplevel
356   dy = 0.5 * (bolthole_width+4);
357   intersection(){
358     KsafeBase();
359     translate([ 0, -dy, -(bolt_above + bolthole_height + 1) ])
360       cube([ main_sz, dy*2, 50 ]);
361   }
362 }
363
364 //DemoProfiles();
365 //Box();
366 //KsafeBase();
367 //RimTest();