Changed dovetail orientation to be more intuitive.

This commit is contained in:
Adrian Mariano 2020-01-21 20:29:43 -05:00
parent 5c28029c47
commit 15e21ebfa8

View file

@ -443,15 +443,16 @@ module joiner_quad(spacing1=undef, spacing2=undef, xspacing=undef, yspacing=unde
// Module: dovetail() // Module: dovetail()
// //
// Usage: // Usage:
// dovetail(l|length, h|height, w|width, slope|angle, taper|width2, [chamfer], [r|radius], [round], [$slop]) // dovetail(l|length, h|height, w|width, slope|angle, taper|back_width, [chamfer], [r|radius], [round], [$slop])
// //
// Description: // Description:
// Produces a possibly tapered dovetail joint shape to attach to or subtract from two parts you wish to join together. // Produces a possibly tapered dovetail joint shape to attach to or subtract from two parts you wish to join together.
// The tapered dovetail is particularly advantageous for long joints because the joint assembles without binding until // The tapered dovetail is particularly advantageous for long joints because the joint assembles without binding until
// it is fully closed, and then wedges tightly. You can chamfer or round the corners of the dovetail shape for better // it is fully closed, and then wedges tightly. You can chamfer or round the corners of the dovetail shape for better
// printing and assembly, or choose a fully rounded joint that looks more like a puzzle piece. The dovetail appears // printing and assembly, or choose a fully rounded joint that looks more like a puzzle piece. The dovetail appears
// parallel to the X axis and projecting upwards, so in its default orientation it will slide together with a translation // parallel to the Y axis and projecting upwards, so in its default orientation it will slide together with a translation
// in the X direction. // in the positive Y direction. The default anchor for dovetails is BOTTOM; the default orientation depends on the gender,
// with male dovetails oriented UP and female ones DOWN.
// //
// Arguments: // Arguments:
// l / length = Length of the dovetail (amount the joint slides during assembly) // l / length = Length of the dovetail (amount the joint slides during assembly)
@ -459,62 +460,64 @@ module joiner_quad(spacing1=undef, spacing2=undef, xspacing=undef, yspacing=unde
// w / width = Width (at the wider, top end) of the dovetail before tapering // w / width = Width (at the wider, top end) of the dovetail before tapering
// slope = slope of the dovetail. Standard woodworking slopes are 4, 6, or 8. Default: 6. // slope = slope of the dovetail. Standard woodworking slopes are 4, 6, or 8. Default: 6.
// angle = angle (in degrees) of the dovetail. Specify only one of slope and angle. // angle = angle (in degrees) of the dovetail. Specify only one of slope and angle.
// taper = taper angle (in degrees). Dovetail gets wider by this angle. Default: no taper // taper = taper angle (in degrees). Dovetail gets narrower by this angle. Default: no taper
// width2 = width of right hand end of the dovetail. This alternate method of specifying the taper may be easier to manage. Specify only one of taper and width2. // back_width = width of right hand end of the dovetail. This alternate method of specifying the taper may be easier to manage. Specify only one of `taper` and `back_width`. Note that `back_width` should be smaller than `width` to taper in the customary direction, with the smaller end at the back.
// chamfer = amount to chamfer the corners of the joint (Default: no chamfer) // chamfer = amount to chamfer the corners of the joint (Default: no chamfer)
// r / radius = amount to round over the corners of the joint (Default: no rounding) // r / radius = amount to round over the corners of the joint (Default: no rounding)
// round = // round = true to round both corners of the dovetail and give it a puzzle piece look. Default: false.
// Example: Ordinary straight dovetail, male version (sticking up) and female verison (below the xy plane) // extra = amount of extra length and base extension added to dovetails for unions and differences. Default: 0.01
// Example: Ordinary straight dovetail, male version (sticking up) and female version (below the xy plane)
// dovetail("male", length=30, width=15, height=8); // dovetail("male", length=30, width=15, height=8);
// fwd(25) dovetail("female", length=30, width=15, height=8); // right(20) dovetail("female", length=30, width=15, height=8);
// Example: Adding a 6 degree taper (Such a big taper is usually not necessary, but easier to see for the example.) // Example: Adding a 6 degree taper (Such a big taper is usually not necessary, but easier to see for the example.)
// dovetail("male", length=30, width=15, height=8, taper=6); // dovetail("male", length=30, width=15, height=8, taper=6);
// fwd(25) dovetail("female", length=30, width=15, height=8, taper=6); // right(20) dovetail("female", length=30, width=15, height=8, taper=6);
// Example: A block that can link to itself // Example: A block that can link to itself
// diff("remove") // diff("remove")
// cuboid([50,30,10]){ // cuboid([50,30,10]){
// attach(BACK) dovetail("male", length=10, width=15, height=8,spin=90); // attach(BACK) dovetail("male", length=10, width=15, height=8);
// attach(FRONT) dovetail("female", length=10, width=15, height=8,spin=90,$tags="remove"); // attach(FRONT) dovetail("female", length=10, width=15, height=8,$tags="remove");
// } // }
// Example: Setting the dovetail angle. This is too extreme to be useful. // Example: Setting the dovetail angle. This is too extreme to be useful.
// diff("remove") // diff("remove")
// cuboid([50,30,10]){ // cuboid([50,30,10]){
// attach(BACK) dovetail("male", length=10, width=15, height=8,angle=30,spin=90); // attach(BACK) dovetail("male", length=10, width=15, height=8,angle=30);
// attach(FRONT) dovetail("female", length=10, width=15, height=8,angle=30,spin=90,$tags="remove"); // attach(FRONT) dovetail("female", length=10, width=15, height=8,angle=30,$tags="remove");
// } // }
// Example: Adding a chamfer helps printed parts fit together without problems at the corners // Example: Adding a chamfer helps printed parts fit together without problems at the corners
// diff("remove") // diff("remove")
// cuboid([50,30,10]){ // cuboid([50,30,10]){
// attach(BACK) dovetail("male", length=10, width=15, height=8,spin=90,chamfer=1); // attach(BACK) dovetail("male", length=10, width=15, height=8,chamfer=1);
// attach(FRONT) dovetail("female", length=10, width=15, height=8,spin=90,chamfer=1,$tags="remove"); // attach(FRONT) dovetail("female", length=10, width=15, height=8,chamfer=1,$tags="remove");
// } // }
// Example: Rounding the outside corners is another option // Example: Rounding the outside corners is another option
// diff("remove") // diff("remove")
// cuboid([50,30,10]){ // cuboid([50,30,10]){
// attach(BACK) dovetail("male", length=10, width=15, height=8,spin=90,radius=1); // attach(BACK) dovetail("male", length=10, width=15, height=8,radius=1,$fn=32);
// attach(FRONT) dovetail("female", length=10, width=15, height=8,spin=90,radius=1,$tags="remove"); // attach(FRONT) dovetail("female", length=10, width=15, height=8,radius=1,$tags="remove",$fn=32);
// } // }
// Example: Or you can make a fully rounded joint // Example: Or you can make a fully rounded joint
// $fn=32;
// diff("remove") // diff("remove")
// cuboid([50,30,10]){ // cuboid([50,30,10]){
// attach(BACK) dovetail("male", length=10, width=15, height=8,spin=90,radius=1.5, round=true); // attach(BACK) dovetail("male", length=10, width=15, height=8,radius=1.5, round=true);
// attach(FRONT) dovetail("female", length=10, width=15, height=8,spin=90,radius=1.5, round=true, $tags="remove"); // attach(FRONT) dovetail("female", length=10, width=15, height=8,radius=1.5, round=true, $tags="remove");
// } // }
// Example: With a long joint like this, a taper makes the joint easy to assemble. It will go together easily and wedge tightly if you get the tolerances right. Specifying the taper with `width2` may be easier than using a taper angle. // Example: With a long joint like this, a taper makes the joint easy to assemble. It will go together easily and wedge tightly if you get the tolerances right. Specifying the taper with `back_width` may be easier than using a taper angle.
// cuboid([50,30,10]) // cuboid([50,30,10])
// attach(TOP) dovetail("male", length=50, width=15, height=4, width2=18); // attach(TOP) dovetail("male", length=50, width=18, height=4, back_width=15, spin=90);
// fwd(35) // fwd(35)
// diff("remove") // diff("remove")
// cuboid([50,30,10]) // cuboid([50,30,10])
// attach(TOP) dovetail("female", length=50, width=15, height=4, width2=18, $tags="remove"); // attach(TOP) dovetail("female", length=50, width=18, height=4, back_width=15, spin=90,$tags="remove");
// Example: A series of dovtails // Example: A series of dovtails
// cuboid([50,30,10]) // cuboid([50,30,10])
// attach(BACK) xspread(10,5) dovetail("male", length=10, width=7, height=4, spin=90); // attach(BACK) xspread(10,5) dovetail("male", length=10, width=7, height=4);
// Example: Mating pin board for a right angle joint // Example: Mating pin board for a right angle joint. Note that the anchor method and use of `spin` ensures that the joint works even with a taper.
// diff("remove") // diff("remove")
// cuboid([50,30,10]) // cuboid([50,30,10])
// position(TOP+BACK) xspread(10,5) dovetail("female", length=10, width=7, height=4, spin=90,$tags="remove",anchor=BOTTOM+RIGHT); // position(TOP+BACK) xspread(10,5) dovetail("female", length=10, width=7, taper=4, height=4, $tags="remove",anchor=BOTTOM+FRONT,spin=180);
module dovetail(gender, length, l, width, w, height, h, angle, slope, taper, width2, chamfer, extra=0.01, r, radius, round=false, anchor=BOTTOM, spin=0, orient) module dovetail(gender, length, l, width, w, height, h, angle, slope, taper, back_width, chamfer, extra=0.01, r, radius, round=false, anchor=BOTTOM, spin=0, orient)
{ {
radius = get_radius(r1=radius,r2=r); radius = get_radius(r1=radius,r2=r);
lcount = num_defined([l,length]); lcount = num_defined([l,length]);
@ -530,8 +533,8 @@ module dovetail(gender, length, l, width, w, height, h, angle, slope, taper, wid
gender == "female" ? DOWN : UP; gender == "female" ? DOWN : UP;
count = num_defined([angle,slope]); count = num_defined([angle,slope]);
assert(count<=1, "Do not specify both angle and slope"); assert(count<=1, "Do not specify both angle and slope");
count2 = num_defined([taper,width2]); count2 = num_defined([taper,back_width]);
assert(count2<=1, "Do not specify both taper and width2"); assert(count2<=1, "Do not specify both taper and back_width");
count3 = num_defined([chamfer, radius]); count3 = num_defined([chamfer, radius]);
assert(count3<=1 || (radius==0 && chamfer==0), "Do not specify both chamfer and radius"); assert(count3<=1 || (radius==0 && chamfer==0), "Do not specify both chamfer and radius");
slope = is_def(slope) ? slope : slope = is_def(slope) ? slope :
@ -539,8 +542,8 @@ module dovetail(gender, length, l, width, w, height, h, angle, slope, taper, wid
width = gender == "male" ? w : w + 2*$slop; width = gender == "male" ? w : w + 2*$slop;
height = h + (gender == "female" ? 2*$slop : 0); height = h + (gender == "female" ? 2*$slop : 0);
front_offset = is_def(taper) ? extra * tan(taper) : front_offset = is_def(taper) ? -extra * tan(taper) :
is_def(width2) ? extra * (width2-width)/length/2 : 0; is_def(back_width) ? extra * (back_width-width)/length/2 : 0;
size = is_def(chamfer) && chamfer>0 ? chamfer : size = is_def(chamfer) && chamfer>0 ? chamfer :
is_def(radius) && radius>0 ? radius : 0; is_def(radius) && radius>0 ? radius : 0;
@ -551,29 +554,29 @@ module dovetail(gender, length, l, width, w, height, h, angle, slope, taper, wid
smallend_half = round_corners( smallend_half = round_corners(
move( move(
[-length/2-extra,0,0], [0,-length/2-extra,0],
p=[ p=[
[0,0 , height], [0 , 0, height],
[0,width/2-front_offset , height], [width/2-front_offset , 0, height],
[0,width/2 - height/slope - front_offset, 0 ], [width/2 - height/slope - front_offset, 0, 0 ],
[0,width/2 - front_offset + height, 0] [width/2 - front_offset + height, 0, 0]
] ]
), ),
curve=type, size=fullsize, closed=false curve=type, size=fullsize, closed=false
); );
smallend_points = concat(select(smallend_half, 1, -2), [down(extra,p=select(smallend_half, -2))]); smallend_points = concat(select(smallend_half, 1, -2), [down(extra,p=select(smallend_half, -2))]);
offset = is_def(taper) ? (length+extra) * tan(taper) : offset = is_def(taper) ? -(length+extra) * tan(taper) :
is_def(width2) ? (width2-width) / 2 : 0; is_def(back_width) ? (back_width-width) / 2 : 0;
bigend_points = move([length+2*extra,offset,0], p=smallend_points); bigend_points = move([offset,length+2*extra,0], p=smallend_points);
adjustment = gender == "male" ? -0.01 : 0.01; // Adjustment for default overlap in attach() adjustment = gender == "male" ? -0.01 : 0.01; // Adjustment for default overlap in attach()
orient_and_anchor([length, width+2*offset, height],anchor=anchor,orient=orient,spin=spin, chain=true) { orient_and_anchor([width+2*offset, length, height],anchor=anchor,orient=orient,spin=spin, chain=true) {
down(height/2+adjustment) { down(height/2+adjustment) {
skin( skin(
[ [
concat(smallend_points, yflip(p=reverse(smallend_points))), reverse(concat(smallend_points, xflip(p=reverse(smallend_points)))),
concat(bigend_points, yflip(p=reverse(bigend_points))) reverse(concat(bigend_points, xflip(p=reverse(bigend_points))))
], ],
convexity=4 convexity=4
); );