chiark / gitweb /
sewing-table: break out cutout_l_end_x (nfc)
[reprap-play.git] / sewing-table.scad.m4
1 // -*- C -*-
2
3 include <funcs.scad>
4 include <commitid.scad>
5
6 ply_th = 18;
7 ply_hole_dia = 15;
8 ply_edge_min = 10;
9
10 tile_th = 3;
11 post_dia = 8;
12
13 post_shorter = 1;
14
15 screw_dia = 2.2;
16 screw_big_dia = 3.6;
17 screw_big_len = 4.0;
18
19 round_edge_rad = 2.0;
20
21 round_cnr_rad = 10;
22
23 interlock_dia = 10;
24 interlock_fine = 0.66;
25
26 interlock_fine_slope = 1.0;
27 interlock_fine_lenslop = 1.0;
28
29 demo_slop = 0.1;
30
31 // cutout
32
33 cutout_l_end_y_front_slop = 0.5;
34 cutout_l_end_y_rear_slop = 0.5;
35 cutout_l_end_x_slop = 0.25;
36
37 cutout_l_end_x = 22;
38 cutout_l_end_y = 85;
39 cutout_l_end_curve = 1;
40 cutout_l_end_y_total = cutout_l_end_y
41   + cutout_l_end_y_front_slop + cutout_l_end_y_rear_slop;
42
43 tile01_tr = [250, 0];
44
45 cutout_tile01_y = 170 - 147 + cutout_l_end_y_front_slop;
46 cutout_tile11_x = cutout_l_end_x + cutout_l_end_curve;
47 cutout_tile11_y = cutout_l_end_y_total - cutout_tile01_y;
48
49 // calculated
50
51 TEST = false;
52
53 ply_edge_hole_dist = ply_edge_min + ply_hole_dia/2;
54
55 echo(str("HOLES IN PLY ctr dist from PLY edge = ", ply_edge_hole_dist));
56
57 hole_slop = (ply_hole_dia - post_dia)/2;
58 tile_hard_edge_hole_dist = ply_edge_hole_dist + hole_slop;
59
60 echo(str("HOLES IN PLY ctr dist from TILE HARD edge = ",
61          tile_hard_edge_hole_dist));
62
63 echo(str("HOLES IN PLY ctr dist from TILE ROUND edge = ",
64          tile_hard_edge_hole_dist + round_edge_rad));
65
66 thehd = [ tile_hard_edge_hole_dist, tile_hard_edge_hole_dist ];
67 thehd_tr = thehd;
68 thehd_tl = [ -thehd_tr[0], thehd_tr[1] ];
69 thehd_bl = -thehd_tr;
70 thehd_br = -thehd_tl;
71
72 interlock_rad = interlock_dia/2;
73 interlock_negative_rad = interlock_rad + 0.125;
74
75 interlock_sq_adj = 0.2; // arbitrary
76
77 module Post(){
78   mirror([0,0,1]) {
79     difference(){
80       cylinder(r= post_dia/2, h= tile_th + ply_th - post_shorter);
81       translate([0,0, tile_th]) {
82         cylinder(r= screw_big_dia/2, h= screw_big_len);
83         cylinder(r= screw_dia/2, h= ply_th, $fn=20);
84       }
85     }
86     if (TEST) {
87       tsz = tile_hard_edge_hole_dist - test_edge + 1;
88       translate([0,0, tile_th/2]) {
89         cube([post_dia, tsz*2, tile_th], center=true);
90         cube([tsz*2, post_dia, tile_th], center=true);
91       }
92     }
93   }
94 }
95
96 module Posts(posts) {
97   for (p= posts) {
98     translate(concat(p, [0]))
99       Post();
100   }
101 }
102
103 module TileBase(botleft, topright){
104   size = topright - botleft;
105   botleft_post = botleft + thehd_tr;
106   topright_post = topright + thehd_bl;
107   difference(){
108     mirror([0,0,1])
109       translate(concat(botleft, [0]))
110       cube(concat(size, [tile_th]));
111     if (!TEST) {
112       translate( concat(botleft_post, [ -tile_th ])
113                  + 0.5 * [ post_dia, post_dia, 0 ] )
114         Commitid_BestCount_M( topright_post-botleft_post
115                               + [-post_dia,-post_dia]
116                               + [0, thehd[1]]);
117     }
118     if (TEST) {
119       translate( concat(botleft + [thehd[0], 0], [0]) )
120         Commitid_BestCount([ size[0] - thehd[0]*2, thehd[1] ]);
121       difference(){
122         mirror([0,0,1]) {
123           translate(concat(botleft + [test_edge,test_edge], [test_tile_th]))
124             cube(concat(size - [test_edge,test_edge]*2, [tile_th]));
125           translate(concat(botleft_post, [-1]))
126             cube(concat(topright_post-botleft_post, [tile_th+2]));
127         }
128         minkowski(){
129           Machine();
130           cube(max(test_edge, tile_hard_edge_hole_dist)*2, center=true);
131         }
132       }
133     }
134   }
135 }
136
137 m4_dnl  INREFFRAME(left_cnr, right_cnr, morevars) { body; }
138 m4_define(`INREFFRAME',`
139   length_vec = ($2) - ($1);
140   length = dist2d([0,0], length_vec);
141   length_uvec = length_vec / length;
142   ortho_uvec = [ -length_uvec[1], length_uvec[0] ];
143   m = [ [ length_uvec[0],  ortho_uvec[0], 0, ($1)[0], ],
144         [ length_uvec[1],  ortho_uvec[1], 0, ($1)[1], ],
145         [ 0,              0,              1,            0, ],
146         [ 0,              0,              0,            1, ] ];
147   $3
148   multmatrix(m)
149 ')
150
151 m4_dnl  INREFFRAME(left_cnr, right_cnr, morevars)
152 m4_dnl    INREFFRAME_EDGE { body; }
153 m4_define(`INREFFRAME_EDGE',`
154   translate([0,0, -round_edge_rad])
155 ')
156
157 module RoundEdge(left_cnr, right_cnr) {
158   INREFFRAME(left_cnr, right_cnr)
159     INREFFRAME_EDGE {
160     difference(){
161       rotate([0,90,0])
162         cylinder(r= round_edge_rad, h= length, $fn=50);
163       translate([-1, 0, -20])
164         cube([length+2, 20, 20]);
165     }
166   }
167 }
168
169 module RoundCornerCut(ci) {
170   // ci should be [this_cnr, right_cnr]
171   // where right_cnr is to the right (ie, anticlockwise)
172   this_cnr = ci[0];
173   right_cnr = ci[1];
174   offr= round_cnr_rad - round_edge_rad;
175   INREFFRAME(this_cnr, right_cnr) INREFFRAME_EDGE {
176     difference(){
177       cube(offr*2 - 0.1, center=true);
178       translate([offr, offr, 0])
179         cylinder(center=true, h=20, r= offr);
180     }
181   }
182 }
183
184 module RoundCornerAdd(ci) {
185   this_cnr = ci[0];
186   right_cnr = ci[1];
187   bigr = round_cnr_rad - round_edge_rad;
188   INREFFRAME(this_cnr, right_cnr) INREFFRAME_EDGE {
189     intersection(){
190       cube(bigr*2 + 0.1, center=true);
191       translate([bigr, bigr, 0])
192         rotate_extrude(convexity=10, $fn=50)
193         translate([bigr, 0])
194         difference(){
195           circle(r= round_edge_rad, $fn=50);
196           mirror([1,1])
197             square([20,20]);
198         }
199     }
200   }
201 }
202
203 module InterlockLobePlan(negative) {
204   r = negative ? interlock_negative_rad : interlock_rad;
205   ymir = negative ? 0 : 1;
206
207   dx = sqrt(3) * r;
208   $fn= 80;
209   translate([thehd[0], 0]){
210     mirror([0,ymir]){
211       circle(r=r);
212       difference(){
213         translate([-dx, -0.1])
214           square([ dx*2, r/2 + 0.1 ]);
215         for (xi = [-1, 1]) {
216           translate([ xi*dx, r ])
217             circle(r=r);
218         }
219       }
220     }
221   }
222 }
223
224 module InterlockEdgePlan(negative, nlobes, length, dosquare=true) {
225   for (lobei = [ 0 : nlobes-1 ]) {
226     lobex = (length - thehd[0]*2) * (lobei ? lobei / (nlobes-1) : 0);
227     translate([lobex, 0, 0]) {
228       InterlockLobePlan(negative);
229     }
230   }
231
232   if (dosquare) {
233     iadj = 0;
234     slotshorter = negative ? -0.1 : interlock_fine_lenslop;
235     mirror([0, negative])
236       translate([slotshorter, iadj])
237       square([length - slotshorter*2, interlock_fine + iadj*2]);
238   }
239 }
240
241 module InterlockEdge(left_cnr, right_cnr, negative=0, nlobes=2) {
242   plusth = negative * 1.0;
243   protr = interlock_fine + interlock_sq_adj;
244
245   z2 = -tile_th/2;
246   z1 = -tile_th/2 - protr / interlock_fine_slope;
247   z3 = -tile_th/2 + protr / interlock_fine_slope;
248
249   negsign = negative ? -1 : +1;
250   yprotr = negsign * protr;
251
252   INREFFRAME(left_cnr, right_cnr) {
253     for (vsect = [ // zs0            zs1      ys0,            ys1
254                   [ -tile_th-plusth, plusth,  0,              0],
255                   [ z1,              z2,      0, yprotr],
256                   [ z2,              z3,      yprotr, 0],
257                   ]) {
258       zs0 = vsect[0];
259       zs1 = vsect[1];
260       zsd = zs1-zs0;
261       ys0 = vsect[2];
262       ys1 = vsect[3];
263       ysd = ys1-ys0;
264       sl = ysd/zsd;
265       m = [ [ 1,0,   0,    0 ],
266             [ 0,1, -sl, -ys0 + negsign*interlock_sq_adj ],
267             [ 0,0,   1,  zs0 ],
268             [ 0,0,   0,    1 ] ];
269       multmatrix(m)
270         linear_extrude(height=zsd, convexity=10)
271         InterlockEdgePlan(negative, nlobes, length, !!ysd);
272     }
273   }
274 }
275
276 function TestPiece_holes2corners(holes) =
277   [ holes[0] + thehd_bl,
278     holes[1] + thehd_br,
279     holes[1] + thehd_tr,
280     holes[0] + thehd_tl ];
281
282 module TestPiece1(){ ////toplevel
283   holes = [ [-100, 0],
284             [   0, 0]
285             ];
286   corners = TestPiece_holes2corners(holes);
287   rcs = [corners[0], corners[1]];
288   difference(){
289     union(){
290       TileBase(corners[0], corners[2]);
291       Posts(holes);
292       RoundEdge(corners[0], corners[1]);
293       RoundEdge(corners[3], corners[0]);
294     }
295     InterlockEdge(corners[1], corners[2], 1, nlobes=1);
296     RoundCornerCut(rcs);
297   }
298   RoundCornerAdd(rcs);
299 }
300
301 module TestPiece2(){ ////toplevel
302   holes = [ [   0, 0],
303             [  50, 0]
304             ];
305   corners = TestPiece_holes2corners(holes);
306   TileBase(corners[0], corners[2]);
307   Posts(holes);
308   RoundEdge(corners[0], corners[1]);
309   InterlockEdge(corners[3], corners[0], 0, nlobes=1);
310 }
311
312 module TestDemo(){ ////toplevel
313   translate([ -thehd[0], 0 ])
314     color("blue")
315     TestPiece1();
316   translate([ +thehd[0] + demo_slop, 0 ])
317     TestPiece2();
318 }
319
320 module Machine_Arm(){
321   ysz = cutout_l_end_y_total;
322   // assume the round end is arc of a circle
323   chordlen = dist2d([0,0], [ cutout_l_end_y, cutout_l_end_curve ]);
324   endrad = cutout_l_end_y / cutout_l_end_curve * chordlen;
325   
326   translate([0,0,-30]) linear_extrude(height=60) {
327     translate(tile01_tr + [0, (-cutout_tile01_y + cutout_tile11_y)/2]) {
328       intersection(){
329         translate([-100, -ysz/2])
330           square([400, ysz]);
331         translate([ endrad - cutout_tile11_x - cutout_l_end_x_slop, 0 ])
332           circle(r=endrad, $fa=0.01,$fd=5);
333       }
334     }
335   }
336 }
337
338 module Machine(){
339   Machine_Arm();
340 }
341   
342 function Rectangle_corners(c0, sz) =
343   // returns the corners of a rectangle from c0 to c0+sz
344   // if sz is positive, the corners are anticlockwise starting with c0
345   [ c0 + [ 0,     0     ],
346     c0 + [ sz[0], 0     ],
347     c0 + [ sz[0], sz[1] ],
348     c0 + [ 0,     sz[1] ] ];
349
350 function Rectangle_corners2posts(c) =
351   [ c[0] + thehd_tr,
352     c[1] + thehd_tl,
353     c[2] + thehd_bl,
354     c[3] + thehd_br ];
355
356 module Rectangle_TileBase(c) { TileBase(c[0], c[2]); }
357
358 function Posts_interpolate_one(c0,c1) = [c0, (c0+c1)/2, c1];
359
360 m4_dnl   R_EDGE(c,ix)
361 m4_dnl        c is from Rectangle_corners and
362 m4_dnl        ix is a corner number
363 m4_dnl    expands to two comma-separated corners:
364 m4_dnl    that denoted by ix, and the next one anticlockwise
365 m4_define(`R_EDGE',`$1[$2],$1[(($2)+1)%4]')
366
367 module Tile02(){ ////toplevel
368   sz = [100,170];
369   c0 = -sz;
370   c = Rectangle_corners(c0, sz);
371   posts = Rectangle_corners2posts(c);
372   rcs = [R_EDGE(c,0)];
373   difference(){
374     union(){
375       Rectangle_TileBase(c);
376       Posts(posts);
377       RoundEdge(R_EDGE(c,0));
378       RoundEdge(R_EDGE(c,3));
379       InterlockEdge(R_EDGE(c,2), 0);
380     }
381     InterlockEdge(R_EDGE(c,1), 1);
382     RoundCornerCut(rcs);
383   }
384   RoundCornerAdd(rcs);
385 }
386
387 module Tile12(){ ////toplevel
388   sz = [100,250];
389   c0 = [-sz[0], 0];
390   c = Rectangle_corners(c0, sz);
391   posts = Rectangle_corners2posts(c);
392   rcs = [R_EDGE(c,3)];
393   difference(){
394     union(){
395       Rectangle_TileBase(c);
396       Posts(posts);
397       RoundEdge(R_EDGE(c,2));
398       RoundEdge(R_EDGE(c,3));
399     }
400     InterlockEdge(R_EDGE(c,0), 1);
401     InterlockEdge(R_EDGE(c,1), 1);
402     RoundCornerCut(rcs);
403   }
404   RoundCornerAdd(rcs);
405 }
406
407 tile_01_11_cnr = [250, 0] + [-cutout_tile11_x, 0];
408 tile_11_10_cnr = [250, 0] + [0, cutout_tile11_y];
409
410 module Tile11(){ ////toplevel
411   sz = [250,250];
412   c0 = [0,0];
413   c = Rectangle_corners(c0, sz);
414   cnr_posts = Rectangle_corners2posts(c);
415   posts = concat(
416                  Posts_interpolate_one(cnr_posts[0],
417                                        cnr_posts[1] - [cutout_tile11_x, 0]),
418                  [ cnr_posts[1] + [0, cutout_tile11_y],
419                    cnr_posts[2],
420                    cnr_posts[3]
421                    ]);
422   difference(){
423     union(){
424       Rectangle_TileBase(c);
425       Posts(posts);
426       RoundEdge(R_EDGE(c,2));
427       InterlockEdge(R_EDGE(c,3));
428     }
429     InterlockEdge(c[0], tile_01_11_cnr, 1);
430     InterlockEdge(tile_11_10_cnr, c[2], 1);
431     Machine();
432   }
433 }    
434
435 tile_01_00_cnr = [250, 0] + [0, -cutout_tile01_y];
436
437 module Tile01(){ ////toplevel
438   sz = [250,170];
439   c0 = [0,-sz[1]];
440   c = Rectangle_corners(c0, sz);
441   cnr_posts = Rectangle_corners2posts(c);
442   posts = concat(
443                  Posts_interpolate_one(R_EDGE(cnr_posts,0)),
444                  [ cnr_posts[2] + [0, -cutout_tile01_y] ],
445                  Posts_interpolate_one(cnr_posts[2] - [cutout_tile11_x, 0],
446                                        cnr_posts[3])
447                  );
448   difference(){
449     union(){
450       Rectangle_TileBase(c);
451       Posts(posts);
452       RoundEdge(R_EDGE(c,0));
453       InterlockEdge(tile_01_11_cnr, c[3]);
454       InterlockEdge(R_EDGE(c,3));
455     }
456     InterlockEdge(c[1], tile_01_00_cnr, 1);
457     Machine();
458   }
459 }    
460
461 module Demo(){ ////toplevel
462   translate(demo_slop*[-2,1]) color("blue") Tile12();
463   translate(demo_slop*[-2,0]) color("red")  Tile02();
464   translate(demo_slop*[-2,1]) color("orange") Tile11();
465   translate(demo_slop*[-2,0]) color("purple") Tile01();
466   %Machine();
467 }
468   
469 //TestPiece1();
470 //TestPiece2();
471 //Demo();