Updated attachment examples.

This commit is contained in:
Revar Desmera 2019-04-26 02:15:53 -07:00
parent 7d239a412d
commit c3b81ce27f
6 changed files with 605 additions and 529 deletions

View File

@ -19,12 +19,12 @@ For purposes of the BOSL2 library, the following terms apply:
## Common Arguments:
Args | What it is
------- | ----------------------------------------
fillet | Radius of rounding for interior or exterior edges.
chamfer | Size of chamfers/bevels for interior or exterior edges.
orient | Axis a part should be oriented along. Given as an XYZ triplet of rotation angles. It is recommended that you use the `ORIENT_` constants from `constants.scad`. Default is usually `ORIENT_Z` for vertical orientation.
anchor | Side of the object that should be anchored to the origin. Given as a vector towards the side of the part to align with the origin. It is recommended that you use the directional constants from `constants.scad`. Default is usually `CENTER` for centered.
Args | What it is
-------- | ----------------------------------------
rounding | Radius of rounding for interior or exterior edges.
chamfer | Size of chamfers/bevels for interior or exterior edges.
orient | Axis a part should be oriented along. Given as an XYZ triplet of rotation angles. It is recommended that you use the `ORIENT_` constants from `constants.scad`. Default is usually `ORIENT_Z` for vertical orientation.
anchor | Side of the object that should be anchored to the origin. Given as a vector towards the side of the part to align with the origin. It is recommended that you use the directional constants from `constants.scad`. Default is usually `CENTER` for centered.
## Examples
@ -85,6 +85,7 @@ The library files are as follows:
- [`vectors.scad`](https://github.com/revarbat/BOSL2/wiki/vectors.scad): Vector math functions.
- [`matrices.scad`](https://github.com/revarbat/BOSL2/wiki/matrices.scad): Matrix math and affine transformation functions.
- [`coords.scad`](https://github.com/revarbat/BOSL2/wiki/coords.scad): Coordinate system conversions and point transformations.
- [`geometry.scad`](https://github.com/revarbat/BOSL2/wiki/geometry.scad): Functions to calculate various geometry.
- [`quaternions.scad`](https://github.com/revarbat/BOSL2/wiki/quaternions.scad): Functions to work with quaternion rotations.
- [`convex_hull.scad`](https://github.com/revarbat/BOSL2/wiki/convex_hull.scad): Functions to generate 2D and 3D hulls of points.
- [`triangulation.scad`](https://github.com/revarbat/BOSL2/wiki/triangulation.scad): Functions to triangulate `polyhedron()` faces.

View File

@ -106,6 +106,7 @@ function find_anchor(anchor, h, size, size2=undef, shift=[0,0], extra_anchors=[]
two_d? sidevec :
anchor==CENTER? UP :
norm([anchor.x,anchor.y]) < EPSILON? anchor :
norm(size)+norm(size2) < EPSILON? anchor :
abs(anchor.z) < EPSILON? sidevec :
anchor.z>0? (UP+sidevec)/2 :
(DOWN+sidevec)/2
@ -162,6 +163,7 @@ function _str_char_split(s,delim,n=0,acc=[],word="") =
// `$parent_orient` is set to the parent object's `orient` value.
// `$parent_anchor` is set to the parent object's `anchor` value.
// `$parent_anchors` is set to the parent object's list of non-standard extra anchors.
// `$parent_2d` is set to the parent object's `two_d` value.
//
// Example:
// #cylinder(d=5, h=10);
@ -248,14 +250,14 @@ module orient_and_anchor(
// Attaches children to a parent object at an anchor point and orientation.
// Arguments:
// name = The name of the parent anchor point to attach to.
// to = The name of the child anchor point.
// overlap = Amount to sink child into the parent.
// norot = If true, don't rotate children when attaching to the anchor point.
// to = Optional name of the child anchor point. If given, orients the child such that the named anchors align together rotationally.
// overlap = Amount to sink child into the parent. Equivalent to `down(X)` after the attach.
// norot = If true, don't rotate children when attaching to the anchor point. Only translate to the anchor point.
// Example:
// spheroid(d=20) {
// attach(TOP) down(1.5) cyl(l=11.5, d1=10, d2=5, anchor=BOTTOM);
// attach(TOP) down(1.5) cyl(l=11.5, d1=10, d2=5, anchor=BOTTOM);
// attach(RIGHT, BOTTOM) down(1.5) cyl(l=11.5, d1=10, d2=5);
// attach(FRONT) down(1.5) cyl(l=11.5, d1=10, d2=5, anchor=BOTTOM);
// attach(FRONT, BOTTOM, overlap=1.5) cyl(l=11.5, d1=10, d2=5);
// }
module attach(name, to=undef, overlap=undef, norot=false)
{
@ -296,6 +298,8 @@ module tags(tags)
// recolor(c) ...
// Description:
// Sets the color for children that can use the $color special variable.
// Arguments:
// c = Color name or RGBA vector.
// Example:
// recolor("red") cyl(l=20, d=10);
module recolor(c)
@ -308,7 +312,13 @@ module recolor(c)
// Module: hide()
// Usage:
// hide(tags) ...
// Description: Hides all children with the given tags.
// Description:
// Hides all children with the given tags.
// Example:
// hide("A") cube(50, anchor=CENTER, $tags="Main") {
// attach(LEFT, BOTTOM) cylinder(d=30, l=30, $tags="A");
// attach(RIGHT, BOTTOM) cylinder(d=30, l=30, $tags="B");
// }
module hide(tags="")
{
$tags_hidden = tags==""? [] : _str_char_split(tags, " ");
@ -319,7 +329,13 @@ module hide(tags="")
// Module: show()
// Usage:
// show(tags) ...
// Description: Shows only children with the given tags.
// Description:
// Shows only children with the given tags.
// Example:
// show("A B") cube(50, anchor=CENTER, $tags="Main") {
// attach(LEFT, BOTTOM) cylinder(d=30, l=30, $tags="A");
// attach(RIGHT, BOTTOM) cylinder(d=30, l=30, $tags="B");
// }
module show(tags="")
{
$tags_shown = tags==""? [] : _str_char_split(tags, " ");
@ -343,6 +359,12 @@ module show(tags="")
// neg = String containing space delimited set of tag names of children to difference away.
// pos = String containing space delimited set of tag names of children to be differenced away from.
// keep = String containing space delimited set of tag names of children to keep whole.
// Example:
// diff("neg", "pos", keep="axle")
// sphere(d=100, $tags="pos") {
// attach(CENTER) xcyl(d=40, h=120, $tags="axle");
// attach(CENTER) cube([40,120,100], anchor=CENTER, $tags="neg");
// }
module diff(neg, pos=undef, keep=undef)
{
difference() {
@ -382,6 +404,12 @@ module diff(neg, pos=undef, keep=undef)
// a = String containing space delimited set of tag names of children.
// b = String containing space delimited set of tag names of children.
// keep = String containing space delimited set of tag names of children to keep whole.
// Example:
// intersect("wheel", "mask", keep="axle")
// sphere(d=100, $tags="wheel") {
// attach(CENTER) cube([40,100,100], anchor=CENTER, $tags="mask");
// attach(CENTER) xcyl(d=40, h=100, $tags="axle");
// }
module intersect(a, b=undef, keep=undef)
{
intersection() {

View File

@ -2,7 +2,7 @@ include <BOSL2/std.scad>
$fn=32;
cuboid([60,40,40], fillet=5, edges=EDGES_Z_ALL, anchor=BOTTOM) {
cuboid([60,40,40], rounding=5, edges=EDGES_Z_ALL, anchor=BOTTOM) {
attach(TOP, BOTTOM) rounded_prismoid([60,40],[20,20], h=50, r1=5, r2=10) {
attach(TOP) cylinder(d=20, h=30) {
attach(TOP) cylinder(d1=50, d2=30, h=12);

View File

@ -1108,520 +1108,6 @@ module onion(cap_h=undef, r=undef, d=undef, maxang=45, h=undef, orient=ORIENT_Z,
}
// Module: narrowing_strut()
//
// Description:
// Makes a rectangular strut with the top side narrowing in a triangle.
// The shape created may be likened to an extruded home plate from baseball.
// This is useful for constructing parts that minimize the need to support
// overhangs.
//
// Usage:
// narrowing_strut(w, l, wall, [ang], [orient], [anchor]);
//
// Arguments:
// w = Width (thickness) of the strut.
// l = Length of the strut.
// wall = height of rectangular portion of the strut.
// ang = angle that the trianglar side will converge at.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `FRONT`.
//
// Example:
// narrowing_strut(w=10, l=100, wall=5, ang=30);
module narrowing_strut(w=10, l=100, wall=5, ang=30, orient=ORIENT_Y, anchor=FRONT)
{
h = wall + w/2/tan(ang);
size = [w, h, l];
orient_and_anchor(size, orient, anchor, chain=true) {
fwd(h/2) {
linear_extrude(height=l, center=true, slices=2) {
back(wall/2) square([w, wall], center=true);
back(wall-0.001) {
yscale(1/tan(ang)) {
difference() {
zrot(45) square(w/sqrt(2), center=true);
fwd(w/2) square(w, center=true);
}
}
}
}
}
children();
}
}
// Module: thinning_wall()
//
// Description:
// Makes a rectangular wall which thins to a smaller width in the center,
// with angled supports to prevent critical overhangs.
//
// Usage:
// thinning_wall(h, l, thick, [ang], [strut], [wall], [orient], [anchor]);
//
// Arguments:
// h = height of wall.
// l = length of wall. If given as a vector of two numbers, specifies bottom and top lengths, respectively.
// thick = thickness of wall.
// ang = maximum overhang angle of diagonal brace.
// strut = the width of the diagonal brace.
// wall = the thickness of the thinned portion of the wall.
// orient = Orientation of the length axis of the wall. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_X`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// thinning_wall(h=50, l=80, thick=4);
// Example: Trapezoidal
// thinning_wall(h=50, l=[80,50], thick=4);
module thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orient=ORIENT_Z, anchor=CENTER)
{
l1 = (l[0] == undef)? l : l[0];
l2 = (l[1] == undef)? l : l[1];
trap_ang = atan2((l2-l1)/2, h);
corr1 = 1 + sin(trap_ang);
corr2 = 1 - sin(trap_ang);
z1 = h/2;
z2 = max(0.1, z1 - strut);
z3 = max(0.05, z2 - (thick-wall)/2*sin(90-ang)/sin(ang));
x1 = l2/2;
x2 = max(0.1, x1 - strut*corr1);
x3 = max(0.05, x2 - (thick-wall)/2*sin(90-ang)/sin(ang)*corr1);
x4 = l1/2;
x5 = max(0.1, x4 - strut*corr2);
x6 = max(0.05, x5 - (thick-wall)/2*sin(90-ang)/sin(ang)*corr2);
y1 = thick/2;
y2 = y1 - min(z2-z3, x2-x3) * sin(ang);
size = [l1, thick, h];
orient_and_anchor(size, orient, anchor, size2=[l2,thick], chain=true) {
polyhedron(
points=[
[-x4, -y1, -z1],
[ x4, -y1, -z1],
[ x1, -y1, z1],
[-x1, -y1, z1],
[-x5, -y1, -z2],
[ x5, -y1, -z2],
[ x2, -y1, z2],
[-x2, -y1, z2],
[-x6, -y2, -z3],
[ x6, -y2, -z3],
[ x3, -y2, z3],
[-x3, -y2, z3],
[-x4, y1, -z1],
[ x4, y1, -z1],
[ x1, y1, z1],
[-x1, y1, z1],
[-x5, y1, -z2],
[ x5, y1, -z2],
[ x2, y1, z2],
[-x2, y1, z2],
[-x6, y2, -z3],
[ x6, y2, -z3],
[ x3, y2, z3],
[-x3, y2, z3],
],
faces=[
[ 4, 5, 1],
[ 5, 6, 2],
[ 6, 7, 3],
[ 7, 4, 0],
[ 4, 1, 0],
[ 5, 2, 1],
[ 6, 3, 2],
[ 7, 0, 3],
[ 8, 9, 5],
[ 9, 10, 6],
[10, 11, 7],
[11, 8, 4],
[ 8, 5, 4],
[ 9, 6, 5],
[10, 7, 6],
[11, 4, 7],
[11, 10, 9],
[20, 21, 22],
[11, 9, 8],
[20, 22, 23],
[16, 17, 21],
[17, 18, 22],
[18, 19, 23],
[19, 16, 20],
[16, 21, 20],
[17, 22, 21],
[18, 23, 22],
[19, 20, 23],
[12, 13, 17],
[13, 14, 18],
[14, 15, 19],
[15, 12, 16],
[12, 17, 16],
[13, 18, 17],
[14, 19, 18],
[15, 16, 19],
[ 0, 1, 13],
[ 1, 2, 14],
[ 2, 3, 15],
[ 3, 0, 12],
[ 0, 13, 12],
[ 1, 14, 13],
[ 2, 15, 14],
[ 3, 12, 15],
],
convexity=6
);
children();
}
}
// Module: braced_thinning_wall()
//
// Description:
// Makes a rectangular wall with cross-bracing, which thins to a smaller width in the center,
// with angled supports to prevent critical overhangs.
//
// Usage:
// braced_thinning_wall(h, l, thick, [ang], [strut], [wall], [orient], [anchor]);
//
// Arguments:
// h = height of wall.
// l = length of wall.
// thick = thickness of wall.
// ang = maximum overhang angle of diagonal brace.
// strut = the width of the diagonal brace.
// wall = the thickness of the thinned portion of the wall.
// orient = Orientation of the length axis of the wall. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// braced_thinning_wall(h=50, l=100, thick=5);
module braced_thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orient=ORIENT_Y, anchor=CENTER)
{
dang = atan((h-2*strut)/(l-2*strut));
dlen = (h-2*strut)/sin(dang);
size = [l, thick, h];
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
union() {
xrot_copies([0, 180]) {
down(h/2) narrowing_strut(w=thick, l=l, wall=strut, ang=ang);
fwd(l/2) xrot(-90) narrowing_strut(w=thick, l=h-0.1, wall=strut, ang=ang);
intersection() {
cube(size=[thick, l, h], center=true);
xrot_copies([-dang,dang]) {
zspread(strut/2) {
scale([1,1,1.5]) yrot(45) {
cube(size=[thick/sqrt(2), dlen, thick/sqrt(2)], center=true);
}
}
cube(size=[thick, dlen, strut/2], center=true);
}
}
}
cube(size=[wall, l-0.1, h-0.1], center=true);
}
children();
}
}
// Module: thinning_triangle()
//
// Description:
// Makes a triangular wall with thick edges, which thins to a smaller width in
// the center, with angled supports to prevent critical overhangs.
//
// Usage:
// thinning_triangle(h, l, thick, [ang], [strut], [wall], [diagonly], [orient], [anchor|center]);
//
// Arguments:
// h = height of wall.
// l = length of wall.
// thick = thickness of wall.
// ang = maximum overhang angle of diagonal brace.
// strut = the width of the diagonal brace.
// wall = the thickness of the thinned portion of the wall.
// diagonly = boolean, which denotes only the diagonal side (hypotenuse) should be thick.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// center = If true, centers shape. If false, overrides `anchor` with `UP+BACK`.
//
// Example: Centered
// thinning_triangle(h=50, l=80, thick=4, ang=30, strut=5, wall=2, center=true);
// Example: All Braces
// thinning_triangle(h=50, l=80, thick=4, ang=30, strut=5, wall=2, center=false);
// Example: Diagonal Brace Only
// thinning_triangle(h=50, l=80, thick=4, ang=30, strut=5, wall=2, diagonly=true, center=false);
module thinning_triangle(h=50, l=100, thick=5, ang=30, strut=5, wall=3, diagonly=false, center=undef, orient=ORIENT_Y, anchor=CENTER)
{
dang = atan(h/l);
dlen = h/sin(dang);
size = [thick, h, l];
orient_and_anchor(size, orient, anchor, center=center, noncentered=BOTTOM+FRONT, orig_orient=ORIENT_Y, chain=true) {
difference() {
union() {
if (!diagonly) {
translate([0, 0, -h/2])
narrowing_strut(w=thick, l=l, wall=strut, ang=ang);
translate([0, -l/2, 0])
xrot(-90) narrowing_strut(w=thick, l=h-0.1, wall=strut, ang=ang);
}
intersection() {
cube(size=[thick, l, h], center=true);
xrot(-dang) yrot(180) {
narrowing_strut(w=thick, l=dlen*1.2, wall=strut, ang=ang);
}
}
cube(size=[wall, l-0.1, h-0.1], center=true);
}
xrot(-dang) {
translate([0, 0, h/2]) {
cube(size=[thick+0.1, l*2, h], center=true);
}
}
}
children();
}
}
// Module: sparse_strut()
//
// Description:
// Makes an open rectangular strut with X-shaped cross-bracing, designed to reduce
// the need for support material in 3D printing.
//
// Usage:
// sparse_strut(h, l, thick, [strut], [maxang], [max_bridge], [orient], [anchor])
//
// Arguments:
// h = height of strut wall.
// l = length of strut wall.
// thick = thickness of strut wall.
// maxang = maximum overhang angle of cross-braces.
// max_bridge = maximum bridging distance between cross-braces.
// strut = the width of the cross-braces.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// sparse_strut(h=40, l=100, thick=3);
// Example: Thinner Strut
// sparse_strut(h=40, l=100, thick=3, strut=2);
// Example: Larger maxang
// sparse_strut(h=40, l=100, thick=3, strut=2, maxang=45);
// Example: Longer max_bridge
// sparse_strut(h=40, l=100, thick=3, strut=2, maxang=45, max_bridge=30);
module sparse_strut(h=50, l=100, thick=4, maxang=30, strut=5, max_bridge=20, orient=ORIENT_Y, anchor=CENTER)
{
zoff = h/2 - strut/2;
yoff = l/2 - strut/2;
maxhyp = 1.5 * (max_bridge+strut)/2 / sin(maxang);
maxz = 2 * maxhyp * cos(maxang);
zreps = ceil(2*zoff/maxz);
zstep = 2*zoff / zreps;
hyp = zstep/2 / cos(maxang);
maxy = min(2 * hyp * sin(maxang), max_bridge+strut);
yreps = ceil(2*yoff/maxy);
ystep = 2*yoff / yreps;
ang = atan(ystep/zstep);
len = zstep / cos(ang);
size = [thick, l, h];
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
union() {
zspread(zoff*2)
cube(size=[thick, l, strut], center=true);
yspread(yoff*2)
cube(size=[thick, strut, h], center=true);
yspread(ystep, n=yreps) {
zspread(zstep, n=zreps) {
xrot( ang) cube(size=[thick, strut, len], center=true);
xrot(-ang) cube(size=[thick, strut, len], center=true);
}
}
}
children();
}
}
// Module: sparse_strut3d()
//
// Usage:
// sparse_strut3d(h, w, l, [thick], [maxang], [max_bridge], [strut], [orient], [anchor]);
//
// Description:
// Makes an open rectangular strut with X-shaped cross-bracing, designed to reduce the
// need for support material in 3D printing.
//
// Arguments:
// h = Z size of strut.
// w = X size of strut.
// l = Y size of strut.
// thick = thickness of strut walls.
// maxang = maximum overhang angle of cross-braces.
// max_bridge = maximum bridging distance between cross-braces.
// strut = the width of the cross-braces.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// sparse_strut3d(h=30, w=30, l=100);
// Example: Thinner strut
// sparse_strut3d(h=30, w=30, l=100, strut=2);
// Example: Larger maxang
// sparse_strut3d(h=30, w=30, l=100, strut=2, maxang=50);
// Example: Smaller max_bridge
// sparse_strut3d(h=30, w=30, l=100, strut=2, maxang=50, max_bridge=20);
module sparse_strut3d(h=50, l=100, w=50, thick=3, maxang=40, strut=3, max_bridge=30, orient=ORIENT_Y, anchor=CENTER)
{
xoff = w - thick;
yoff = l - thick;
zoff = h - thick;
xreps = ceil(xoff/yoff);
yreps = ceil(yoff/xoff);
zreps = ceil(zoff/min(xoff, yoff));
xstep = xoff / xreps;
ystep = yoff / yreps;
zstep = zoff / zreps;
cross_ang = atan2(xstep, ystep);
cross_len = hypot(xstep, ystep);
supp_ang = min(maxang, min(atan2(max_bridge, zstep), atan2(cross_len/2, zstep)));
supp_reps = floor(cross_len/2/(zstep*sin(supp_ang)));
supp_step = cross_len/2/supp_reps;
size = [w, l, h];
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
intersection() {
union() {
ybridge = (l - (yreps+1) * strut) / yreps;
xspread(xoff) sparse_strut(h=h, l=l, thick=thick, maxang=maxang, strut=strut, max_bridge=ybridge/ceil(ybridge/max_bridge));
yspread(yoff) zrot(90) sparse_strut(h=h, l=w, thick=thick, maxang=maxang, strut=strut, max_bridge=max_bridge);
for(zs = [0:zreps-1]) {
for(xs = [0:xreps-1]) {
for(ys = [0:yreps-1]) {
translate([(xs+0.5)*xstep-xoff/2, (ys+0.5)*ystep-yoff/2, (zs+0.5)*zstep-zoff/2]) {
zflip_copy(offset=-(zstep-strut)/2) {
xflip_copy() {
zrot(cross_ang) {
down(strut/2) {
cube([strut, cross_len, strut], center=true);
}
if (zreps>1) {
back(cross_len/2) {
zrot(-cross_ang) {
down(strut) cube([strut, strut, zstep+strut], anchor=BOTTOM);
}
}
}
for (soff = [0 : supp_reps-1] ) {
yflip_copy() {
back(soff*supp_step) {
skew_xy(ya=supp_ang) {
cube([strut, strut, zstep], anchor=BOTTOM);
}
}
}
}
}
}
}
}
}
}
}
}
cube([w,l,h], center=true);
}
children();
}
}
// Module: corrugated_wall()
//
// Description:
// Makes a corrugated wall which relieves contraction stress while still
// providing support strength. Designed with 3D printing in mind.
//
// Usage:
// corrugated_wall(h, l, thick, [strut], [wall], [orient], [anchor]);
//
// Arguments:
// h = height of strut wall.
// l = length of strut wall.
// thick = thickness of strut wall.
// strut = the width of the cross-braces.
// wall = thickness of corrugations.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// corrugated_wall(h=50, l=100);
// Example: Wider Strut
// corrugated_wall(h=50, l=100, strut=8);
// Example: Thicker Wall
// corrugated_wall(h=50, l=100, strut=8, wall=3);
module corrugated_wall(h=50, l=100, thick=5, strut=5, wall=2, orient=ORIENT_Y, anchor=CENTER)
{
amplitude = (thick - wall) / 2;
period = min(15, thick * 2);
steps = quantup(segs(thick/2),4);
step = period/steps;
il = l - 2*strut + 2*step;
size = [thick, l, h];
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
union() {
linear_extrude(height=h-2*strut+0.1, slices=2, convexity=ceil(2*il/period), center=true) {
polygon(
points=concat(
[for (y=[-il/2:step:il/2]) [amplitude*sin(y/period*360)-wall/2, y] ],
[for (y=[il/2:-step:-il/2]) [amplitude*sin(y/period*360)+wall/2, y] ]
)
);
}
difference() {
cube([thick, l, h], center=true);
cube([thick+0.5, l-2*strut, h-2*strut], center=true);
}
}
children();
}
}
// Section: Miscellaneous

View File

@ -459,7 +459,7 @@ module zflip(cp=[0,0,0]) translate(cp) mirror([0,0,1]) translate(-cp) children()
// Skews children on the X-Y plane, keeping constant in Z.
//
// Usage:
// skew_xy([xa], [ya]) ...
// skew_xy([xa], [ya], [planar]) ...
//
// Arguments:
// xa = skew angle towards the X direction.

561
walls.scad Normal file
View File

@ -0,0 +1,561 @@
//////////////////////////////////////////////////////////////////////
// LibFile: walls.scad
// Various wall constructions.
// To use, add the following lines to the beginning of your file:
// ```
// include <BOSL2/std.scad>
// include <BOSL2/walls.scad>
// ```
//////////////////////////////////////////////////////////////////////
/*
BSD 2-Clause License
Copyright (c) 2017-2019, Revar Desmera
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Section: Walls
// Module: narrowing_strut()
//
// Description:
// Makes a rectangular strut with the top side narrowing in a triangle.
// The shape created may be likened to an extruded home plate from baseball.
// This is useful for constructing parts that minimize the need to support
// overhangs.
//
// Usage:
// narrowing_strut(w, l, wall, [ang], [orient], [anchor]);
//
// Arguments:
// w = Width (thickness) of the strut.
// l = Length of the strut.
// wall = height of rectangular portion of the strut.
// ang = angle that the trianglar side will converge at.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `FRONT`.
//
// Example:
// narrowing_strut(w=10, l=100, wall=5, ang=30);
module narrowing_strut(w=10, l=100, wall=5, ang=30, orient=ORIENT_Y, anchor=FRONT)
{
h = wall + w/2/tan(ang);
size = [w, h, l];
orient_and_anchor(size, orient, anchor, chain=true) {
fwd(h/2) {
linear_extrude(height=l, center=true, slices=2) {
back(wall/2) square([w, wall], center=true);
back(wall-0.001) {
yscale(1/tan(ang)) {
difference() {
zrot(45) square(w/sqrt(2), center=true);
fwd(w/2) square(w, center=true);
}
}
}
}
}
children();
}
}
// Module: thinning_wall()
//
// Description:
// Makes a rectangular wall which thins to a smaller width in the center,
// with angled supports to prevent critical overhangs.
//
// Usage:
// thinning_wall(h, l, thick, [ang], [strut], [wall], [orient], [anchor]);
//
// Arguments:
// h = height of wall.
// l = length of wall. If given as a vector of two numbers, specifies bottom and top lengths, respectively.
// thick = thickness of wall.
// ang = maximum overhang angle of diagonal brace.
// strut = the width of the diagonal brace.
// wall = the thickness of the thinned portion of the wall.
// orient = Orientation of the length axis of the wall. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_X`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// thinning_wall(h=50, l=80, thick=4);
// Example: Trapezoidal
// thinning_wall(h=50, l=[80,50], thick=4);
module thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orient=ORIENT_Z, anchor=CENTER)
{
l1 = (l[0] == undef)? l : l[0];
l2 = (l[1] == undef)? l : l[1];
trap_ang = atan2((l2-l1)/2, h);
corr1 = 1 + sin(trap_ang);
corr2 = 1 - sin(trap_ang);
z1 = h/2;
z2 = max(0.1, z1 - strut);
z3 = max(0.05, z2 - (thick-wall)/2*sin(90-ang)/sin(ang));
x1 = l2/2;
x2 = max(0.1, x1 - strut*corr1);
x3 = max(0.05, x2 - (thick-wall)/2*sin(90-ang)/sin(ang)*corr1);
x4 = l1/2;
x5 = max(0.1, x4 - strut*corr2);
x6 = max(0.05, x5 - (thick-wall)/2*sin(90-ang)/sin(ang)*corr2);
y1 = thick/2;
y2 = y1 - min(z2-z3, x2-x3) * sin(ang);
size = [l1, thick, h];
orient_and_anchor(size, orient, anchor, size2=[l2,thick], chain=true) {
polyhedron(
points=[
[-x4, -y1, -z1],
[ x4, -y1, -z1],
[ x1, -y1, z1],
[-x1, -y1, z1],
[-x5, -y1, -z2],
[ x5, -y1, -z2],
[ x2, -y1, z2],
[-x2, -y1, z2],
[-x6, -y2, -z3],
[ x6, -y2, -z3],
[ x3, -y2, z3],
[-x3, -y2, z3],
[-x4, y1, -z1],
[ x4, y1, -z1],
[ x1, y1, z1],
[-x1, y1, z1],
[-x5, y1, -z2],
[ x5, y1, -z2],
[ x2, y1, z2],
[-x2, y1, z2],
[-x6, y2, -z3],
[ x6, y2, -z3],
[ x3, y2, z3],
[-x3, y2, z3],
],
faces=[
[ 4, 5, 1],
[ 5, 6, 2],
[ 6, 7, 3],
[ 7, 4, 0],
[ 4, 1, 0],
[ 5, 2, 1],
[ 6, 3, 2],
[ 7, 0, 3],
[ 8, 9, 5],
[ 9, 10, 6],
[10, 11, 7],
[11, 8, 4],
[ 8, 5, 4],
[ 9, 6, 5],
[10, 7, 6],
[11, 4, 7],
[11, 10, 9],
[20, 21, 22],
[11, 9, 8],
[20, 22, 23],
[16, 17, 21],
[17, 18, 22],
[18, 19, 23],
[19, 16, 20],
[16, 21, 20],
[17, 22, 21],
[18, 23, 22],
[19, 20, 23],
[12, 13, 17],
[13, 14, 18],
[14, 15, 19],
[15, 12, 16],
[12, 17, 16],
[13, 18, 17],
[14, 19, 18],
[15, 16, 19],
[ 0, 1, 13],
[ 1, 2, 14],
[ 2, 3, 15],
[ 3, 0, 12],
[ 0, 13, 12],
[ 1, 14, 13],
[ 2, 15, 14],
[ 3, 12, 15],
],
convexity=6
);
children();
}
}
// Module: braced_thinning_wall()
//
// Description:
// Makes a rectangular wall with cross-bracing, which thins to a smaller width in the center,
// with angled supports to prevent critical overhangs.
//
// Usage:
// braced_thinning_wall(h, l, thick, [ang], [strut], [wall], [orient], [anchor]);
//
// Arguments:
// h = height of wall.
// l = length of wall.
// thick = thickness of wall.
// ang = maximum overhang angle of diagonal brace.
// strut = the width of the diagonal brace.
// wall = the thickness of the thinned portion of the wall.
// orient = Orientation of the length axis of the wall. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// braced_thinning_wall(h=50, l=100, thick=5);
module braced_thinning_wall(h=50, l=100, thick=5, ang=30, strut=5, wall=2, orient=ORIENT_Y, anchor=CENTER)
{
dang = atan((h-2*strut)/(l-2*strut));
dlen = (h-2*strut)/sin(dang);
size = [l, thick, h];
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
union() {
xrot_copies([0, 180]) {
down(h/2) narrowing_strut(w=thick, l=l, wall=strut, ang=ang);
fwd(l/2) xrot(-90) narrowing_strut(w=thick, l=h-0.1, wall=strut, ang=ang);
intersection() {
cube(size=[thick, l, h], center=true);
xrot_copies([-dang,dang]) {
zspread(strut/2) {
scale([1,1,1.5]) yrot(45) {
cube(size=[thick/sqrt(2), dlen, thick/sqrt(2)], center=true);
}
}
cube(size=[thick, dlen, strut/2], center=true);
}
}
}
cube(size=[wall, l-0.1, h-0.1], center=true);
}
children();
}
}
// Module: thinning_triangle()
//
// Description:
// Makes a triangular wall with thick edges, which thins to a smaller width in
// the center, with angled supports to prevent critical overhangs.
//
// Usage:
// thinning_triangle(h, l, thick, [ang], [strut], [wall], [diagonly], [orient], [anchor|center]);
//
// Arguments:
// h = height of wall.
// l = length of wall.
// thick = thickness of wall.
// ang = maximum overhang angle of diagonal brace.
// strut = the width of the diagonal brace.
// wall = the thickness of the thinned portion of the wall.
// diagonly = boolean, which denotes only the diagonal side (hypotenuse) should be thick.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
// center = If true, centers shape. If false, overrides `anchor` with `UP+BACK`.
//
// Example: Centered
// thinning_triangle(h=50, l=80, thick=4, ang=30, strut=5, wall=2, center=true);
// Example: All Braces
// thinning_triangle(h=50, l=80, thick=4, ang=30, strut=5, wall=2, center=false);
// Example: Diagonal Brace Only
// thinning_triangle(h=50, l=80, thick=4, ang=30, strut=5, wall=2, diagonly=true, center=false);
module thinning_triangle(h=50, l=100, thick=5, ang=30, strut=5, wall=3, diagonly=false, center=undef, orient=ORIENT_Y, anchor=CENTER)
{
dang = atan(h/l);
dlen = h/sin(dang);
size = [thick, h, l];
orient_and_anchor(size, orient, anchor, center=center, noncentered=BOTTOM+FRONT, orig_orient=ORIENT_Y, chain=true) {
difference() {
union() {
if (!diagonly) {
translate([0, 0, -h/2])
narrowing_strut(w=thick, l=l, wall=strut, ang=ang);
translate([0, -l/2, 0])
xrot(-90) narrowing_strut(w=thick, l=h-0.1, wall=strut, ang=ang);
}
intersection() {
cube(size=[thick, l, h], center=true);
xrot(-dang) yrot(180) {
narrowing_strut(w=thick, l=dlen*1.2, wall=strut, ang=ang);
}
}
cube(size=[wall, l-0.1, h-0.1], center=true);
}
xrot(-dang) {
translate([0, 0, h/2]) {
cube(size=[thick+0.1, l*2, h], center=true);
}
}
}
children();
}
}
// Module: sparse_strut()
//
// Description:
// Makes an open rectangular strut with X-shaped cross-bracing, designed to reduce
// the need for support material in 3D printing.
//
// Usage:
// sparse_strut(h, l, thick, [strut], [maxang], [max_bridge], [orient], [anchor])
//
// Arguments:
// h = height of strut wall.
// l = length of strut wall.
// thick = thickness of strut wall.
// maxang = maximum overhang angle of cross-braces.
// max_bridge = maximum bridging distance between cross-braces.
// strut = the width of the cross-braces.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// sparse_strut(h=40, l=100, thick=3);
// Example: Thinner Strut
// sparse_strut(h=40, l=100, thick=3, strut=2);
// Example: Larger maxang
// sparse_strut(h=40, l=100, thick=3, strut=2, maxang=45);
// Example: Longer max_bridge
// sparse_strut(h=40, l=100, thick=3, strut=2, maxang=45, max_bridge=30);
module sparse_strut(h=50, l=100, thick=4, maxang=30, strut=5, max_bridge=20, orient=ORIENT_Y, anchor=CENTER)
{
zoff = h/2 - strut/2;
yoff = l/2 - strut;
maxhyp = 1.5 * (max_bridge+strut)/2 / sin(maxang);
maxz = 2 * maxhyp * cos(maxang);
zreps = ceil(2*zoff/maxz);
zstep = 2*zoff / zreps;
hyp = zstep/2 / cos(maxang);
maxy = min(2 * hyp * sin(maxang), max_bridge+strut);
yreps = ceil(2*yoff/maxy);
ystep = 2*yoff / yreps;
ang = atan(ystep/zstep);
len = zstep / cos(ang);
size = [thick, l, h];
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
yrot(90)
linear_extrude(height=thick, convexity=4*yreps, center=true) {
difference() {
square([h, l], center=true);
square([h-2*strut, l-2*strut], center=true);
}
yspread(ystep, n=yreps) {
xspread(zstep, n=zreps) {
skew_xy(planar=true, ya=-ang) square([h-1.99*strut, strut], center=true);
skew_xy(planar=true, ya= ang) square([h-1.99*strut, strut], center=true);
}
}
}
children();
}
}
// Module: sparse_strut3d()
//
// Usage:
// sparse_strut3d(h, w, l, [thick], [maxang], [max_bridge], [strut], [orient], [anchor]);
//
// Description:
// Makes an open rectangular strut with X-shaped cross-bracing, designed to reduce the
// need for support material in 3D printing.
//
// Arguments:
// h = Z size of strut.
// w = X size of strut.
// l = Y size of strut.
// thick = thickness of strut walls.
// maxang = maximum overhang angle of cross-braces.
// max_bridge = maximum bridging distance between cross-braces.
// strut = the width of the cross-braces.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// sparse_strut3d(h=30, w=30, l=100);
// Example: Thinner strut
// sparse_strut3d(h=30, w=30, l=100, strut=2);
// Example: Larger maxang
// sparse_strut3d(h=30, w=30, l=100, strut=2, maxang=50);
// Example: Smaller max_bridge
// sparse_strut3d(h=30, w=30, l=100, strut=2, maxang=50, max_bridge=20);
module sparse_strut3d(h=50, l=100, w=50, thick=3, maxang=40, strut=3, max_bridge=30, orient=ORIENT_Y, anchor=CENTER)
{
xoff = w - thick;
yoff = l - thick;
zoff = h - thick;
xreps = ceil(xoff/yoff);
yreps = ceil(yoff/xoff);
zreps = ceil(zoff/min(xoff, yoff));
xstep = xoff / xreps;
ystep = yoff / yreps;
zstep = zoff / zreps;
cross_ang = atan2(xstep, ystep);
cross_len = hypot(xstep, ystep);
supp_ang = min(maxang, min(atan2(max_bridge, zstep), atan2(cross_len/2, zstep)));
supp_reps = floor(cross_len/2/(zstep*sin(supp_ang)));
supp_step = cross_len/2/supp_reps;
size = [w, l, h];
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
intersection() {
union() {
ybridge = (l - (yreps+1) * strut) / yreps;
xspread(xoff) sparse_strut(h=h, l=l, thick=thick, maxang=maxang, strut=strut, max_bridge=ybridge/ceil(ybridge/max_bridge));
yspread(yoff) zrot(90) sparse_strut(h=h, l=w, thick=thick, maxang=maxang, strut=strut, max_bridge=max_bridge);
for(zs = [0:zreps-1]) {
for(xs = [0:xreps-1]) {
for(ys = [0:yreps-1]) {
translate([(xs+0.5)*xstep-xoff/2, (ys+0.5)*ystep-yoff/2, (zs+0.5)*zstep-zoff/2]) {
zflip_copy(offset=-(zstep-strut)/2) {
xflip_copy() {
zrot(cross_ang) {
down(strut/2) {
cube([strut, cross_len, strut], center=true);
}
if (zreps>1) {
back(cross_len/2) {
zrot(-cross_ang) {
down(strut) cube([strut, strut, zstep+strut], anchor=BOTTOM);
}
}
}
for (soff = [0 : supp_reps-1] ) {
yflip_copy() {
back(soff*supp_step) {
skew_xy(ya=supp_ang) {
cube([strut, strut, zstep], anchor=BOTTOM);
}
}
}
}
}
}
}
}
}
}
}
}
cube([w,l,h], center=true);
}
children();
}
}
// Module: corrugated_wall()
//
// Description:
// Makes a corrugated wall which relieves contraction stress while still
// providing support strength. Designed with 3D printing in mind.
//
// Usage:
// corrugated_wall(h, l, thick, [strut], [wall], [orient], [anchor]);
//
// Arguments:
// h = height of strut wall.
// l = length of strut wall.
// thick = thickness of strut wall.
// strut = the width of the cross-braces.
// wall = thickness of corrugations.
// orient = Orientation of the length axis of the shape. Use the `ORIENT_` constants from `constants.scad`. Default: `ORIENT_Y`.
// anchor = Alignment of the shape. Use the constants from `constants.scad`. Default: `CENTER`.
//
// Example: Typical Shape
// corrugated_wall(h=50, l=100);
// Example: Wider Strut
// corrugated_wall(h=50, l=100, strut=8);
// Example: Thicker Wall
// corrugated_wall(h=50, l=100, strut=8, wall=3);
module corrugated_wall(h=50, l=100, thick=5, strut=5, wall=2, orient=ORIENT_Y, anchor=CENTER)
{
amplitude = (thick - wall) / 2;
period = min(15, thick * 2);
steps = quantup(segs(thick/2),4);
step = period/steps;
il = l - 2*strut + 2*step;
size = [thick, l, h];
orient_and_anchor(size, orient, anchor, orig_orient=ORIENT_Y, chain=true) {
union() {
linear_extrude(height=h-2*strut+0.1, slices=2, convexity=ceil(2*il/period), center=true) {
polygon(
points=concat(
[for (y=[-il/2:step:il/2]) [amplitude*sin(y/period*360)-wall/2, y] ],
[for (y=[il/2:-step:-il/2]) [amplitude*sin(y/period*360)+wall/2, y] ]
)
);
}
difference() {
cube([thick, l, h], center=true);
cube([thick+0.5, l-2*strut, h-2*strut], center=true);
}
}
children();
}
}
// vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap