mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-01 09:49:45 +00:00
joiners bugfix, attachments proofread
This commit is contained in:
parent
1cf60c41e2
commit
45826195c8
2 changed files with 90 additions and 59 deletions
58
joiners.scad
58
joiners.scad
|
@ -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)))),
|
||||
|
|
|
@ -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);
|
||||
```
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue