Updated tutorials.

This commit is contained in:
Garth Minette 2021-04-17 19:17:44 -07:00
parent f47b02d9ef
commit fe788f56b5
7 changed files with 513 additions and 515 deletions

View file

@ -15,7 +15,7 @@ done
if [[ "$FILES" != "" ]]; then if [[ "$FILES" != "" ]]; then
PREVIEW_LIBS="$FILES" PREVIEW_LIBS="$FILES"
else else
PREVIEW_LIBS="Shapes2d Shapes3d Transforms Distributors Mutators Paths FractalTree" PREVIEW_LIBS="Shapes2d Shapes3d Transforms Distributors Mutators Attachments Paths FractalTree"
fi fi
dir="$(basename $PWD)" dir="$(basename $PWD)"

View file

@ -14,7 +14,7 @@ imgmgr = ImageManager()
def img_started(req): def img_started(req):
print(" {}... ".format(os.path.basename(req.src_file)), end='') print(" {}... ".format(os.path.basename(req.image_file)), end='')
sys.stdout.flush() sys.stdout.flush()
@ -52,7 +52,7 @@ def processFile(infile, outfile=None, imgroot=""):
outdata = [] outdata = []
with open(infile, "r") as f: with open(infile, "r") as f:
script = [] script = ["include <BOSL2/std.scad>"]
extyp = "" extyp = ""
in_script = False in_script = False
imgnum = 0 imgnum = 0
@ -67,26 +67,24 @@ def processFile(infile, outfile=None, imgroot=""):
extyp = line.split("-")[1] extyp = line.split("-")[1]
else: else:
extyp = "" extyp = ""
line = "```openscad"
script = []
show_script = "ImgOnly" not in extyp show_script = "ImgOnly" not in extyp
script = ["include <BOSL2/std.scad>"]
imgnum = imgnum + 1 imgnum = imgnum + 1
if show_script:
outdata.append(line)
elif in_script: elif in_script:
if show_script:
outdata.append(line)
if line == "```": if line == "```":
in_script = False in_script = False
imgfile = "{}_{}.png".format(fileroot, imgnum) imgfile = os.path.join(imgroot, "{}_{}.png".format(fileroot, imgnum))
imgmgr.new_request( imgmgr.new_request(
fileroot+".md", linenum, fileroot+".md", linenum,
imgfile, script, extyp, imgfile, script, extyp,
starting_cb=img_started, starting_cb=img_started,
completion_cb=img_completed completion_cb=img_completed
) )
outdata.append("![Figure {}]({})".format(imgnum, imgroot + imgfile)) if show_script:
script = [] outdata.append("```openscad")
outdata.extend(script)
outdata.append("```")
outdata.append("![Figure {}]({})".format(imgnum, imgfile))
show_script = True show_script = True
extyp = "" extyp = ""
else: else:

View file

@ -7,51 +7,51 @@ Sometimes you want to take a 3D shape like a sphere, and cut it in half.
The BOSL2 library provides a number of ways to do this: The BOSL2 library provides a number of ways to do this:
```openscad ```openscad
left_half() sphere(d=100); left_half() sphere(d=100);
``` ```
```openscad ```openscad
right_half() sphere(d=100); right_half() sphere(d=100);
``` ```
```openscad ```openscad
front_half() sphere(d=100); front_half() sphere(d=100);
``` ```
```openscad ```openscad
back_half() sphere(d=100); back_half() sphere(d=100);
``` ```
```openscad ```openscad
bottom_half() sphere(d=100); bottom_half() sphere(d=100);
``` ```
```openscad ```openscad
top_half() sphere(d=100); top_half() sphere(d=100);
``` ```
You can use the `half_of()` module if you want to split space in a way not aligned with an axis: You can use the `half_of()` module if you want to split space in a way not aligned with an axis:
```openscad ```openscad
half_of([-1,0,-1]) sphere(d=100); half_of([-1,0,-1]) sphere(d=100);
``` ```
The plane of dissection can be shifted along the axis of any of these operators: The plane of dissection can be shifted along the axis of any of these operators:
```openscad ```openscad
left_half(x=20) sphere(d=100); left_half(x=20) sphere(d=100);
``` ```
```openscad ```openscad
back_half(y=-20) sphere(d=100); back_half(y=-20) sphere(d=100);
``` ```
```openscad ```openscad
bottom_half(z=20) sphere(d=100); bottom_half(z=20) sphere(d=100);
``` ```
```openscad ```openscad
half_of([-1,0,-1], cp=[20,0,20]) sphere(d=100); half_of([-1,0,-1], cp=[20,0,20]) sphere(d=100);
``` ```
By default, these operators can be applied to objects that fit in a cube 1000 on a side. If you need By default, these operators can be applied to objects that fit in a cube 1000 on a side. If you need
@ -59,59 +59,59 @@ to apply these halving operators to objects larger than this, you can give the s
argument: argument:
```openscad ```openscad
bottom_half(s=2000) sphere(d=1500); bottom_half(s=2000) sphere(d=1500);
``` ```
## 2D Plane Halving ## 2D Plane Halving
To cut 2D shapes in half, you will need to add the `planar=true` argument: To cut 2D shapes in half, you will need to add the `planar=true` argument:
```openscad ```openscad
left_half(planar=true) circle(d=100); left_half(planar=true) circle(d=100);
``` ```
```openscad ```openscad
right_half(planar=true) circle(d=100); right_half(planar=true) circle(d=100);
``` ```
```openscad ```openscad
front_half(planar=true) circle(d=100); front_half(planar=true) circle(d=100);
``` ```
```openscad ```openscad
back_half(planar=true) circle(d=100); back_half(planar=true) circle(d=100);
``` ```
## Chained Mutators ## Chained Mutators
If you have a set of shapes that you want to do pair-wise hulling of, you can use `chain_hull()`: If you have a set of shapes that you want to do pair-wise hulling of, you can use `chain_hull()`:
```openscad ```openscad
chain_hull() { chain_hull() {
cube(5, center=true); cube(5, center=true);
translate([30, 0, 0]) sphere(d=15); translate([30, 0, 0]) sphere(d=15);
translate([60, 30, 0]) cylinder(d=10, h=20); translate([60, 30, 0]) cylinder(d=10, h=20);
translate([60, 60, 0]) cube([10,1,20], center=false); translate([60, 60, 0]) cube([10,1,20], center=false);
} }
``` ```
## Extrusion Mutators ## Extrusion Mutators
The OpenSCAD `linear_extrude()` module can take a 2D shape and extrude it vertically in a line: The OpenSCAD `linear_extrude()` module can take a 2D shape and extrude it vertically in a line:
```openscad ```openscad
linear_extrude(height=30) zrot(45) square(40,center=true); linear_extrude(height=30) zrot(45) square(40,center=true);
``` ```
The `rotate_extrude()` module can take a 2D shape and rotate it around the Z axis. The `rotate_extrude()` module can take a 2D shape and rotate it around the Z axis.
```openscad ```openscad
linear_extrude(height=30) left(30) zrot(45) square(40,center=true); linear_extrude(height=30) left(30) zrot(45) square(40,center=true);
``` ```
In a similar manner, the BOSL2 `cylindrical_extrude()` module can take a 2d shape and extrude it In a similar manner, the BOSL2 `cylindrical_extrude()` module can take a 2d shape and extrude it
out radially from the center of a cylinder: out radially from the center of a cylinder:
```openscad ```openscad
cylindrical_extrude(or=40, ir=35) cylindrical_extrude(or=40, ir=35)
text(text="Hello World!", size=10, halign="center", valign="center"); text(text="Hello World!", size=10, halign="center", valign="center");
``` ```
@ -121,61 +121,61 @@ out radially from the center of a cylinder:
Openscad provides the `minkowski()` module to trace a shape over the entire surface of another shape: Openscad provides the `minkowski()` module to trace a shape over the entire surface of another shape:
```openscad ```openscad
minkowski() { minkowski() {
union() { union() {
cube([100,33,33], center=true); cube([100,33,33], center=true);
cube([33,100,33], center=true); cube([33,100,33], center=true);
cube([33,33,100], center=true); cube([33,33,100], center=true);
}
sphere(r=8);
} }
sphere(r=8);
}
``` ```
However, it doesn't provide the inverse of this operation; to remove a shape from the entire surface However, it doesn't provide the inverse of this operation; to remove a shape from the entire surface
of another object. For this, the BOSL2 library provides the `minkowski_difference()` module: of another object. For this, the BOSL2 library provides the `minkowski_difference()` module:
```openscad ```openscad
minkowski_difference() { minkowski_difference() {
union() { union() {
cube([100,33,33], center=true); cube([100,33,33], center=true);
cube([33,100,33], center=true); cube([33,100,33], center=true);
cube([33,33,100], center=true); cube([33,33,100], center=true);
}
sphere(r=8);
} }
sphere(r=8);
}
``` ```
To perform a `minkowski_difference()` on 2D shapes, you need to supply the `planar=true` argument: To perform a `minkowski_difference()` on 2D shapes, you need to supply the `planar=true` argument:
```openscad-2D ```openscad-2D
minkowski_difference(planar=true) { minkowski_difference(planar=true) {
union() { union() {
square([100,33], center=true); square([100,33], center=true);
square([33,100], center=true); square([33,100], center=true);
}
circle(r=8);
} }
circle(r=8);
}
``` ```
### Round2d ### Round2d
The `round2d()` module lets you take a 2D shape and round inside and outside corners. The inner concave corners are rounded to the radius `ir=`, while the outer convex corners are rounded to the radius `or=`: The `round2d()` module lets you take a 2D shape and round inside and outside corners. The inner concave corners are rounded to the radius `ir=`, while the outer convex corners are rounded to the radius `or=`:
```openscad-2D ```openscad-2D
round2d(or=8) star(6, step=2, d=100); round2d(or=8) star(6, step=2, d=100);
``` ```
```openscad-2D ```openscad-2D
round2d(ir=12) star(6, step=2, d=100); round2d(ir=12) star(6, step=2, d=100);
``` ```
```openscad-2D ```openscad-2D
round2d(or=8,ir=12) star(6, step=2, d=100); round2d(or=8,ir=12) star(6, step=2, d=100);
``` ```
You can use `r=` to effectively set both `ir=` and `or=` to the same value: You can use `r=` to effectively set both `ir=` and `or=` to the same value:
```openscad-2D ```openscad-2D
round2d(r=8) star(6, step=2, d=100); round2d(r=8) star(6, step=2, d=100);
``` ```
### Shell2d ### Shell2d
@ -183,62 +183,62 @@ With the `shell2d()` module, you can take an arbitrary shape, and get the shell
With a positive thickness, the shell is offset outwards from the original shape: With a positive thickness, the shell is offset outwards from the original shape:
```openscad-2D ```openscad-2D
shell2d(thickness=5) star(5,step=2,d=100); shell2d(thickness=5) star(5,step=2,d=100);
color("blue") stroke(star(5,step=2,d=100),closed=true); color("blue") stroke(star(5,step=2,d=100),closed=true);
``` ```
With a negative thickness, the shell if inset from the original shape: With a negative thickness, the shell if inset from the original shape:
```openscad-2D ```openscad-2D
shell2d(thickness=-5) star(5,step=2,d=100); shell2d(thickness=-5) star(5,step=2,d=100);
color("blue") stroke(star(5,step=2,d=100),closed=true); color("blue") stroke(star(5,step=2,d=100),closed=true);
``` ```
You can give a pair of thickness values if you want it both inset and outset from the original shape: You can give a pair of thickness values if you want it both inset and outset from the original shape:
```openscad-2D ```openscad-2D
shell2d(thickness=[-5,5]) star(5,step=2,d=100); shell2d(thickness=[-5,5]) star(5,step=2,d=100);
color("blue") stroke(star(5,step=2,d=100),closed=true); color("blue") stroke(star(5,step=2,d=100),closed=true);
``` ```
You can add rounding to the outside by passing a radius to the `or=` argument. You can add rounding to the outside by passing a radius to the `or=` argument.
```openscad-2D ```openscad-2D
shell2d(thickness=-5,or=5) star(5,step=2,d=100); shell2d(thickness=-5,or=5) star(5,step=2,d=100);
``` ```
If you need to pass different radii for the convex and concave corners of the outside, you can pass them as `or=[CONVEX,CONCAVE]`: If you need to pass different radii for the convex and concave corners of the outside, you can pass them as `or=[CONVEX,CONCAVE]`:
```openscad-2D ```openscad-2D
shell2d(thickness=-5,or=[5,10]) star(5,step=2,d=100); shell2d(thickness=-5,or=[5,10]) star(5,step=2,d=100);
``` ```
A radius of 0 can be used to specify no rounding: A radius of 0 can be used to specify no rounding:
```openscad-2D ```openscad-2D
shell2d(thickness=-5,or=[5,0]) star(5,step=2,d=100); shell2d(thickness=-5,or=[5,0]) star(5,step=2,d=100);
``` ```
You can add rounding to the inside by passing a radius to the `ir=` argument. You can add rounding to the inside by passing a radius to the `ir=` argument.
```openscad-2D ```openscad-2D
shell2d(thickness=-5,ir=5) star(5,step=2,d=100); shell2d(thickness=-5,ir=5) star(5,step=2,d=100);
``` ```
If you need to pass different radii for the convex and concave corners of the inside, you can pass them as `ir=[CONVEX,CONCAVE]`: If you need to pass different radii for the convex and concave corners of the inside, you can pass them as `ir=[CONVEX,CONCAVE]`:
```openscad-2D ```openscad-2D
shell2d(thickness=-5,ir=[8,3]) star(5,step=2,d=100); shell2d(thickness=-5,ir=[8,3]) star(5,step=2,d=100);
``` ```
You can use `or=` and `ir=` together to get nice combined rounding effects: You can use `or=` and `ir=` together to get nice combined rounding effects:
```openscad-2D ```openscad-2D
shell2d(thickness=-5,or=[7,2],ir=[7,2]) star(5,step=2,d=100); shell2d(thickness=-5,or=[7,2],ir=[7,2]) star(5,step=2,d=100);
``` ```
```openscad-2D ```openscad-2D
shell2d(thickness=-5,or=[5,0],ir=[5,0]) star(5,step=2,d=100); shell2d(thickness=-5,or=[5,0],ir=[5,0]) star(5,step=2,d=100);
``` ```
@ -253,21 +253,21 @@ easier to select colors using other color schemes. You can use the HSL or Hue-S
color scheme with the `HSL()` module: color scheme with the `HSL()` module:
```openscad ```openscad
for (h=[0:0.1:1], s=[0:0.1:1], l=[0:0.1:1]) { for (h=[0:0.1:1], s=[0:0.1:1], l=[0:0.1:1]) {
translate(100*[h,s,l]) { translate(100*[h,s,l]) {
HSL(h*360,1-s,l) cube(10,center=true); HSL(h*360,1-s,l) cube(10,center=true);
}
} }
}
``` ```
You can use the HSV or Hue-Saturation-Value color scheme with the `HSV()` module: You can use the HSV or Hue-Saturation-Value color scheme with the `HSV()` module:
```openscad ```openscad
for (h=[0:0.1:1], s=[0:0.1:1], v=[0:0.1:1]) { for (h=[0:0.1:1], s=[0:0.1:1], v=[0:0.1:1]) {
translate(100*[h,s,v]) { translate(100*[h,s,v]) {
HSV(h*360,1-s,v) cube(10,center=true); HSV(h*360,1-s,v) cube(10,center=true);
}
} }
}
``` ```

