joiners bugfix, attachments proofread

This commit is contained in:
Adrian Mariano 2022-11-15 23:02:39 -05:00
parent 1cf60c41e2
commit 45826195c8
2 changed files with 90 additions and 59 deletions

View file

@ -629,70 +629,76 @@ module dovetail(gender, width, height, slide, h, w, angle, slope, thickness, tap
count2 = num_defined([taper,back_width]);
count3 = num_defined([chamfer, radius]);
dummy =
assert(count<=1, "Do not specify both angle and slope")
assert(count2<=1, "Do not specify both taper and back_width")
assert(count3<=1 || (radius==0 && chamfer==0), "Do not specify both chamfer and radius");
slope = is_def(slope) ? slope :
is_def(angle) ? 1/tan(angle) : 6;
assert(count<=1, "Do not specify both angle and slope")
assert(count2<=1, "Do not specify both taper and back_width")
assert(count3<=1 || (radius==0 && chamfer==0), "Do not specify both chamfer and radius");
slope = is_def(slope) ? slope
: is_def(angle) ? 1/tan(angle)
: 6;
height_slop = gender == "female" ? get_slop() : 0;
// This adjustment factor doesn't seem to be exactly right, but don't know how to get it right
// Need taper angle for computing width adjustment, but not used elsewhere
taper_ang = is_def(taper) ? taper
: is_def(back_width) ? atan((back_width-width)/slide)
: is_def(back_width) ? atan((back_width-width)/2/slide)
: 0;
wfactor=rot(atan(cos(taper_ang)/slope),p=zrot(taper_ang, RIGHT), v=[-sin(taper_ang),cos(taper_ang),0]).x;
// This is the adjustment factor for width to grow in the direction normal to the dovetail face
wfactor = sqrt( 1/slope^2 + 1/cos(taper_ang)^2 );
// adjust width for increased height adjust for normal to dovetail surface
width_slop = 2*height_slop/slope + 2* height_slop / wfactor;
width_slop = 2*height_slop/slope + 2* height_slop * wfactor;
width = w + width_slop;
height = h + height_slop;
back_width = u_add(back_width, width_slop);
front_offset = is_def(taper) ? -extra * tan(taper)
extra_offset = is_def(taper) ? -extra * tan(taper)
: is_def(back_width) ? extra * (back_width-width)/slide/2
: 0;
size = is_def(chamfer) && chamfer>0 ? chamfer
: is_def(radius) && radius>0 ? radius
: 0;
fullsize = round ? [size,size]
: gender == "male" ? [size,0]
: [0,size];
type = is_def(chamfer) && chamfer>0 ? "chamfer" : "circle";
fullsize = round ? [size,size] :
gender == "male" ? [size,0] : [0,size];
smallend_half = round_corners(
move(
[0,-slide/2-extra,0],
p=[
[0, 0, height],
[width/2 - front_offset, 0, height],
[width/2 - height/slope - front_offset, 0, 0 ],
[width/2 - front_offset + height, 0, 0 ]
[width/2 - extra_offset, 0, height],
[width/2 - extra_offset - height/slope, 0, 0 ],
[width/2 - extra_offset + height, 0, 0 ]
]
),
method=type, cut = fullsize, closed=false
);
smallend_points = concat(select(smallend_half, 1, -2), [down(extra,p=select(smallend_half, -2))]);
offset = is_def(taper) ? -(slide+extra) * tan(taper)
offset = is_def(taper) ? -slide * tan(taper)
: is_def(back_width) ? (back_width-width) / 2
: 0;
bigend_points = move([offset,slide+2*extra,0], p=smallend_points);
bigend_points = move([offset+2*extra_offset,slide+2*extra,0], p=smallend_points);
bigenough = all_nonnegative(column(smallend_half,0)) && all_nonnegative(column(bigend_points,0));
assert(bigenough, "Width of dovetail is not large enough for its geometry (angle and taper");
//adjustment = $overlap * (gender == "male" ? -1 : 1); // Adjustment for default overlap in attach()
adjustment = 0; // Default overlap is assumed to be zero
// This code computes the true normal from which the exact width factor can be obtained
// as the x component. Comparing to wfactor above shows small discrepancy.
// Note, male joint case is totally wrong, but that doesn't matter because we only need
// slop for female
// as the x component. Comparing to wfactor above shows that they agree.
// pts = [smallend_points[0], smallend_points[1], bigend_points[1],bigend_points[0]];
// n = -polygon_normal(pts);
// echo(n=n);
// echo(wfactor=wfactor);
// echo(err = n.x-wfactor);
// echo(invwfactor = 1/wfactor, error = n.x-1/wfactor);
attachable(anchor,spin,orient, size=[width+2*offset, slide, height]) {
down(height/2+adjustment) {
//color("red")stroke([pts],width=.1);
skin(
[
reverse(concat(smallend_points, xflip(p=reverse(smallend_points)))),

View file

@ -311,7 +311,7 @@ is CENTER, and in this case, the cylinder is centered on the cube's center
```openscad-3D
include <BOSL2/std.scad>
up(13) cube(50)
cyl(d=25,l=75);
cyl(d=25,l=95);
```
With `cylinder()` the default anchor is BOTTOM. It's hard to tell,
@ -331,7 +331,7 @@ side of the cylinder is aligned with the center of the cube.
```openscad-3D
include <BOSL2/std.scad>
cube(50,anchor=FRONT)
cylinder(d=25,l=75,anchor=RIGHT);
cylinder(d=25,l=95,anchor=RIGHT);
```
The `position()` module enables you to specify where on the parent to
@ -389,14 +389,17 @@ mechanism for re-orienting the child() that eases this burden.
Using its `anchor=` argument you can orient the
child relative to the parent anchor directions. This is different
than giving an `orient=` argument to the child, because that orients
relative to the **child** anchor directions. A series of three
relative to the parent's global coordinate system by just using the vector
directly instead of orienting to the parent's anchor, which takes
account of face orientation. A series of three
examples shows the different results. In the first example, we use
only `position()`. The child cube is erected pointing upwards, in the
Z direction. In the second example we use `orient=RIGHT` in the child
and the result is that the child object points in the X+ direction,
without regard for the shape of the parent object. In the final
example we apply `orient(anchor=RIGHT)` and the child is oriented
relative to the slanted right face of the parent.
relative to the slanted right face of the parent using the parent
RIGHT anchor.
```openscad-3D
include<BOSL2/std.scad>
@ -422,8 +425,8 @@ prismoid([50,50],[30,30],h=40)
cube([15,15,25],anchor=BACK+BOT);
```
You may have noticed that the anchors were different in each of the
three examples above. Why is that? The first and second examples
You may have noticed that the children in the above three examples
have different anchors. Why is that? The first and second examples
differ because anchoring up and anchoring to the right require
anchoring on opposite sides of the child. But the third case differs
because the spin has changed. The examples below show the same models
@ -436,7 +439,7 @@ flag.
include<BOSL2/std.scad>
prismoid([50,50],[30,30],h=40)
position(RIGHT+TOP)
anchor_arrow(20);
anchor_arrow(40);
```
@ -444,7 +447,7 @@ prismoid([50,50],[30,30],h=40)
include<BOSL2/std.scad>
prismoid([50,50],[30,30],h=40)
position(RIGHT+TOP)
anchor_arrow(20, orient=RIGHT);
anchor_arrow(40, orient=RIGHT);
```
```openscad-3D
@ -452,12 +455,12 @@ include<BOSL2/std.scad>
prismoid([50,50],[30,30],h=40)
position(RIGHT+TOP)
orient(anchor=RIGHT)
anchor_arrow(20);
anchor_arrow(40);
```
Note also that `orient()` can be used to orient the child relative to
the absolute coordinate system using its first argument, `dir=`. This
the parent global coordinate system using its first argument, `dir=`. This
use of `orient()` is the same as using the `orient=` argument for the
child object.
@ -467,10 +470,22 @@ child object.
Attachables get their name from their ability to be attached to each
other. Unlike with positioning, attaching changes the orientation of
the child object. When you attach an object, it appears on the parent
relative to the local coordinate system of the parent. To understand
relative to the local coordinate system of the parent at the anchor point. To understand
what this means, imagine the perspective of an ant walking on a
sphere. If you attach a cylinder to the sphere then the cylinder will
be "up" from the ant's perspective.
sphere. The meaning of UP varies depending on where on the sphere the
ant is standing. If you **attach** a cylinder to the sphere then the cylinder will
be "up" from the ant's perspective. The first example shows a
cylinder placed with `position()` so it points up in the global parent
coordinate system. The second example shows how `attach()` points the
cylinder UP from the perspective of an ant standing at the anchor
point on the sphere.
```openscad-3D
include<BOSL2/std.scad>
sphere(40)
position(RIGHT+TOP) cylinder(r=8,l=20);
```
```openscad-3D
include<BOSL2/std.scad>
@ -491,9 +506,13 @@ direction you can use anchor arrows.
## Anchor Directions and Anchor Arrows
For the ant on the sphere it is obvious which direction is UP; that
direction corresponds to the Z+ axis. The location of the X and Y
axes is less clear and in fact it may be arbitrary.
One way that is useful to show the position and orientation of an anchor point is by attaching
an anchor arrow to that anchor. As noted before, the small red flag
points in the direction that is zero spin for the anchor.
points in the direction of the anchor's Y+ axis when the spin is
zero.
```openscad-3D
include <BOSL2/std.scad>
@ -565,7 +584,7 @@ cube(50,center=true)
In the second example, the child object point diagonally away
from the cube. If you want the child at at edge of the parent it's
likely that this result will not be what you want. To get a different
result, use `position()`, maybe combined with `orient(anchor=)`.
result, use `position()` with `orient(anchor=)`, if needed.
If you give an anchor point to the child object it moves the child
around (in the attached coordinate system). Or alternatively you can
@ -595,16 +614,11 @@ appeared above the anchor point. The CENTER anchor generally has a
direction that points upward, so an attached object will keep its
orientation if attached to the CENTER of a parent.
```openscad-3D
include <BOSL2/std.scad>
cube(50,center=true)
attach(RIGHT)anchor_arrow(30);
By default, `attach()` places the child exactly flush with the surface of the parent. Sometimes
it's useful to have the child overlap the parent by insetting a bit. You can do this with the
`overlap=` argument to `attach()`. A positive value will inset the child into the parent, and
a negative value will outset out from the parent:
a negative value will outset out from the parent, which may be helpful
when doing differences.
```openscad-3D
include <BOSL2/std.scad>
@ -621,16 +635,17 @@ cube(50,center=true)
```
As with `position()`, you can still apply your own translations and
other transformations even after anchoring an object. However, the
other transformations even after attaching an object. However, the
order of operations now matters. If you apply a translation outside
of the anchor then it acts in the global coordinate system, so the
of the anchor then it acts in the parent's global coordinate system, so the
child moves up in this example:
```openscad-3D
include <BOSL2/std.scad>
cube(50,center=true)
up(10)
attach(RIGHT)cylinder(d1=30,d2=15,l=25);
up(13)
attach(RIGHT)
cylinder(d1=30,d2=15,l=25);
```
On the other hand, if you put the translation between the attach and
@ -640,7 +655,9 @@ the parent, so in the example below it moves to the right.
```openscad-3D
include <BOSL2/std.scad>
cube(50,center=true)
attach(RIGHT) up(10) cylinder(d1=30,d2=15,l=25);
attach(RIGHT)
up(13)
cylinder(d1=30,d2=15,l=25);
```
@ -658,13 +675,13 @@ attaching with those anchors.
```openscad-3D
include <BOSL2/std.scad>
cube(50,center=true) attach(TOP) anchor_arrow(30);
cube(50,anchor=BOT) attach(TOP) anchor_arrow(30);
right(60)cylinder(d1=30,d2=15,l=25) attach(TOP) anchor_arrow(30);
```
```openscad-3D
include <BOSL2/std.scad>
cube(50,center=true)
cube(50,anchor=BOT)
attach(TOP,TOP) cylinder(d1=30,d2=15,l=25);
```
@ -682,12 +699,20 @@ cube(50,center=true)
Note that when you attach with two anchors like this, the attachment
operation **overrides any anchor or orientation specified in the
child**. That means the child `anchor=` and `orient=` options are
child**. That means the child's `anchor=` and `orient=` options are
ignored.
Attachment with CENTER anchors can be surprising because the anchors
point upwards, so in the example below, the child's CENTER anchor
points up, so it is inverted when it is attached to the parent cone.
points up, so it is inverted when it is attached to the parent cone.
Note that the anchors are CENTER anchors, so the bases of the anchors are
hidden in the middle of the objects.
```openscad-3D
include <BOSL2/std.scad>
cylinder(d1=30,d2=15,l=25) attach(CENTER) anchor_arrow(40);
right(40)cylinder(d1=30,d2=15,l=25) attach(CENTER) anchor_arrow(40);
```
```openscad-3D
include <BOSL2/std.scad>
@ -715,13 +740,13 @@ desired anchors as a list to the `attach()` or `position()` modules:
```openscad-3D
include <BOSL2/std.scad>
cube(50, center=true)
attach([RIGHT,FRONT],TOP) cylinder(d1=50,d2=20,l=20);
attach([RIGHT,FRONT],TOP) cylinder(d1=35,d2=20,l=25);
```
```openscad-3D
include <BOSL2/std.scad>
cube(50, center=true)
position([TOP,RIGHT,FRONT]) cylinder(d1=50,d2=20,l=20);
position([TOP,RIGHT,FRONT]) cylinder(d1=35,d2=20,l=25);
```