Skip to content

Commit fa080e5

Browse files
committed
add missing fillets and a joints test
1 parent dd3fb21 commit fa080e5

File tree

2 files changed

+174
-79
lines changed

2 files changed

+174
-79
lines changed

library.scad

+16-8
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,22 @@ module roundCorner(radius, height) {
2525
*/
2626
module dogboneCube(dimensions, radius) {
2727
union() {
28-
offset = sin(45)*radius;
2928
cube(dimensions);
30-
translate([0, 0, dimensions[2]/2]) {
31-
32-
translate([offset, offset, 0]) cylinder(r = radius, h = dimensions[2], center = true);
33-
translate([dimensions[0]-offset, offset, 0]) cylinder(r = radius, h = dimensions[2], center = true);
34-
translate([dimensions[0]-offset, dimensions[1]-offset, 0]) cylinder(r = radius, h = dimensions[2], center = true);
35-
translate([offset, dimensions[1]-offset, 0]) cylinder(r = radius, h = dimensions[2], center = true);
36-
}
29+
translate([0, 0, 0]) rotate([0, 0, 0]) fillet(radius, dimensions[2]);
30+
translate([dimensions[0], 0, 0]) rotate([0, 0, 90]) fillet(radius, dimensions[2]);
31+
translate([dimensions[0], dimensions[1], 0]) rotate([0, 0, 180]) fillet(radius, dimensions[2]);
32+
translate([0, dimensions[1], 0]) rotate([0, 0, 270]) fillet(radius, dimensions[2]);
3733
}
3834
}
35+
36+
/**
37+
* A single cylinder to be used as negative for subtracting fillets.
38+
*
39+
* @param {Number} radius Radius of the fillet
40+
* @param {Number} height Stock thickness
41+
*/
42+
module fillet(radius, height) {
43+
offset = sin(45)*radius;
44+
translate([offset, offset, STOCK_THICKNESS/2])
45+
cylinder(r = radius, h = height + 0.01, center = true);
46+
}

standesk.scad

+158-71
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ DESK_WIDTH = 1120;
1616
DESK_DEPTH = 800; // mm // Depth of the desk surface between front and rear edge
1717

1818
CORNER_RADIUS = 10; // mm // Radius for rounding the outer corners
19-
FILLET_RADIUS = 2; // mm // Radius for dogbone fillets
19+
FILLET_RADIUS = 5; // mm // Radius for dogbone fillets
2020
DRILL_DIAMETER = 6; // mm // Diameter of the drill bit used to cut the material
2121
CLEARANCE = 10; // mm // Extra space between individual Parts on the panel
2222

@@ -30,10 +30,11 @@ STOCK_THICKNESS = 18; //
3030
| Output Options
3131
|-------------------------------------------------------------------------------
3232
*/
33-
FLAT = false;
34-
PROJECTION = true;
35-
SHOW_STOCK = true;
36-
$fn = 50;
33+
FLAT = true;
34+
PROJECTION = false;
35+
SHOW_STOCK = false;
36+
TEST_JOINT = false;
37+
$fn = 24;
3738

3839

3940
/*
@@ -107,33 +108,45 @@ module top() {
107108
rot = FLAT ? [0, 0, 90] : [0, 0, 0];
108109
translate(trans)
109110
rotate(rot)
110-
union() {
111-
difference() {
111+
difference() {
112+
union() {
112113
cube(size = [DESK_WIDTH, DESK_DEPTH, STOCK_THICKNESS]);
113114

114-
// Rounded corners
115-
roundCorner(CORNER_RADIUS, STOCK_THICKNESS);
116-
translate([DESK_WIDTH, 0, 0]) rotate([0, 0, 90]) roundCorner(CORNER_RADIUS, STOCK_THICKNESS);
117-
translate([DESK_WIDTH, DESK_DEPTH, 0]) rotate([0, 0, 180]) roundCorner(CORNER_RADIUS, STOCK_THICKNESS);
118-
translate([0, DESK_DEPTH, 0]) rotate([0, 0, 270]) roundCorner(CORNER_RADIUS, STOCK_THICKNESS);
115+
// Joints
116+
// left
117+
translate([0, DESK_DEPTH - (STAND_DEPTH - JOINT_WIDTH) / 2, 0])
118+
rotate([90, 0, -90])
119+
joint();
120+
translate([0, STAND_SPACE + STAND_DEPTH - (STAND_DEPTH - JOINT_WIDTH) / 2, 0])
121+
rotate([90, 0, -90])
122+
joint();
123+
124+
// right
125+
translate([DESK_WIDTH, DESK_DEPTH - (STAND_DEPTH + JOINT_WIDTH) / 2, 0])
126+
rotate([90, 0, 90])
127+
joint();
128+
translate([DESK_WIDTH, STAND_SPACE + (STAND_DEPTH - JOINT_WIDTH) / 2, 0])
129+
rotate([90, 0, 90])
130+
joint();
119131
}
120132

121-
// joints
122-
// left
123-
translate([0, DESK_DEPTH - (STAND_DEPTH - JOINT_WIDTH) / 2, 0])
124-
rotate([90, 0, -90])
125-
joint();
126-
translate([0, STAND_SPACE + STAND_DEPTH - (STAND_DEPTH - JOINT_WIDTH) / 2, 0])
127-
rotate([90, 0, -90])
128-
joint();
133+
// Rounded corners
134+
roundCorner(CORNER_RADIUS, STOCK_THICKNESS);
135+
translate([DESK_WIDTH, 0, 0]) rotate([0, 0, 90]) roundCorner(CORNER_RADIUS, STOCK_THICKNESS);
136+
translate([DESK_WIDTH, DESK_DEPTH, 0]) rotate([0, 0, 180]) roundCorner(CORNER_RADIUS, STOCK_THICKNESS);
137+
translate([0, DESK_DEPTH, 0]) rotate([0, 0, 270]) roundCorner(CORNER_RADIUS, STOCK_THICKNESS);
129138

139+
// Fillets
140+
// left
141+
translate([0, DESK_DEPTH - (STAND_DEPTH - JOINT_WIDTH) / 2, 0]) rotate([0, 0, 90]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
142+
translate([0, DESK_DEPTH - (STAND_DEPTH - JOINT_WIDTH) / 2 - JOINT_WIDTH, 0]) rotate([0, 0, 180]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
143+
translate([0, STAND_SPACE + STAND_DEPTH - (STAND_DEPTH - JOINT_WIDTH) / 2, 0]) rotate([0, 0, 90]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
144+
translate([0, STAND_SPACE + STAND_DEPTH - (STAND_DEPTH - JOINT_WIDTH) / 2 - JOINT_WIDTH, 0]) rotate([0, 0, 180]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
130145
// right
131-
translate([DESK_WIDTH, DESK_DEPTH - (STAND_DEPTH + JOINT_WIDTH) / 2, 0])
132-
rotate([90, 0, 90])
133-
joint();
134-
translate([DESK_WIDTH, STAND_SPACE + (STAND_DEPTH - JOINT_WIDTH) / 2, 0])
135-
rotate([90, 0, 90])
136-
joint();
146+
translate([DESK_WIDTH, DESK_DEPTH - (STAND_DEPTH + JOINT_WIDTH) / 2, 0]) rotate([0, 0, 270]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
147+
translate([DESK_WIDTH, DESK_DEPTH - (STAND_DEPTH + JOINT_WIDTH) / 2 + JOINT_WIDTH, 0]) rotate([0, 0, 0]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
148+
translate([DESK_WIDTH, STAND_SPACE + (STAND_DEPTH - JOINT_WIDTH) / 2, 0]) rotate([0, 0, 270]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
149+
translate([DESK_WIDTH, STAND_SPACE + (STAND_DEPTH - JOINT_WIDTH) / 2 + JOINT_WIDTH, 0]) rotate([0, 0, 0]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
137150
}
138151
}
139152

@@ -338,29 +351,40 @@ module cross() {
338351
rotX2 = FLAT ? -90 : 0;
339352
rotZ = FLAT ? -CROSS_ANGLE : 0;
340353
rotate([0, 0, rotZ])
341-
union() {
342-
rotate([rotX1, 0, 0])
343-
linear_extrude(height = STOCK_THICKNESS)
344-
polygon(
345-
points = [
346-
[0, 0],
347-
[DESK_WIDTH, DESK_HEIGHT - CROSS_CUT],
348-
[DESK_WIDTH, DESK_HEIGHT],
349-
[0, CROSS_CUT]
350-
],
351-
paths = [
352-
[0, 1, 2, 3]
353-
]
354-
);
355-
356-
// joints
354+
difference() {
355+
union() {
356+
rotate([rotX1, 0, 0])
357+
linear_extrude(height = STOCK_THICKNESS)
358+
polygon(
359+
points = [
360+
[0, 0],
361+
[DESK_WIDTH, DESK_HEIGHT - CROSS_CUT],
362+
[DESK_WIDTH, DESK_HEIGHT],
363+
[0, CROSS_CUT]
364+
],
365+
paths = [
366+
[0, 1, 2, 3]
367+
]
368+
);
369+
370+
// Joints
371+
rotate([rotX2, 0, 0]) {
372+
translate([0, -STOCK_THICKNESS, (CROSS_CUT - JOINT_WIDTH)/2])
373+
rotate([0, -90, 0])
374+
joint();
375+
translate([DESK_WIDTH, -STOCK_THICKNESS, DESK_HEIGHT- (CROSS_CUT - JOINT_WIDTH)/2])
376+
rotate([0, 90, 0])
377+
joint();
378+
}
379+
}
380+
381+
// Fillets
357382
rotate([rotX2, 0, 0]) {
358-
translate([0, -STOCK_THICKNESS, (CROSS_CUT - JOINT_WIDTH)/2])
359-
rotate([0, -90, 0])
360-
joint();
361-
translate([DESK_WIDTH, -STOCK_THICKNESS, DESK_HEIGHT- (CROSS_CUT - JOINT_WIDTH)/2])
362-
rotate([0, 90, 0])
363-
joint();
383+
translate([2, -STOCK_THICKNESS, (CROSS_CUT - JOINT_WIDTH)/2]) rotate([90, 90, 180]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
384+
translate([2, -STOCK_THICKNESS, (CROSS_CUT - JOINT_WIDTH)/2 + JOINT_WIDTH]) rotate([90, 0, 180]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
385+
386+
translate([DESK_WIDTH, -STOCK_THICKNESS, DESK_HEIGHT- (CROSS_CUT - JOINT_WIDTH)/2]) rotate([90, 270, 180]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
387+
translate([DESK_WIDTH, -STOCK_THICKNESS, DESK_HEIGHT- (CROSS_CUT - JOINT_WIDTH)/2 - JOINT_WIDTH]) rotate([90, 180, 180]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
364388
}
365389
}
366390
}
@@ -374,16 +398,25 @@ module rest() {
374398

375399
translate(trans)
376400
rotate(rot)
377-
union() {
378-
cube([DESK_WIDTH, REST_DEPTH, STOCK_THICKNESS]);
379-
380-
// joints
381-
translate([0, (REST_DEPTH + JOINT_WIDTH) / 2, 0])
382-
rotate([90, 0, -90])
383-
joint();
384-
translate([DESK_WIDTH, (REST_DEPTH - JOINT_WIDTH) / 2, 0])
385-
rotate([90, 0, 90])
386-
joint();
401+
difference() {
402+
union() {
403+
cube([DESK_WIDTH, REST_DEPTH, STOCK_THICKNESS]);
404+
405+
// joints
406+
translate([0, (REST_DEPTH + JOINT_WIDTH) / 2, 0])
407+
rotate([90, 0, -90])
408+
joint();
409+
translate([DESK_WIDTH, (REST_DEPTH - JOINT_WIDTH) / 2, 0])
410+
rotate([90, 0, 90])
411+
joint();
412+
}
413+
414+
// Fillets
415+
translate([0, (REST_DEPTH + JOINT_WIDTH) / 2, 0]) rotate([0, 0, 90]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
416+
translate([0, (REST_DEPTH + JOINT_WIDTH) / 2 - JOINT_WIDTH, 0]) rotate([0, 0, 180]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
417+
418+
translate([DESK_WIDTH, (REST_DEPTH - JOINT_WIDTH) / 2, 0]) rotate([0, 0, 270]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
419+
translate([DESK_WIDTH, (REST_DEPTH - JOINT_WIDTH) / 2 + JOINT_WIDTH, 0]) rotate([0, 0, 0]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
387420
}
388421
}
389422

@@ -398,16 +431,25 @@ module topsupport() {
398431

399432
translate(trans)
400433
rotate(rot)
401-
union() {
402-
cube([DESK_WIDTH, TOPSUPPORT_DEPTH, STOCK_THICKNESS]);
434+
difference() {
435+
union() {
436+
cube([DESK_WIDTH, TOPSUPPORT_DEPTH, STOCK_THICKNESS]);
403437

404-
// joints
405-
translate([0, (TOPSUPPORT_DEPTH + JOINT_WIDTH) / 2, 0])
406-
rotate([90, 0, -90])
407-
joint();
408-
translate([DESK_WIDTH, (TOPSUPPORT_DEPTH - JOINT_WIDTH) / 2, 0])
409-
rotate([90, 0, 90])
410-
joint();
438+
// joints
439+
translate([0, (TOPSUPPORT_DEPTH + JOINT_WIDTH) / 2, 0])
440+
rotate([90, 0, -90])
441+
joint();
442+
translate([DESK_WIDTH, (TOPSUPPORT_DEPTH - JOINT_WIDTH) / 2, 0])
443+
rotate([90, 0, 90])
444+
joint();
445+
}
446+
447+
// Fillets
448+
translate([0, (TOPSUPPORT_DEPTH + JOINT_WIDTH) / 2, 0]) rotate([0, 0, 90]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
449+
translate([0, (TOPSUPPORT_DEPTH + JOINT_WIDTH) / 2 - JOINT_WIDTH, 0]) rotate([0, 0, 180]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
450+
451+
translate([DESK_WIDTH, (TOPSUPPORT_DEPTH - JOINT_WIDTH) / 2, 0]) rotate([0, 0, 270]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
452+
translate([DESK_WIDTH, (TOPSUPPORT_DEPTH - JOINT_WIDTH) / 2 + JOINT_WIDTH, 0]) rotate([0, 0, 0]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
411453
}
412454
}
413455
}
@@ -449,7 +491,7 @@ module jointHole() {
449491
*/
450492
module keys() {
451493
if (FLAT) {
452-
translate([STOCK_LENGTH - CLEARANCE - KEY_LENGTH, CLEARANCE, 0])
494+
translate([DESK_DEPTH + DESK_HEIGHT + BASE_HEIGHT + 8*CLEARANCE, CLEARANCE, 0])
453495
for(n = [0 : 9]) {
454496
translate([0, (KEY_THICKNESS + CLEARANCE) * n, 0])
455497
key();
@@ -465,6 +507,40 @@ module key() {
465507
polygon([[0, 0], [KEY_LENGTH, 0], [0, KEY_THICKNESS]]);
466508
}
467509

510+
/**
511+
* Male and female part of a joint plus key for test cutting.
512+
*/
513+
module jointTest() {
514+
if (FLAT) {
515+
FEMALE_X = STOCK_THICKNESS*3;
516+
FEMALE_Y = JOINT_WIDTH+2*STOCK_THICKNESS;
517+
518+
translate([STOCK_LENGTH - FEMALE_X - CLEARANCE, CLEARANCE, 0]) {
519+
// Female
520+
difference() {
521+
cube([FEMALE_X, FEMALE_Y, STOCK_THICKNESS]);
522+
translate([2*STOCK_THICKNESS, STOCK_THICKNESS, 0]) rotate([0, 0, 90]) jointHole();
523+
}
524+
525+
// Male
526+
translate([-(FEMALE_X + CLEARANCE), CLEARANCE + STOCK_THICKNESS, 0])
527+
rotate([0, 0, 90])
528+
difference() {
529+
union() {
530+
translate([-STOCK_THICKNESS, 0, 0]) cube([JOINT_WIDTH+2*STOCK_THICKNESS, 2*STOCK_THICKNESS, STOCK_THICKNESS]);
531+
rotate([90, 0, 0]) joint();
532+
}
533+
// Fillets
534+
rotate([0, 0, 180]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
535+
translate([JOINT_WIDTH, 0, 0]) rotate([0, 0, 270]) fillet(FILLET_RADIUS, STOCK_THICKNESS);
536+
}
537+
538+
// Key
539+
translate([0, FEMALE_Y + CLEARANCE, 0]) key();
540+
}
541+
}
542+
}
543+
468544

469545
/**
470546
* The full desk.
@@ -485,20 +561,31 @@ module stock(){
485561
cube([STOCK_LENGTH, STOCK_WIDTH, STOCK_THICKNESS]);
486562
}
487563

564+
/**
565+
* Render either the desk or the joint tests.
566+
*/
567+
module show() {
568+
if (TEST_JOINT) {
569+
jointTest();
570+
}
571+
else {
572+
desk();
573+
}
574+
}
575+
488576

489577
/*
490578
|-------------------------------------------------------------------------------
491579
| Rendering logic
492580
|-------------------------------------------------------------------------------
493581
*/
494-
495582
if (FLAT && PROJECTION) {
496583
projection(cut = true)
497584
translate([0, 0, -STOCK_THICKNESS/2])
498-
desk();
585+
show();
499586
}
500587
else {
501-
desk();
588+
show();
502589
}
503590

504591
if (FLAT && SHOW_STOCK)

0 commit comments

Comments
 (0)