View file

@ -18,64 +18,64 @@ A path can be hard to visualize, since it's just a bunch of numbers in the sourc
One way to see the path is to pass it to `polygon()`: One way to see the path is to pass it to `polygon()`:
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
polygon(path); polygon(path);
``` ```
Sometimes, however, it's easier to see just the path itself. For this, you can use the `stroke()` module. Sometimes, however, it's easier to see just the path itself. For this, you can use the `stroke()` module.
At its most basic, `stroke()` just shows the path's line segments: At its most basic, `stroke()` just shows the path's line segments:
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path); stroke(path);
``` ```
You can vary the width of the drawn path with the `width=` argument: You can vary the width of the drawn path with the `width=` argument:
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, width=3); stroke(path, width=3);
``` ```
You can vary the line length along the path by giving a list of widths, one per point: You can vary the line length along the path by giving a list of widths, one per point:
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, width=[3,2,1,2,3]); stroke(path, width=[3,2,1,2,3]);
``` ```
If a path is meant to represent a closed polygon, you can use `closed=true` to show it that way: If a path is meant to represent a closed polygon, you can use `closed=true` to show it that way:
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, closed=true); stroke(path, closed=true);
``` ```
The ends of the drawn path are normally capped with a "round" endcap, but there are other options: The ends of the drawn path are normally capped with a "round" endcap, but there are other options:
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcaps="round"); stroke(path, endcaps="round");
``` ```
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcaps="butt"); stroke(path, endcaps="butt");
``` ```
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcaps="line"); stroke(path, endcaps="line");
``` ```
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcaps="tail"); stroke(path, endcaps="tail");
``` ```
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcaps="arrow2"); stroke(path, endcaps="arrow2");
``` ```
For more standard supported endcap options, see the docs for [`stroke()`](shapes2d.scad#stroke). For more standard supported endcap options, see the docs for [`stroke()`](shapes2d.scad#stroke).
@ -83,26 +83,26 @@ For more standard supported endcap options, see the docs for [`stroke()`](shapes
The start and ending endcaps can be specified individually or separately, using `endcap1=` and `endcap2=`: The start and ending endcaps can be specified individually or separately, using `endcap1=` and `endcap2=`:
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcap1="butt", endcap2="arrow2"); stroke(path, endcap1="butt", endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
stroke(path, endcap1="tail", endcap2="arrow"); stroke(path, endcap1="tail", endcap2="arrow");
``` ```
The size of the endcaps will be relative to the width of the line where the endcap is to be placed: The size of the endcaps will be relative to the width of the line where the endcap is to be placed:
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
widths = [1, 1.25, 1.5, 1.75, 2]; widths = [1, 1.25, 1.5, 1.75, 2];
stroke(path, width=widths, endcaps="arrow2"); stroke(path, width=widths, endcaps="arrow2");
``` ```
If none of the standard endcaps are useful to you, it is possible to design your own, simply by If none of the standard endcaps are useful to you, it is possible to design your own, simply by
@ -114,104 +114,104 @@ line width size.
Untrimmed: Untrimmed:
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
dblarrow = [[0,0], [2,-3], [0.5,-2.3], [2,-4], [0.5,-3.5], [-0.5,-3.5], [-2,-4], [-0.5,-2.3], [-2,-3]]; dblarrow = [[0,0], [2,-3], [0.5,-2.3], [2,-4], [0.5,-3.5], [-0.5,-3.5], [-2,-4], [-0.5,-2.3], [-2,-3]];
stroke(path, endcaps=dblarrow); stroke(path, endcaps=dblarrow);
``` ```
Trimmed: Trimmed:
```openscad-2D ```openscad-2D
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]]; path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
dblarrow = [[0,0], [2,-3], [0.5,-2.3], [2,-4], [0.5,-3.5], [-0.5,-3.5], [-2,-4], [-0.5,-2.3], [-2,-3]]; dblarrow = [[0,0], [2,-3], [0.5,-2.3], [2,-4], [0.5,-3.5], [-0.5,-3.5], [-2,-4], [-0.5,-2.3], [-2,-3]];
stroke(path, trim=3.5, endcaps=dblarrow); stroke(path, trim=3.5, endcaps=dblarrow);
``` ```
### Standard 2D Shape Polygons ### Standard 2D Shape Polygons
BOSL2 will let you get the perimeter polygon for almost all of the standard 2D shapes simply by calling them like a function: BOSL2 will let you get the perimeter polygon for almost all of the standard 2D shapes simply by calling them like a function:
```openscad-2D ```openscad-2D
path = square(40, center=true); path = square(40, center=true);
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = rect([40,30], rounding=5, center=true); path = rect([40,30], rounding=5, center=true);
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = trapezoid(w1=40, w2=20, h=30); path = trapezoid(w1=40, w2=20, h=30);
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = circle(d=50); path = circle(d=50);
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = oval(d=[50,30]); path = oval(d=[50,30]);
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = pentagon(d=50); path = pentagon(d=50);
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = star(n=5, step=2, d=50); path = star(n=5, step=2, d=50);
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
### Arcs ### Arcs
Often, when you are constructing a path, you will want to add an arc. The `arc()` command lets you do that: Often, when you are constructing a path, you will want to add an arc. The `arc()` command lets you do that:
```openscad-2D ```openscad-2D
path = arc(r=30, angle=120); path = arc(r=30, angle=120);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = arc(d=60, angle=120); path = arc(d=60, angle=120);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
If you give the `N=` argument, you can control exactly how many points the arc is divided into: If you give the `N=` argument, you can control exactly how many points the arc is divided into:
```openscad-2D ```openscad-2D
path = arc(N=5, r=30, angle=120); path = arc(N=5, r=30, angle=120);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
With the `start=` argument, you can start the arc somewhere other than the X+ axis: With the `start=` argument, you can start the arc somewhere other than the X+ axis:
```openscad-2D ```openscad-2D
path = arc(start=45, r=30, angle=120); path = arc(start=45, r=30, angle=120);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
Alternatively, you can give starting and ending angles in a list in the `angle=` argument: Alternatively, you can give starting and ending angles in a list in the `angle=` argument:
```openscad-2D ```openscad-2D
path = arc(angle=[120,45], r=30); path = arc(angle=[120,45], r=30);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
The `cp=` argument lets you center the arc somewhere other than the origin: The `cp=` argument lets you center the arc somewhere other than the origin:
```openscad-2D ```openscad-2D
path = arc(cp=[10,0], r=30, angle=120); path = arc(cp=[10,0], r=30, angle=120);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
The arc can also be given by three points on the arc: The arc can also be given by three points on the arc:
```openscad-2D ```openscad-2D
pts = [[-15,10],[0,20],[35,-5]]; pts = [[-15,10],[0,20],[35,-5]];
path = arc(points=pts); path = arc(points=pts);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
@ -222,75 +222,75 @@ turtle or cursor walking a path. It can "move" forward or backward, or turn "le
place: place:
```openscad-2D ```openscad-2D
path = turtle([ path = turtle([
"move", 10, "move", 10,
"left", 90, "left", 90,
"move", 20, "move", 20,
"left", 135, "left", 135,
"move", 10*sqrt(2), "move", 10*sqrt(2),
"right", 90, "right", 90,
"move", 10*sqrt(2), "move", 10*sqrt(2),
"left", 135, "left", 135,
"move", 20 "move", 20
]); ]);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
The position and the facing of the turtle/cursor updates after each command. The motion and turning The position and the facing of the turtle/cursor updates after each command. The motion and turning
commands can also have default distances or angles given: commands can also have default distances or angles given:
```openscad-2D ```openscad-2D
path = turtle([ path = turtle([
"angle",360/6, "angle",360/6,
"length",10, "length",10,
"move","turn", "move","turn",
"move","turn", "move","turn",
"move","turn", "move","turn",
"move","turn", "move","turn",
"move" "move"
]); ]);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
You can use "scale" to relatively scale up the default motion length: You can use "scale" to relatively scale up the default motion length:
```openscad-2D ```openscad-2D
path = turtle([ path = turtle([
"angle",360/6, "angle",360/6,
"length",10, "length",10,
"move","turn", "move","turn",
"move","turn", "move","turn",
"scale",2, "scale",2,
"move","turn", "move","turn",
"move","turn", "move","turn",
"scale",0.5, "scale",0.5,
"move" "move"
]); ]);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
Sequences of commands can be repeated using the "repeat" command: Sequences of commands can be repeated using the "repeat" command:
```openscad-2D ```openscad-2D
path=turtle([ path=turtle([
"angle",360/5, "angle",360/5,
"length",10, "length",10,
"repeat",5,["move","turn"] "repeat",5,["move","turn"]
]); ]);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
More complicated commands also exist, including those that form arcs: More complicated commands also exist, including those that form arcs:
```openscad-2D ```openscad-2D
path = turtle([ path = turtle([
"move", 10, "move", 10,
"left", 90, "left", 90,
"move", 20, "move", 20,
"arcleft", 10, 180, "arcleft", 10, 180,
"move", 20 "move", 20
]); ]);
stroke(path, endcap2="arrow2"); stroke(path, endcap2="arrow2");
``` ```
A comprehensive list of supported turtle commands can be found in the docs for [`turtle()`](shapes2d.scad#turtle). A comprehensive list of supported turtle commands can be found in the docs for [`turtle()`](shapes2d.scad#turtle).
@ -299,97 +299,97 @@ A comprehensive list of supported turtle commands can be found in the docs for [
To translate a path, you can just pass it to the `move()` (or up/down/left/right/fwd/back) function in the `p=` argument: To translate a path, you can just pass it to the `move()` (or up/down/left/right/fwd/back) function in the `p=` argument:
```openscad-2D ```openscad-2D
path = move([-15,-30], p=square(50,center=true)); path = move([-15,-30], p=square(50,center=true));
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = fwd(30, p=square(50,center=true)); path = fwd(30, p=square(50,center=true));
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = left(30, p=square(50,center=true)); path = left(30, p=square(50,center=true));
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
To scale a path, you can just pass it to the `scale()` (or [xyz]scale) function in the `p=` argument: To scale a path, you can just pass it to the `scale()` (or [xyz]scale) function in the `p=` argument:
```openscad-2D ```openscad-2D
path = scale([1.5,0.75], p=square(50,center=true)); path = scale([1.5,0.75], p=square(50,center=true));
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = xscale(1.5, p=square(50,center=true)); path = xscale(1.5, p=square(50,center=true));
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = yscale(1.5, p=square(50,center=true)); path = yscale(1.5, p=square(50,center=true));
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
To rotate a path, just can pass it to the `rot()` (or [xyz]rot) function in the `p=` argument: To rotate a path, just can pass it to the `rot()` (or [xyz]rot) function in the `p=` argument:
```openscad-2D ```openscad-2D
path = rot(30, p=square(50,center=true)); path = rot(30, p=square(50,center=true));
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = zrot(30, p=square(50,center=true)); path = zrot(30, p=square(50,center=true));
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
To mirror a path, just can pass it to the `mirror()` (or [xyz]flip) function in the `p=` argument: To mirror a path, just can pass it to the `mirror()` (or [xyz]flip) function in the `p=` argument:
```openscad-2D ```openscad-2D
path = mirror([1,1], p=trapezoid(w1=40, w2=10, h=25)); path = mirror([1,1], p=trapezoid(w1=40, w2=10, h=25));
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = xflip(p=trapezoid(w1=40, w2=10, h=25)); path = xflip(p=trapezoid(w1=40, w2=10, h=25));
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
```openscad-2D ```openscad-2D
path = yflip(p=trapezoid(w1=40, w2=10, h=25)); path = yflip(p=trapezoid(w1=40, w2=10, h=25));
stroke(path, closed=true, endcap2="arrow2"); stroke(path, closed=true, endcap2="arrow2");
``` ```
You can get raw transformation matrices for various transformations by calling them like a function without a `p=` argument: You can get raw transformation matrices for various transformations by calling them like a function without a `p=` argument:
```openscad-2D ```openscad-2D
mat = move([5,10,0]); mat = move([5,10,0]);
multmatrix(mat) square(50,center=true); multmatrix(mat) square(50,center=true);
``` ```
```openscad-2D ```openscad-2D
mat = scale([1.5,0.75,1]); mat = scale([1.5,0.75,1]);
multmatrix(mat) square(50,center=true); multmatrix(mat) square(50,center=true);
``` ```
```openscad-2D ```openscad-2D
mat = rot(30); mat = rot(30);
multmatrix(mat) square(50,center=true); multmatrix(mat) square(50,center=true);
``` ```
Raw transformation matrices can be multiplied together to precalculate a compound transformation. For example, to scale a shape, then rotate it, then translate the result, you can do something like: Raw transformation matrices can be multiplied together to precalculate a compound transformation. For example, to scale a shape, then rotate it, then translate the result, you can do something like:
```openscad-2D ```openscad-2D
mat = move([5,10,0]) * rot(30) * scale([1.5,0.75,1]); mat = move([5,10,0]) * rot(30) * scale([1.5,0.75,1]);
multmatrix(mat) square(50,center=true); multmatrix(mat) square(50,center=true);
``` ```
To apply a compound transformation matrix to a path, you can use the `apply()` function: To apply a compound transformation matrix to a path, you can use the `apply()` function:
```openscad-2D ```openscad-2D
mat = move([5,10]) * rot(30, planar=true) * scale([1.5,0.75]); mat = move([5,10]) * rot(30, planar=true) * scale([1.5,0.75]);
path = square(50,center=true); path = square(50,center=true);
tpath = apply(mat, path); tpath = apply(mat, path);
stroke(tpath, endcap2="arrow2"); stroke(tpath, endcap2="arrow2");
``` ```
@ -401,39 +401,39 @@ XORed against all the others. You can display a region using the `region()` mod
If you have a region with one polygon fully inside another, it makes a hole: If you have a region with one polygon fully inside another, it makes a hole:
```openscad-2D ```openscad-2D
rgn = [square(50,center=true), circle(d=30)]; rgn = [square(50,center=true), circle(d=30)];
region(rgn); region(rgn);
``` ```
If you have a region with multiple polygons that are not contained by any others, they make multiple discontiguous shapes: If you have a region with multiple polygons that are not contained by any others, they make multiple discontiguous shapes:
```openscad-2D ```openscad-2D
rgn = [ rgn = [
move([-30, 20], p=square(20,center=true)), move([-30, 20], p=square(20,center=true)),
move([ 0,-20], p=trapezoid(w1=20, w2=10, h=20)), move([ 0,-20], p=trapezoid(w1=20, w2=10, h=20)),
move([ 30, 20], p=square(20,center=true)), move([ 30, 20], p=square(20,center=true)),
]; ];
region(rgn); region(rgn);
``` ```
Region polygons can be nested abitrarily deep, in multiple discontiguous shapes: Region polygons can be nested abitrarily deep, in multiple discontiguous shapes:
```openscad-2D ```openscad-2D
rgn = [ rgn = [
for (d=[50:-10:10]) left(30, p=circle(d=d)), for (d=[50:-10:10]) left(30, p=circle(d=d)),
for (d=[50:-10:10]) right(30, p=circle(d=d)) for (d=[50:-10:10]) right(30, p=circle(d=d))
]; ];
region(rgn); region(rgn);
``` ```
A region with crossing polygons is somewhat poorly formed, but the intersection(s) of the polygons become holes: A region with crossing polygons is somewhat poorly formed, but the intersection(s) of the polygons become holes:
```openscad-2D ```openscad-2D
rgn = [ rgn = [
left(15, p=circle(d=50)), left(15, p=circle(d=50)),
right(15, p=circle(d=50)) right(15, p=circle(d=50))
]; ];
region(rgn); region(rgn);
``` ```
### Boolean Region Geometry ### Boolean Region Geometry
@ -441,65 +441,65 @@ Similarly to how OpenSCAD can perform operations like union/difference/intersect
the BOSL2 library lets you perform those same operations on regions: the BOSL2 library lets you perform those same operations on regions:
```openscad-2D ```openscad-2D
rgn1 = [for (d=[40:-10:10]) circle(d=d)]; rgn1 = [for (d=[40:-10:10]) circle(d=d)];
rgn2 = [square([60,12], center=true)]; rgn2 = [square([60,12], center=true)];
rgn = union(rgn1, rgn2); rgn = union(rgn1, rgn2);
region(rgn); region(rgn);
``` ```
```openscad-2D ```openscad-2D
rgn1 = [for (d=[40:-10:10]) circle(d=d)]; rgn1 = [for (d=[40:-10:10]) circle(d=d)];
rgn2 = [square([60,12], center=true)]; rgn2 = [square([60,12], center=true)];
rgn = difference(rgn1, rgn2); rgn = difference(rgn1, rgn2);
region(rgn); region(rgn);
``` ```
```openscad-2D ```openscad-2D
rgn1 = [for (d=[40:-10:10]) circle(d=d)]; rgn1 = [for (d=[40:-10:10]) circle(d=d)];
rgn2 = [square([60,12], center=true)]; rgn2 = [square([60,12], center=true)];
rgn = intersection(rgn1, rgn2); rgn = intersection(rgn1, rgn2);
region(rgn); region(rgn);
``` ```
```openscad-2D ```openscad-2D
rgn1 = [for (d=[40:-10:10]) circle(d=d)]; rgn1 = [for (d=[40:-10:10]) circle(d=d)];
rgn2 = [square([60,12], center=true)]; rgn2 = [square([60,12], center=true)];
rgn = exclusive_or(rgn1, rgn2); rgn = exclusive_or(rgn1, rgn2);
region(rgn); region(rgn);
``` ```
```openscad-2D ```openscad-2D
orig_rgn = [star(n=5, step=2, d=50)]; orig_rgn = [star(n=5, step=2, d=50)];
rgn = offset(orig_rgn, r=-3, closed=true); rgn = offset(orig_rgn, r=-3, closed=true);
color("blue") region(orig_rgn); color("blue") region(orig_rgn);
region(rgn); region(rgn);
``` ```
You can use regions for several useful things. If you wanted a grid of holes in your object that You can use regions for several useful things. If you wanted a grid of holes in your object that
form the shape given by a region, you can do that with `grid2d()`: form the shape given by a region, you can do that with `grid2d()`:
```openscad-3D ```openscad-3D
rgn = [ rgn = [
circle(d=100), circle(d=100),
star(n=5,step=2,d=100,spin=90) star(n=5,step=2,d=100,spin=90)
]; ];
difference() { difference() {
cyl(h=5, d=120); cyl(h=5, d=120);
grid2d(size=[120,120], spacing=[4,4], inside=rgn) cyl(h=10,d=2); grid2d(size=[120,120], spacing=[4,4], inside=rgn) cyl(h=10,d=2);
} }
``` ```
You can also sweep a region through 3-space to make a solid: You can also sweep a region through 3-space to make a solid:
```openscad-3D ```openscad-3D
$fa=1; $fs=1; $fa=1; $fs=1;
rgn = [ for (d=[50:-10:10]) circle(d=d) ]; rgn = [ for (d=[50:-10:10]) circle(d=d) ];
tforms = [ tforms = [
for (a=[90:-5:0]) xrot(a, cp=[0,-70]), for (a=[90:-5:0]) xrot(a, cp=[0,-70]),
for (a=[0:5:90]) xrot(a, cp=[0,70]), for (a=[0:5:90]) xrot(a, cp=[0,70]),
move([0,150,-70]) * xrot(90), move([0,150,-70]) * xrot(90),
]; ];
sweep(rgn, tforms, closed=false, caps=true); sweep(rgn, tforms, closed=false, caps=true);
``` ```

View file

@ -12,15 +12,15 @@ and more ways to simply reorient them.
You can still use the built-in `square()` in the familiar ways that OpenSCAD provides: You can still use the built-in `square()` in the familiar ways that OpenSCAD provides:
```openscad-2D ```openscad-2D
square(100, center=false); square(100, center=false);
``` ```
```openscad-2D ```openscad-2D
square(100, center=true); square(100, center=true);
``` ```
```openscad-2D ```openscad-2D
square([60,40], center=true); square([60,40], center=true);
``` ```
The BOSL2 library provides an enhanced equivalent to `square()` called `rect()`. The BOSL2 library provides an enhanced equivalent to `square()` called `rect()`.
@ -28,13 +28,13 @@ You can use it in the same way you use `square()`, but it also provides
extended functionality. For example, it allows you to round the corners: extended functionality. For example, it allows you to round the corners:
```openscad-2D ```openscad-2D
rect([60,40], center=true, rounding=10); rect([60,40], center=true, rounding=10);
``` ```
Or chamfer them: Or chamfer them:
```openscad-2D ```openscad-2D
rect([60,40], center=true, chamfer=10); rect([60,40], center=true, chamfer=10);
``` ```
You can even specify *which* corners get rounded or chamfered. If you pass a You can even specify *which* corners get rounded or chamfered. If you pass a
@ -44,26 +44,26 @@ corner, counter-clockwise around to the back-left (quadrant II) corner, to the
forward-left (quadrant III) corner, to the forward-right (quadrant IV) corner: forward-left (quadrant III) corner, to the forward-right (quadrant IV) corner:
```openscad-2DImgOnly ```openscad-2DImgOnly
module text3d(text) color("black") text( module text3d(text) color("black") text(
text=text, font="Times", size=10, text=text, font="Times", size=10,
halign="center", valign="center" halign="center", valign="center"
); );
translate([ 50, 50]) text3d("I"); translate([ 50, 50]) text3d("I");
translate([-50, 50]) text3d("II"); translate([-50, 50]) text3d("II");
translate([-50,-50]) text3d("III"); translate([-50,-50]) text3d("III");
translate([ 50,-50]) text3d("IV"); translate([ 50,-50]) text3d("IV");
rect([90,80], center=true); rect([90,80], center=true);
``` ```
If a size is given as `0`, then there is no rounding and/or chamfering for If a size is given as `0`, then there is no rounding and/or chamfering for
that quadrant's corner: that quadrant's corner:
```openscad-2D ```openscad-2D
rect([60,40], center=true, rounding=[0,5,10,15]); rect([60,40], center=true, rounding=[0,5,10,15]);
``` ```
```openscad-2D ```openscad-2D
rect([60,40], center=true, chamfer=[0,5,10,15]); rect([60,40], center=true, chamfer=[0,5,10,15]);
``` ```
You can give both `rounding=` and `chamfer=` arguments to mix rounding and You can give both `rounding=` and `chamfer=` arguments to mix rounding and
@ -71,7 +71,7 @@ chamfering, but only if you specify per corner. If you want a rounding in
a corner, specify a 0 chamfer for that corner, and vice versa: a corner, specify a 0 chamfer for that corner, and vice versa:
```openscad-2D ```openscad-2D
rect([60,40], center=true, rounding=[5,0,10,0], chamfer=[0,5,0,15]); rect([60,40], center=true, rounding=[5,0,10,0], chamfer=[0,5,0,15]);
``` ```
#### Anchors and Spin #### Anchors and Spin
@ -84,19 +84,19 @@ the side or corner you want to align to the origin. For example, to align
the center of the back edge to the origin, set the anchor to `[0,1]`: the center of the back edge to the origin, set the anchor to `[0,1]`:
```openscad-2D ```openscad-2D
rect([60,40], anchor=[0,1]); rect([60,40], anchor=[0,1]);
``` ```
To align the front right corner to the origin: To align the front right corner to the origin:
```openscad-2D ```openscad-2D
rect([60,40], anchor=[1,-1]); rect([60,40], anchor=[1,-1]);
``` ```
To center: To center:
```openscad-2D ```openscad-2D
rect([60,40], anchor=[0,0]); rect([60,40], anchor=[0,0]);
``` ```
To make it clearer when giving vectors, there are several standard vector To make it clearer when giving vectors, there are several standard vector
@ -116,52 +116,52 @@ Note that even though these are 3D vectors, you can use most of them,
(except `UP`/`DOWN`, of course) for anchors in 2D shapes: (except `UP`/`DOWN`, of course) for anchors in 2D shapes:
```openscad-2D ```openscad-2D
rect([60,40], anchor=BACK); rect([60,40], anchor=BACK);
``` ```
```openscad-2D ```openscad-2D
rect([60,40], anchor=CENTER); rect([60,40], anchor=CENTER);
``` ```
You can add vectors together to point to corners: You can add vectors together to point to corners:
```openscad-2D ```openscad-2D
rect([60,40], anchor=FRONT+RIGHT); rect([60,40], anchor=FRONT+RIGHT);
``` ```
Finally, the `spin` argument can rotate the shape by a given number of degrees Finally, the `spin` argument can rotate the shape by a given number of degrees
clockwise: clockwise:
```openscad-2D ```openscad-2D
rect([60,40], anchor=CENTER, spin=30); rect([60,40], anchor=CENTER, spin=30);
``` ```
Anchoring or centering is performed before the spin: Anchoring or centering is performed before the spin:
```openscad-2D ```openscad-2D
rect([60,40], anchor=BACK, spin=30); rect([60,40], anchor=BACK, spin=30);
``` ```
Anchor points double as attachment points, so that you can attach other shapes: Anchor points double as attachment points, so that you can attach other shapes:
```openscad-2D ```openscad-2D
rect([60,40],center=true) rect([60,40],center=true)
show_anchors(); show_anchors();
``` ```
### 2D Circles and Ovals ### 2D Circles and Ovals
The built-in `circle()` primitive can be used as expected: The built-in `circle()` primitive can be used as expected:
```openscad-2D ```openscad-2D
circle(r=50); circle(r=50);
``` ```
```openscad-2D ```openscad-2D
circle(d=100); circle(d=100);
``` ```
```openscad-2D ```openscad-2D
circle(d=100, $fn=8); circle(d=100, $fn=8);
``` ```
The BOSL2 library also provides an enhanced equivalent of `circle()` called `oval()`. The BOSL2 library also provides an enhanced equivalent of `circle()` called `oval()`.
@ -176,7 +176,7 @@ The `realign=` argument, if set `true`, rotates the `oval()` by half the angle
between the sides: between the sides:
```openscad-2D ```openscad-2D
oval(d=100, $fn=8, realign=true); oval(d=100, $fn=8, realign=true);
``` ```
The `circum=` argument, if true, makes it so that the polygon forming the The `circum=` argument, if true, makes it so that the polygon forming the
@ -185,19 +185,19 @@ The `circum=` argument, if true, makes it so that the polygon forming the
Inscribing the ideal circle: Inscribing the ideal circle:
```openscad-2D ```openscad-2D
difference() { difference() {
circle(d=100, $fn=360); circle(d=100, $fn=360);
oval(d=100, $fn=8); oval(d=100, $fn=8);
} }
``` ```
Circumscribing the ideal circle: Circumscribing the ideal circle:
```openscad-2D ```openscad-2D
difference() { difference() {
oval(d=100, $fn=8, circum=true); oval(d=100, $fn=8, circum=true);
circle(d=100, $fn=360); circle(d=100, $fn=360);
} }
``` ```
The `oval()` module, as its name suggests, can be given separate X and Y radii The `oval()` module, as its name suggests, can be given separate X and Y radii
@ -205,29 +205,29 @@ or diameters. To do this, just give `r=` or `d=` with a list of two radii or
diameters: diameters:
```openscad-2D ```openscad-2D
oval(r=[30,20]); oval(r=[30,20]);
``` ```
```openscad-2D ```openscad-2D
oval(d=[60,40]); oval(d=[60,40]);
``` ```
Another way that `oval()` is enhanced over `circle()`, is that you can anchor, Another way that `oval()` is enhanced over `circle()`, is that you can anchor,
spin and attach it. spin and attach it.
```openscad-2D ```openscad-2D
oval(r=50, anchor=BACK); oval(r=50, anchor=BACK);
``` ```
```openscad-2D ```openscad-2D
oval(r=50, anchor=FRONT+RIGHT); oval(r=50, anchor=FRONT+RIGHT);
``` ```
Using spin on a circle may not make initial sense, until you remember that Using spin on a circle may not make initial sense, until you remember that
anchoring is performed before spin: anchoring is performed before spin:
```openscad-2D ```openscad-2D
oval(r=50, anchor=FRONT, spin=-30); oval(r=50, anchor=FRONT, spin=-30);
``` ```
@ -239,51 +239,51 @@ The BOSL2 library can provide all of these shapes with the `trapezoid()` module.
To make a simple triangle, just make one of the widths zero: To make a simple triangle, just make one of the widths zero:
```openscad-2D ```openscad-2D
trapezoid(w1=50, w2=0, h=50); trapezoid(w1=50, w2=0, h=50);
``` ```
To make a right triangle, you need to use the `shift=` argument, to shift the back of the trapezoid along the X axis: To make a right triangle, you need to use the `shift=` argument, to shift the back of the trapezoid along the X axis:
```openscad-2D ```openscad-2D
trapezoid(w1=50, w2=0, h=50, shift=-25); trapezoid(w1=50, w2=0, h=50, shift=-25);
``` ```
```openscad-2D ```openscad-2D
trapezoid(w1=50, w2=0, h=50, shift=25); trapezoid(w1=50, w2=0, h=50, shift=25);
``` ```
```openscad-2D ```openscad-2D
trapezoid(w1=0, w2=50, h=50, shift=-25); trapezoid(w1=0, w2=50, h=50, shift=-25);
``` ```
```openscad-2D ```openscad-2D
trapezoid(w1=0, w2=50, h=50, shift=25); trapezoid(w1=0, w2=50, h=50, shift=25);
``` ```
You can make a trapezoid by specifying non-zero widths for both the front (`w1=`) and back (`w2=`): You can make a trapezoid by specifying non-zero widths for both the front (`w1=`) and back (`w2=`):
```openscad-2D ```openscad-2D
trapezoid(w1=30, w2=50, h=50); trapezoid(w1=30, w2=50, h=50);
``` ```
A parallelogram is just a matter of using the same width for front and back, with a shift along the X axis: A parallelogram is just a matter of using the same width for front and back, with a shift along the X axis:
```openscad-2D ```openscad-2D
trapezoid(w1=50, w2=50, shift=20, h=50); trapezoid(w1=50, w2=50, shift=20, h=50);
``` ```
A quadrilateral can be made by having unequal, non-zero front (`w1=`) and back (`w2=`) widths, with the back shifted along the X axis: A quadrilateral can be made by having unequal, non-zero front (`w1=`) and back (`w2=`) widths, with the back shifted along the X axis:
```openscad-2D ```openscad-2D
trapezoid(w1=50, w2=30, shift=20, h=50); trapezoid(w1=50, w2=30, shift=20, h=50);
``` ```
You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor
points are based on the side angles of the faces, and may not be where you expect them: points are based on the side angles of the faces, and may not be where you expect them:
```openscad-2D ```openscad-2D
trapezoid(w1=30, w2=50, h=50) trapezoid(w1=30, w2=50, h=50)
show_anchors(); show_anchors();
``` ```
### Regular N-Gons ### Regular N-Gons
@ -292,25 +292,25 @@ OpenSCAD lets you make regular N-gons (pentagon, hexagon, etc) by using `circle(
While this is concise, it may be less than obvious at first glance: While this is concise, it may be less than obvious at first glance:
```openscad-2D ```openscad-2D
circle(d=50, $fn=5); circle(d=50, $fn=5);
``` ```
The BOSL2 library has modules that are named more clearly: The BOSL2 library has modules that are named more clearly:
```openscad-2D ```openscad-2D
pentagon(d=50); pentagon(d=50);
``` ```
```openscad-2D ```openscad-2D
hexagon(d=50); hexagon(d=50);
``` ```
```openscad-2D ```openscad-2D
octagon(d=50); octagon(d=50);
``` ```
```openscad-2D ```openscad-2D
regular_ngon(n=7, d=50); regular_ngon(n=7, d=50);
``` ```
These modules also provide you with extra functionality. These modules also provide you with extra functionality.
@ -318,44 +318,44 @@ These modules also provide you with extra functionality.
They can be sized by side length: They can be sized by side length:
```openscad-2D ```openscad-2D
pentagon(side=20); pentagon(side=20);
``` ```
They can be sized by circumscribed circle radius/diameter: They can be sized by circumscribed circle radius/diameter:
```openscad-2D ```openscad-2D
pentagon(ir=25); pentagon(ir=25);
pentagon(id=50); pentagon(id=50);
``` ```
They can be realigned by half a side's angle: They can be realigned by half a side's angle:
```openscad-2D ```openscad-2D
left(30) pentagon(d=50, realign=true); left(30) pentagon(d=50, realign=true);
right(30) pentagon(d=50, realign=false); right(30) pentagon(d=50, realign=false);
``` ```
They can be rounded: They can be rounded:
```openscad-2D ```openscad-2D
pentagon(d=50, rounding=10); pentagon(d=50, rounding=10);
``` ```
```openscad-2D ```openscad-2D
hexagon(d=50, rounding=10); hexagon(d=50, rounding=10);
``` ```
They also have somewhat different attachment behavior: They also have somewhat different attachment behavior:
```openscad-2D ```openscad-2D
color("green") stroke(circle(d=50), closed=true); color("green") stroke(circle(d=50), closed=true);
oval(d=50,$fn=5) oval(d=50,$fn=5)
attach(LEFT) color("blue") anchor_arrow2d(); attach(LEFT) color("blue") anchor_arrow2d();
``` ```
```openscad-2D ```openscad-2D
pentagon(d=50) pentagon(d=50)
attach(LEFT) color("blue") anchor_arrow2d(); attach(LEFT) color("blue") anchor_arrow2d();
``` ```
You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor
@ -363,15 +363,15 @@ points are based on where the anchor vector would intersect the side of the N-go
be where you expect them: be where you expect them:
```openscad-2D ```openscad-2D
pentagon(d=50) pentagon(d=50)
show_anchors(custom=false); show_anchors(custom=false);
``` ```
N-gons also have named anchor points for their sides and tips: N-gons also have named anchor points for their sides and tips:
```openscad-2D ```openscad-2D
pentagon(d=30) pentagon(d=30)
show_anchors(std=false); show_anchors(std=false);
``` ```
@ -381,72 +381,72 @@ The BOSL2 library has stars as a basic supported shape. They can have any numbe
You can specify a star's shape by point count, inner and outer vertex radius/diameters: You can specify a star's shape by point count, inner and outer vertex radius/diameters:
```openscad-2D ```openscad-2D
star(n=3, id=10, d=50); star(n=3, id=10, d=50);
``` ```
```openscad-2D ```openscad-2D
star(n=5, id=15, r=25); star(n=5, id=15, r=25);
``` ```
```openscad-2D ```openscad-2D
star(n=10, id=30, d=50); star(n=10, id=30, d=50);
``` ```
Or you can specify the star shape by point count and number of points to step: Or you can specify the star shape by point count and number of points to step:
```openscad-2D ```openscad-2D
star(n=7, step=2, d=50); star(n=7, step=2, d=50);
``` ```
```openscad-2D ```openscad-2D
star(n=7, step=3, d=50); star(n=7, step=3, d=50);
``` ```
If the `realign=` argument is given a true value, then the star will be rotated by half a point angle: If the `realign=` argument is given a true value, then the star will be rotated by half a point angle:
```openscad-2D ```openscad-2D
left(30) star(n=5, step=2, d=50); left(30) star(n=5, step=2, d=50);
right(30) star(n=5, step=2, d=50, realign=true); right(30) star(n=5, step=2, d=50, realign=true);
``` ```
The `align_tip=` argument can be given a vector so that you can align the first point in a specific direction: The `align_tip=` argument can be given a vector so that you can align the first point in a specific direction:
```openscad-2D ```openscad-2D
star(n=5, ir=15, or=30, align_tip=BACK+LEFT) star(n=5, ir=15, or=30, align_tip=BACK+LEFT)
attach("tip0") color("blue") anchor_arrow2d(); attach("tip0") color("blue") anchor_arrow2d();
``` ```
```openscad-2D ```openscad-2D
star(n=5, ir=15, or=30, align_tip=BACK+RIGHT) star(n=5, ir=15, or=30, align_tip=BACK+RIGHT)
attach("tip0") color("blue") anchor_arrow2d(); attach("tip0") color("blue") anchor_arrow2d();
``` ```
Similarly, the first indentation or pit can be oriented towards a specific vector with `align_pit=`: Similarly, the first indentation or pit can be oriented towards a specific vector with `align_pit=`:
```openscad-2D ```openscad-2D
star(n=5, ir=15, or=30, align_pit=BACK+LEFT) star(n=5, ir=15, or=30, align_pit=BACK+LEFT)
attach("pit0") color("blue") anchor_arrow2d(); attach("pit0") color("blue") anchor_arrow2d();
``` ```
```openscad-2D ```openscad-2D
star(n=5, ir=15, or=30, align_pit=BACK+RIGHT) star(n=5, ir=15, or=30, align_pit=BACK+RIGHT)
attach("pit0") color("blue") anchor_arrow2d(); attach("pit0") color("blue") anchor_arrow2d();
``` ```
You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor
points are based on the furthest extents of the shape, and may not be where you expect them: points are based on the furthest extents of the shape, and may not be where you expect them:
```openscad-2D ```openscad-2D
star(n=5, step=2, d=50) star(n=5, step=2, d=50)
show_anchors(custom=false); show_anchors(custom=false);
``` ```
Stars also have named anchor points for their pits, tips, and midpoints between tips: Stars also have named anchor points for their pits, tips, and midpoints between tips:
```openscad-2D ```openscad-2D
star(n=5, step=2, d=40) star(n=5, step=2, d=40)
show_anchors(std=false); show_anchors(std=false);
``` ```
@ -460,36 +460,36 @@ The `teardrop2d()` module will let you make a 2D version of the teardrop shape,
extrude it later: extrude it later:
```openscad-2D ```openscad-2D
teardrop2d(r=20); teardrop2d(r=20);
``` ```
```openscad-2D ```openscad-2D
teardrop2d(d=50); teardrop2d(d=50);
``` ```
The default overhang angle is 45 degrees, but you can adjust that with the `ang=` argument: The default overhang angle is 45 degrees, but you can adjust that with the `ang=` argument:
```openscad-2D ```openscad-2D
teardrop2d(d=50, ang=30); teardrop2d(d=50, ang=30);
``` ```
If you prefer to flatten the top of the teardrop, to encourage bridging, you can use the `cap_h=` If you prefer to flatten the top of the teardrop, to encourage bridging, you can use the `cap_h=`
argument: argument:
```openscad-2D ```openscad-2D
teardrop2d(d=50, cap_h=25); teardrop2d(d=50, cap_h=25);
``` ```
```openscad-2D ```openscad-2D
teardrop2d(d=50, ang=30, cap_h=30); teardrop2d(d=50, ang=30, cap_h=30);
``` ```
You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor
points are based on the furthest extents of the shape, and may not be where you expect them: points are based on the furthest extents of the shape, and may not be where you expect them:
```openscad-2D ```openscad-2D
teardrop2d(d=50, ang=30, cap_h=30) teardrop2d(d=50, ang=30, cap_h=30)
show_anchors(); show_anchors();
``` ```
@ -499,57 +499,57 @@ A more unusal shape that BOSL2 provides is Glued Circles. It's basically a pair
connected by what looks like a gloopy glued miniscus: connected by what looks like a gloopy glued miniscus:
```openscad-2D ```openscad-2D
glued_circles(d=30, spread=40); glued_circles(d=30, spread=40);
``` ```
The `r=`/`d=` arguments can specify the radius or diameter of the two circles: The `r=`/`d=` arguments can specify the radius or diameter of the two circles:
```openscad-2D ```openscad-2D
glued_circles(r=20, spread=45); glued_circles(r=20, spread=45);
``` ```
```openscad-2D ```openscad-2D
glued_circles(d=40, spread=45); glued_circles(d=40, spread=45);
``` ```
The `spread=` argument specifies the distance between the centers of the two circles: The `spread=` argument specifies the distance between the centers of the two circles:
```openscad-2D ```openscad-2D
glued_circles(d=30, spread=30); glued_circles(d=30, spread=30);
``` ```
```openscad-2D ```openscad-2D
glued_circles(d=30, spread=40); glued_circles(d=30, spread=40);
``` ```
The `tangent=` argument gives the angle of the tangent of the meniscus on the two circles: The `tangent=` argument gives the angle of the tangent of the meniscus on the two circles:
```openscad-2D ```openscad-2D
glued_circles(d=30, spread=30, tangent=45); glued_circles(d=30, spread=30, tangent=45);
``` ```
```openscad-2D ```openscad-2D
glued_circles(d=30, spread=30, tangent=20); glued_circles(d=30, spread=30, tangent=20);
``` ```
```openscad-2D ```openscad-2D
glued_circles(d=30, spread=30, tangent=-20); glued_circles(d=30, spread=30, tangent=-20);
``` ```
One useful thing you can do is to string a few `glued_circle()`s in a line then extrude them to make a ribbed wall: One useful thing you can do is to string a few `glued_circle()`s in a line then extrude them to make a ribbed wall:
```openscad-3D ```openscad-3D
$fn=36; s=10; $fn=36; s=10;
linear_extrude(height=50,convexity=16,center=true) linear_extrude(height=50,convexity=16,center=true)
xcopies(s*sqrt(2),n=3) xcopies(s*sqrt(2),n=3)
glued_circles(d=s, spread=s*sqrt(2), tangent=45); glued_circles(d=s, spread=s*sqrt(2), tangent=45);
``` ```
You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor
points are based on the furthest extents of the shape, and may not be where you expect them: points are based on the furthest extents of the shape, and may not be where you expect them:
```openscad-2D ```openscad-2D
glued_circles(d=40, spread=40, tangent=45) glued_circles(d=40, spread=40, tangent=45)
show_anchors(); show_anchors();
``` ```

View file

@ -12,15 +12,15 @@ that they support more features, and more ways to simply reorient them.
BOSL2 overrides the built-in `cube()` module. It still can be used as you expect from the built-in: BOSL2 overrides the built-in `cube()` module. It still can be used as you expect from the built-in:
```openscad-3D ```openscad-3D
cube(100); cube(100);
``` ```
```openscad-3D ```openscad-3D
cube(100, center=true); cube(100, center=true);
``` ```
```openscad-3D ```openscad-3D
cube([50,40,20], center=true); cube([50,40,20], center=true);
``` ```
It is also enhanced to allow you to anchor, spin, orient, and attach it. It is also enhanced to allow you to anchor, spin, orient, and attach it.
@ -30,21 +30,21 @@ except you can also anchor vertically in 3D, allowing anchoring to faces, edges,
and corners: and corners:
```openscad-3D ```openscad-3D
cube([50,40,20], anchor=BOTTOM); cube([50,40,20], anchor=BOTTOM);
``` ```
```openscad-3D ```openscad-3D
cube([50,40,20], anchor=TOP+BACK); cube([50,40,20], anchor=TOP+BACK);
``` ```
```openscad-3D ```openscad-3D
cube([50,40,20], anchor=TOP+FRONT+LEFT); cube([50,40,20], anchor=TOP+FRONT+LEFT);
``` ```
You can use `spin=` to rotate around the Z axis: You can use `spin=` to rotate around the Z axis:
```openscad-3D ```openscad-3D
cube([50,40,20], anchor=FRONT, spin=30); cube([50,40,20], anchor=FRONT, spin=30);
``` ```
3D objects also gain the ability to use an extra trick with `spin=`; 3D objects also gain the ability to use an extra trick with `spin=`;
@ -52,29 +52,29 @@ if you pass a list of `[X,Y,Z]` rotation angles to `spin=`, it will
rotate by the three given axis angles, similar to using `rotate()`: rotate by the three given axis angles, similar to using `rotate()`:
```openscad-3D ```openscad-3D
cube([50,40,20], anchor=FRONT, spin=[15,0,30]); cube([50,40,20], anchor=FRONT, spin=[15,0,30]);
``` ```
3D objects also can be given an `orient=` argument as a vector, pointing 3D objects also can be given an `orient=` argument as a vector, pointing
to where the top of the shape should be rotated towards. to where the top of the shape should be rotated towards.
```openscad-3D ```openscad-3D
cube([50,40,20], orient=UP+BACK+RIGHT); cube([50,40,20], orient=UP+BACK+RIGHT);
``` ```
If you use `anchor=`, `spin=`, and `orient=` together, the anchor is performed If you use `anchor=`, `spin=`, and `orient=` together, the anchor is performed
first, then the spin, then the orient: first, then the spin, then the orient:
```openscad-3D ```openscad-3D
cube([50,40,20], anchor=FRONT); cube([50,40,20], anchor=FRONT);
``` ```
```openscad-3D ```openscad-3D
cube([50,40,20], anchor=FRONT, spin=45); cube([50,40,20], anchor=FRONT, spin=45);
``` ```
```openscad-3D ```openscad-3D
cube([50,40,20], anchor=FRONT, spin=45, orient=UP+FWD+RIGHT); cube([50,40,20], anchor=FRONT, spin=45, orient=UP+FWD+RIGHT);
``` ```
BOSL2 provides a `cuboid()` module that expands on `cube()`, by providing BOSL2 provides a `cuboid()` module that expands on `cube()`, by providing
@ -84,13 +84,13 @@ except that `cuboid()` centers by default.
You can round the edges with the `rounding=` argument: You can round the edges with the `rounding=` argument:
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=20); cuboid([100,80,60], rounding=20);
``` ```
Similarly, you can chamfer the edges with the `chamfer=` argument: Similarly, you can chamfer the edges with the `chamfer=` argument:
```openscad-3D ```openscad-3D
cuboid([100,80,60], chamfer=10); cuboid([100,80,60], chamfer=10);
``` ```
You can round only some edges, by using the `edges=` arguments. It can be You can round only some edges, by using the `edges=` arguments. It can be
@ -98,80 +98,80 @@ given a few types of arguments. If you gave it a vector pointed at a face,
it will only round the edges surrounding that face: it will only round the edges surrounding that face:
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=20, edges=TOP); cuboid([100,80,60], rounding=20, edges=TOP);
``` ```
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=20, edges=RIGHT); cuboid([100,80,60], rounding=20, edges=RIGHT);
``` ```
If you give `edges=` a vector pointing at a corner, it will round all edges If you give `edges=` a vector pointing at a corner, it will round all edges
that meet at that corner: that meet at that corner:
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=20, edges=RIGHT+FRONT+TOP); cuboid([100,80,60], rounding=20, edges=RIGHT+FRONT+TOP);
``` ```
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=20, edges=LEFT+FRONT+TOP); cuboid([100,80,60], rounding=20, edges=LEFT+FRONT+TOP);
``` ```
If you give `edges=` a vector pointing at an edge, it will round only that edge: If you give `edges=` a vector pointing at an edge, it will round only that edge:
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=10, edges=FRONT+TOP); cuboid([100,80,60], rounding=10, edges=FRONT+TOP);
``` ```
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=10, edges=RIGHT+FRONT); cuboid([100,80,60], rounding=10, edges=RIGHT+FRONT);
``` ```
If you give the string "X", "Y", or "Z", then all edges aligned with the specified If you give the string "X", "Y", or "Z", then all edges aligned with the specified
axis will be rounded: axis will be rounded:
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=10, edges="X"); cuboid([100,80,60], rounding=10, edges="X");
``` ```
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=10, edges="Y"); cuboid([100,80,60], rounding=10, edges="Y");
``` ```
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=10, edges="Z"); cuboid([100,80,60], rounding=10, edges="Z");
``` ```
If you give a list of edge specs, then all edges referenced in the list will If you give a list of edge specs, then all edges referenced in the list will
be rounded: be rounded:
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=10, edges=[TOP,"Z",BOTTOM+RIGHT]); cuboid([100,80,60], rounding=10, edges=[TOP,"Z",BOTTOM+RIGHT]);
``` ```
The default value for `edges=` is `EDGES_ALL`, which is all edges. You can also The default value for `edges=` is `EDGES_ALL`, which is all edges. You can also
give an `except_edges=` argument that specifies edges to NOT round: give an `except_edges=` argument that specifies edges to NOT round:
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=10, except_edges=BOTTOM+RIGHT); cuboid([100,80,60], rounding=10, except_edges=BOTTOM+RIGHT);
``` ```
You can give the `except_edges=` argument any type of argument that you can You can give the `except_edges=` argument any type of argument that you can
give to `edges=`: give to `edges=`:
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=10, except_edges=[BOTTOM,"Z",TOP+RIGHT]); cuboid([100,80,60], rounding=10, except_edges=[BOTTOM,"Z",TOP+RIGHT]);
``` ```
You can give both `edges=` and `except_edges=`, to simplify edge specs: You can give both `edges=` and `except_edges=`, to simplify edge specs:
```openscad-3D ```openscad-3D
cuboid([100,80,60], rounding=10, edges=[TOP,FRONT], except_edges=TOP+FRONT); cuboid([100,80,60], rounding=10, edges=[TOP,FRONT], except_edges=TOP+FRONT);
``` ```
You can specify what edges to chamfer similarly: You can specify what edges to chamfer similarly:
```openscad-3D ```openscad-3D
cuboid([100,80,60], chamfer=10, edges=[TOP,FRONT], except_edges=TOP+FRONT); cuboid([100,80,60], chamfer=10, edges=[TOP,FRONT], except_edges=TOP+FRONT);
``` ```
@ -180,37 +180,37 @@ BOSL2 overrides the built-in `cylinder()` module. It still can be used as you
expect from the built-in: expect from the built-in:
```openscad-3D ```openscad-3D
cylinder(r=50,h=50); cylinder(r=50,h=50);
``` ```
```openscad-3D ```openscad-3D
cylinder(r=50,h=50,center=true); cylinder(r=50,h=50,center=true);
``` ```
```openscad-3D ```openscad-3D
cylinder(d=100,h=50,center=true); cylinder(d=100,h=50,center=true);
``` ```
```openscad-3D ```openscad-3D
cylinder(d1=100,d2=80,h=50,center=true); cylinder(d1=100,d2=80,h=50,center=true);
``` ```
You can also anchor, spin, orient, and attach like the `cuboid()` module: You can also anchor, spin, orient, and attach like the `cuboid()` module:
```openscad-3D ```openscad-3D
cylinder(r=50, h=50, anchor=TOP+FRONT); cylinder(r=50, h=50, anchor=TOP+FRONT);
``` ```
```openscad-3D ```openscad-3D
cylinder(r=50, h=50, anchor=BOTTOM+LEFT); cylinder(r=50, h=50, anchor=BOTTOM+LEFT);
``` ```
```openscad-3D ```openscad-3D
cylinder(r=50, h=50, anchor=BOTTOM+LEFT, spin=30); cylinder(r=50, h=50, anchor=BOTTOM+LEFT, spin=30);
``` ```
```openscad-3D ```openscad-3D
cylinder(r=50, h=50, anchor=BOTTOM, orient=UP+BACK+RIGHT); cylinder(r=50, h=50, anchor=BOTTOM, orient=UP+BACK+RIGHT);
``` ```
@ -219,55 +219,55 @@ rounding and chamfering of edges. You can use it similarly to `cylinder()`,
except that `cyl()` centers the cylinder by default. except that `cyl()` centers the cylinder by default.
```openscad-3D ```openscad-3D
cyl(r=60, l=100); cyl(r=60, l=100);
``` ```
```openscad-3D ```openscad-3D
cyl(d=100, l=100); cyl(d=100, l=100);
``` ```
```openscad-3D ```openscad-3D
cyl(d=100, l=100, anchor=TOP); cyl(d=100, l=100, anchor=TOP);
``` ```
You can round the edges with the `rounding=` argument: You can round the edges with the `rounding=` argument:
```openscad-3D ```openscad-3D
cyl(d=100, l=100, rounding=20); cyl(d=100, l=100, rounding=20);
``` ```
Similarly, you can chamfer the edges with the `chamfer=` argument: Similarly, you can chamfer the edges with the `chamfer=` argument:
```openscad-3D ```openscad-3D
cyl(d=100, l=100, chamfer=10); cyl(d=100, l=100, chamfer=10);
``` ```
You can specify rounding and chamfering for each end individually: You can specify rounding and chamfering for each end individually:
```openscad-3D ```openscad-3D
cyl(d=100, l=100, rounding1=20); cyl(d=100, l=100, rounding1=20);
``` ```
```openscad-3D ```openscad-3D
cyl(d=100, l=100, rounding2=20); cyl(d=100, l=100, rounding2=20);
``` ```
```openscad-3D ```openscad-3D
cyl(d=100, l=100, chamfer1=10); cyl(d=100, l=100, chamfer1=10);
``` ```
```openscad-3D ```openscad-3D
cyl(d=100, l=100, chamfer2=10); cyl(d=100, l=100, chamfer2=10);
``` ```
You can even mix and match rounding and chamfering: You can even mix and match rounding and chamfering:
```openscad-3D ```openscad-3D
cyl(d=100, l=100, rounding1=20, chamfer2=10); cyl(d=100, l=100, rounding1=20, chamfer2=10);
``` ```
```openscad-3D ```openscad-3D
cyl(d=100, l=100, rounding2=20, chamfer1=10); cyl(d=100, l=100, rounding2=20, chamfer1=10);
``` ```
@ -276,26 +276,26 @@ BOSL2 overrides the built-in `sphere()` module. It still can be used as you
expect from the built-in: expect from the built-in:
```openscad-3D ```openscad-3D
sphere(r=50); sphere(r=50);
``` ```
```openscad-3D ```openscad-3D
sphere(d=100); sphere(d=100);
``` ```
You can anchor, spin, and orient `sphere()`s, much like you can with `cylinder()` You can anchor, spin, and orient `sphere()`s, much like you can with `cylinder()`
and `cube()`: and `cube()`:
```openscad-3D ```openscad-3D
sphere(d=100, anchor=FRONT); sphere(d=100, anchor=FRONT);
``` ```
```openscad-3D ```openscad-3D
sphere(d=100, anchor=FRONT, spin=30); sphere(d=100, anchor=FRONT, spin=30);
``` ```
```openscad-3D ```openscad-3D
sphere(d=100, anchor=BOTTOM, orient=RIGHT+TOP); sphere(d=100, anchor=BOTTOM, orient=RIGHT+TOP);
``` ```
BOSL2 also provides `spheroid()`, which enhances `sphere()` with a few features BOSL2 also provides `spheroid()`, which enhances `sphere()` with a few features
@ -305,27 +305,27 @@ You can use the `circum=true` argument to force the sphere to circumscribe the
ideal sphere, as opposed to the default inscribing: ideal sphere, as opposed to the default inscribing:
```openscad-3D ```openscad-3D
spheroid(d=100, circum=true); spheroid(d=100, circum=true);
``` ```
The `style=` argument can choose the way that the sphere will be constructed: The `style=` argument can choose the way that the sphere will be constructed:
The "orig" style matches the `sphere()` built-in's construction. The "orig" style matches the `sphere()` built-in's construction.
```openscad-3D ```openscad-3D
spheroid(d=100, style="orig", $fn=20); spheroid(d=100, style="orig", $fn=20);
``` ```
The "aligned" style will ensure that there is a vertex at each axis extrema, The "aligned" style will ensure that there is a vertex at each axis extrema,
so long as `$fn` is a multiple of 4. so long as `$fn` is a multiple of 4.
```openscad-3D ```openscad-3D
spheroid(d=100, style="aligned", $fn=20); spheroid(d=100, style="aligned", $fn=20);
``` ```
The "stagger" style will stagger the triangulation of the vertical rows: The "stagger" style will stagger the triangulation of the vertical rows:
```openscad-3D ```openscad-3D
spheroid(d=100, style="stagger", $fn=20); spheroid(d=100, style="stagger", $fn=20);
``` ```
The "icosa" style will make for roughly equal-sized triangles for the entire The "icosa" style will make for roughly equal-sized triangles for the entire
@ -333,7 +333,7 @@ sphere surface, based on subdividing an icosahedron. This style will round the
effective `$fn` to a multiple of 5 when constructing the spheroid: effective `$fn` to a multiple of 5 when constructing the spheroid:
```openscad-3D ```openscad-3D
spheroid(d=100, style="icosa", $fn=20); spheroid(d=100, style="icosa", $fn=20);
``` ```
The "octa" style will also make for roughly equal-sized triangles for the entire The "octa" style will also make for roughly equal-sized triangles for the entire
@ -342,6 +342,6 @@ guarantees vertices at the axis extrema. This style will round the effective `$
to a multiple of 4 when constructing the spheroid: to a multiple of 4 when constructing the spheroid:
```openscad-3D ```openscad-3D
spheroid(d=100, style="octa", $fn=20); spheroid(d=100, style="octa", $fn=20);
``` ```

View file

@ -14,124 +14,124 @@ just what axis is being moved along, and in which direction. It's also a bit ve
frequently used command. For these reasons, BOSL2 provides you with shortcuts for each direction. frequently used command. For these reasons, BOSL2 provides you with shortcuts for each direction.
These shortcuts are `up()`, `down()`, `fwd()`, `back()`, `left()`, and `right()`: These shortcuts are `up()`, `down()`, `fwd()`, `back()`, `left()`, and `right()`:
```openscad ```openscad
#sphere(d=20); #sphere(d=20);
up(30) sphere(d=20); up(30) sphere(d=20);
``` ```
```openscad ```openscad
#sphere(d=20); #sphere(d=20);
down(30) sphere(d=20); down(30) sphere(d=20);
``` ```
```openscad ```openscad
#sphere(d=20); #sphere(d=20);
fwd(30) sphere(d=20); fwd(30) sphere(d=20);
``` ```
```openscad ```openscad
#sphere(d=20); #sphere(d=20);
back(30) sphere(d=20); back(30) sphere(d=20);
``` ```
```openscad ```openscad
#sphere(d=20); #sphere(d=20);
left(30) sphere(d=20); left(30) sphere(d=20);
``` ```
```openscad ```openscad
#sphere(d=20); #sphere(d=20);
right(30) sphere(d=20); right(30) sphere(d=20);
``` ```
There is also a more generic `move()` command that can work just like `translate()`, or you can There is also a more generic `move()` command that can work just like `translate()`, or you can
specify the motion on each axis more clearly: specify the motion on each axis more clearly:
```openscad ```openscad
#sphere(d=20); #sphere(d=20);
move([30,-10]) sphere(d=20); move([30,-10]) sphere(d=20);
``` ```
```openscad ```openscad
#sphere(d=20); #sphere(d=20);
move(x=30,y=10) sphere(d=20); move(x=30,y=10) sphere(d=20);
``` ```
## Scaling ## Scaling
The `scale()` command is also fairly simple: The `scale()` command is also fairly simple:
```openscad ```openscad
scale(2) cube(10, center=true); scale(2) cube(10, center=true);
``` ```
```openscad ```openscad
scale([1,2,3]) cube(10, center=true); scale([1,2,3]) cube(10, center=true);
``` ```
If you want to only change the scaling on one axis, though, BOSL2 provides clearer If you want to only change the scaling on one axis, though, BOSL2 provides clearer
commands to do just that; `xscale()`, `yscale()`, and `zscale()`: commands to do just that; `xscale()`, `yscale()`, and `zscale()`:
```openscad ```openscad
xscale(2) cube(10, center=true); xscale(2) cube(10, center=true);
``` ```
```openscad ```openscad
yscale(2) cube(10, center=true); yscale(2) cube(10, center=true);
``` ```
```openscad ```openscad
zscale(2) cube(10, center=true); zscale(2) cube(10, center=true);
``` ```
## Rotation ## Rotation
The `rotate()` command is fairly straightforward: The `rotate()` command is fairly straightforward:
```openscad ```openscad
rotate([0,30,0]) cube(20, center=true); rotate([0,30,0]) cube(20, center=true);
``` ```
It is also a bit verbose, and can, at a glance, be difficult to tell just how it is rotating. It is also a bit verbose, and can, at a glance, be difficult to tell just how it is rotating.
BOSL2 provides shortcuts for rotating around each axis, for clarity; `xrot()`, `yrot()`, and `zrot()`: BOSL2 provides shortcuts for rotating around each axis, for clarity; `xrot()`, `yrot()`, and `zrot()`:
```openscad ```openscad
xrot(30) cube(20, center=true); xrot(30) cube(20, center=true);
``` ```
```openscad ```openscad
yrot(30) cube(20, center=true); yrot(30) cube(20, center=true);
``` ```
```openscad ```openscad
zrot(30) cube(20, center=true); zrot(30) cube(20, center=true);
``` ```
The `rot()` command is a more generic rotation command, and shorter to type than `rotate()`: The `rot()` command is a more generic rotation command, and shorter to type than `rotate()`:
```openscad ```openscad
rot([0,30,15]) cube(20, center=true); rot([0,30,15]) cube(20, center=true);
``` ```
All of the rotation shortcuts can take a `cp=` argument, that lets you specify a All of the rotation shortcuts can take a `cp=` argument, that lets you specify a
centerpoint to rotate around: centerpoint to rotate around:
```openscad ```openscad
cp = [0,0,40]; cp = [0,0,40];
color("blue") move(cp) sphere(d=3); color("blue") move(cp) sphere(d=3);
#cube(20, center=true); #cube(20, center=true);
xrot(45, cp=cp) cube(20, center=true); xrot(45, cp=cp) cube(20, center=true);
``` ```
```openscad ```openscad
cp = [0,0,40]; cp = [0,0,40];
color("blue") move(cp) sphere(d=3); color("blue") move(cp) sphere(d=3);
#cube(20, center=true); #cube(20, center=true);
yrot(45, cp=cp) cube(20, center=true); yrot(45, cp=cp) cube(20, center=true);
``` ```
```openscad ```openscad
cp = [0,40,0]; cp = [0,40,0];
color("blue") move(cp) sphere(d=3); color("blue") move(cp) sphere(d=3);
#cube(20, center=true); #cube(20, center=true);
zrot(45, cp=cp) cube(20, center=true); zrot(45, cp=cp) cube(20, center=true);
``` ```
You can also do a new trick with it. You can rotate from pointing in one direction, towards another. You can also do a new trick with it. You can rotate from pointing in one direction, towards another.
You give these directions using vectors: You give these directions using vectors:
```openscad ```openscad
#cylinder(d=10, h=50); #cylinder(d=10, h=50);
rot(from=[0,0,1], to=[1,0,1]) cylinder(d=10, h=50); rot(from=[0,0,1], to=[1,0,1]) cylinder(d=10, h=50);
``` ```
There are several direction vectors constants and aliases you can use for clarity: There are several direction vectors constants and aliases you can use for clarity:
@ -150,51 +150,51 @@ Constant | Value | Direction
This lets you rewrite the above vector rotation more clearly as: This lets you rewrite the above vector rotation more clearly as:
```openscad ```openscad
#cylinder(d=10, h=50); #cylinder(d=10, h=50);
rot(from=UP, to=UP+RIGHT) cylinder(d=10, h=50); rot(from=UP, to=UP+RIGHT) cylinder(d=10, h=50);
``` ```
## Mirroring ## Mirroring
The standard `mirror()` command works like this: The standard `mirror()` command works like this:
```openscad ```openscad
#yrot(60) cylinder(h=50, d1=20, d2=10); #yrot(60) cylinder(h=50, d1=20, d2=10);
mirror([1,0,0]) yrot(60) cylinder(h=50, d1=20, d2=10); mirror([1,0,0]) yrot(60) cylinder(h=50, d1=20, d2=10);
``` ```
BOSL2 provides shortcuts for mirroring across the standard axes; `xflip()`, `yflip()`, and `zflip()`: BOSL2 provides shortcuts for mirroring across the standard axes; `xflip()`, `yflip()`, and `zflip()`:
```openscad ```openscad
#yrot(60) cylinder(h=50, d1=20, d2=10); #yrot(60) cylinder(h=50, d1=20, d2=10);
xflip() yrot(60) cylinder(h=50, d1=20, d2=10); xflip() yrot(60) cylinder(h=50, d1=20, d2=10);
``` ```
```openscad ```openscad
#xrot(60) cylinder(h=50, d1=20, d2=10); #xrot(60) cylinder(h=50, d1=20, d2=10);
yflip() xrot(60) cylinder(h=50, d1=20, d2=10); yflip() xrot(60) cylinder(h=50, d1=20, d2=10);
``` ```
```openscad ```openscad
#cylinder(h=50, d1=20, d2=10); #cylinder(h=50, d1=20, d2=10);
zflip() cylinder(h=50, d1=20, d2=10); zflip() cylinder(h=50, d1=20, d2=10);
``` ```
All of the flip commands can offset where the mirroring is performed: All of the flip commands can offset where the mirroring is performed:
```openscad ```openscad
#zrot(30) cube(20, center=true); #zrot(30) cube(20, center=true);
xflip(x=-20) zrot(30) cube(20, center=true); xflip(x=-20) zrot(30) cube(20, center=true);
color("blue",0.25) left(20) cube([0.1,50,50], center=true); color("blue",0.25) left(20) cube([0.1,50,50], center=true);
``` ```
```openscad ```openscad
#zrot(30) cube(20, center=true); #zrot(30) cube(20, center=true);
yflip(y=20) zrot(30) cube(20, center=true); yflip(y=20) zrot(30) cube(20, center=true);
color("blue",0.25) back(20) cube([40,0.1,40], center=true); color("blue",0.25) back(20) cube([40,0.1,40], center=true);
``` ```
```openscad ```openscad
#xrot(30) cube(20, center=true); #xrot(30) cube(20, center=true);
zflip(z=-20) xrot(30) cube(20, center=true); zflip(z=-20) xrot(30) cube(20, center=true);
color("blue",0.25) down(20) cube([40,40,0.1], center=true); color("blue",0.25) down(20) cube([40,40,0.1], center=true);
``` ```