chiark / gitweb /
08b0b1ea0ebdcbeaeb6f93674dd5fa2c5454cb86
[reprap-play.git] / fairphone-case.scad
1 // -*- C -*-
2
3 phone_height = 146.5;
4 phone_width = 76.75;
5
6 phone_cnr_rad = 4.0;
7
8 phone_edge_thick = 9.0;
9 phone_total_thick = 12.0;
10 phone_backside_slope = 1.0; // larger means shallower
11
12 case_th_bottom = 2;
13 case_th_lid = 2;
14 case_th_side = 2;
15 case_th_lip = 1.2;
16
17 keeper_th_z = 0.75;
18 keeper_th_x = 0.75;
19 keeper_inner_width = 1.75;
20 keeper_inner_height = 1.75;
21
22 keeper_gap_z_top = 0.25;
23 keeper_gap_z_bot = 0.25;
24 keeper_gap_x     = 0.25;
25 keeper_gap_x_holes = 0.75;
26
27 case_lip = 1.25;
28
29 $fa = 5;
30 $fs = 0.1;
31
32 // calculated
33
34 phone_backside_slope_thick = phone_total_thick - phone_edge_thick;
35
36 //lid_lip_overlap_width xxx bad name = ;
37 //lid_lip_inner_slope = [ 5, 5 ]; // xxx
38
39 epp0 = [0,0];
40 epp1 = [0, -phone_edge_thick];
41 epp2 = epp1 + phone_backside_slope_thick * [ phone_backside_slope, -1 ];
42 epp3 = epp2 + [10, 0];
43 epp5 = epp0 + [0,1] * (keeper_th_z + keeper_gap_z_top + case_lip);
44 epp4 = epp5 + [-1,0] * case_th_side;
45
46 kppe = [0,0];
47 kppd = kppe + [1,0] * keeper_inner_width;
48 kppc = kppd + [0,1] * keeper_th_z;
49 kppb = [ kppe[0] - keeper_th_x, kppc[1] ];
50 kppf = kppe - [0,1] * keeper_inner_height;
51 kppa = [ kppb[0], kppf[1] ];
52
53 module rectfromto(a,b) {
54   ab = b - a;
55   translate([min(a[0], b[0]), min(a[1], b[1])])
56     square([abs(ab[0]), abs(ab[1])]);
57 }
58 module circleat(c,r) { translate(c) circle(r); }
59
60 module KeeperProfile(){
61   polygon([kppe, kppd, kppc, kppb, kppa, kppf]);
62 }
63
64 module EdgeProfile(){
65   difference(){
66     hull(){
67       circleat(epp3, r=case_th_bottom);
68       circleat(epp2, r=case_th_bottom);
69       circleat(epp1, r=case_th_side);
70       rectfromto(epp0, epp4);
71     }
72     polygon([ epp5 + [0,10],
73               epp1,
74               epp2,
75               epp3 + [10,0] ]);
76   }
77 }
78
79 module CaseBase_rhsflip() {
80   for (rhs=[0,1]) {
81     translate([phone_width/2, 0, 0])
82       mirror([rhs,0,0])
83       translate([-phone_width/2, 0, 0])
84       children();
85   }
86 }
87
88 module CaseBase_botflip() {
89   for (bot=[0,1]) {
90     translate([0, -phone_height/2, 0])
91       mirror([0, bot, 0])
92       translate([0, phone_height/2, 0])
93       children();
94   }
95 }  
96
97 module CaseBase(){
98   CaseBase_rhsflip(){
99     translate([0, -phone_cnr_rad, 0])
100       rotate([90,0,0])
101       linear_extrude(height = phone_height - phone_cnr_rad*2)
102       EdgeProfile();
103   }
104   CaseBase_rhsflip() CaseBase_botflip() {
105     translate([+1,-1] * phone_cnr_rad)
106       intersection(){
107         rotate_extrude()
108           intersection(){
109             mirror([1,0,0])
110               translate([-1,0] * phone_cnr_rad)
111               EdgeProfile();
112             rectfromto([0,-20],[10,20]);
113           }
114         translate([-10, 0, -20] + 0.01 * [+1,-1, 0] )
115           cube([10,10,40]);
116       }
117   }
118   CaseBase_botflip(){
119     translate([ phone_width - phone_cnr_rad, 0,0 ])
120       rotate([90,0,-90])
121       linear_extrude(height = phone_width - phone_cnr_rad*2)
122       EdgeProfile();
123   }
124 }
125
126 module Case(){
127   difference(){
128     CaseBase();
129     CaseBase_rhsflip()
130       translate([0, -phone_cnr_rad, 0])
131       rotate([90, 0, 0])
132       linear_extrude(height = phone_height + phone_cnr_rad * 2)
133       minkowski(){
134         KeeperProfile();
135         rectfromto([ -keeper_gap_x,    -keeper_gap_z_bot ],
136                    [ keeper_gap_x_holes,    +keeper_gap_z_top ]);
137       }
138   }
139 }
140
141 module Keeper(){
142   CaseBase_rhsflip()
143     translate([0, -phone_cnr_rad, 0])
144     rotate([90, 0, 0])
145     linear_extrude(height = phone_height - phone_cnr_rad * 2)
146     KeeperProfile();
147 }
148
149 //EdgeProfile();
150 //KeeperProfile();
151 //CaseBase();
152 %Case();
153 Keeper();