mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-01 09:49:45 +00:00
Tutorials work.. Shapes2d and Paths.
This commit is contained in:
parent
b054edb5fb
commit
eb12f5f9cb
4 changed files with 1073 additions and 227 deletions
504
tutorials/Paths.md
Normal file
504
tutorials/Paths.md
Normal file
|
@ -0,0 +1,504 @@
|
||||||
|
# Paths, Polygons and Regions Tutorial
|
||||||
|
|
||||||
|
## Paths
|
||||||
|
A number of advanced features in BOSL2 rely on paths, which are just ordered lists of points.
|
||||||
|
|
||||||
|
First-off, some terminology:
|
||||||
|
- A 2D point is a vectors of X and Y axis position values ie: `[3,4]` or `[7,-3]`.
|
||||||
|
- A 3D point is a vectors of X, Y and Z axis position values ie: `[3,4,2]` or `[-7,5,3]`.
|
||||||
|
- A 2D path is simply a list of two or more 2D points. ie: `[[5,7], [1,-5], [-5,6]]`
|
||||||
|
- A 3D path is simply a list of two or more 3D points. ie: `[[5,7,-1], [1,-5,3], [-5,6,1]]`
|
||||||
|
- A polygon is a 2D (or planar 3D) path where the last point is assumed to connect to the first point.
|
||||||
|
- A region is a list of 2D polygons, where each polygon is XORed against all the others. ie: if one polygon is inside another, it makes a hole in the first polygon.
|
||||||
|
|
||||||
|
### Stroke
|
||||||
|
A path can be hard to visualize, since it's just a bunch of numbers in the source code.
|
||||||
|
One way to see the path is to pass it to `polygon()`:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
polygon(path);
|
||||||
|
```
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
stroke(path);
|
||||||
|
```
|
||||||
|
|
||||||
|
You can vary the width of the drawn path with the `width=` argument:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
stroke(path, width=3);
|
||||||
|
```
|
||||||
|
|
||||||
|
You can vary the line length along the path by giving a list of widths, one per point:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
stroke(path, closed=true);
|
||||||
|
```
|
||||||
|
|
||||||
|
The ends of the drawn path are normally capped with a "round" endcap, but there are other options:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
stroke(path, endcaps="round");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
stroke(path, endcaps="butt");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
stroke(path, endcaps="line");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
stroke(path, endcaps="tail");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
stroke(path, endcaps="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
For more standard supported endcap options, see the docs for [`stroke()`](shapes2d.scad#stroke).
|
||||||
|
|
||||||
|
The start and ending endcaps can be specified individually or separately, using `endcap1=` and `endcap2=`:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
stroke(path, endcap1="butt", endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||||
|
widths = [1, 1.25, 1.5, 1.75, 2];
|
||||||
|
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
|
||||||
|
passing a path to the `endcaps=`, `endcap1=`, or `endcap2=` arguments. You may also need to give
|
||||||
|
`trim=` to tell it how far back to trim the main line, so it renders nicely. The values in the
|
||||||
|
endcap polygon, and in the `trim=` argument are relative to the line width. A value of 1 is one
|
||||||
|
line width size.
|
||||||
|
|
||||||
|
Untrimmed:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
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]];
|
||||||
|
stroke(path, endcaps=dblarrow);
|
||||||
|
```
|
||||||
|
|
||||||
|
Trimmed:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
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]];
|
||||||
|
stroke(path, trim=3.5, endcaps=dblarrow);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = square(40, center=true);
|
||||||
|
stroke(path, closed=true, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = rect([40,30], rounding=5, center=true);
|
||||||
|
stroke(path, closed=true, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = trapezoid(w1=40, w2=20, h=30);
|
||||||
|
stroke(path, closed=true, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = circle(d=50);
|
||||||
|
stroke(path, closed=true, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = oval(d=[50,30]);
|
||||||
|
stroke(path, closed=true, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = pentagon(d=50);
|
||||||
|
stroke(path, closed=true, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = star(n=5, step=2, d=50);
|
||||||
|
stroke(path, closed=true, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
### Arcs
|
||||||
|
Often, when you are constructing a path, you will want to add an arc. The `arc()` command lets you do that:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = arc(r=30, angle=120);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = arc(d=60, angle=120);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
If you give the `N=` argument, you can control exactly how many points the arc is divided into:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = arc(N=5, r=30, angle=120);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
With the `start=` argument, you can start the arc somewhere other than the X+ axis:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = arc(start=45, r=30, angle=120);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
Alternatively, you can give starting and ending angles in a list in the `angle=` argument:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = arc(angle=[120,45], r=30);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
The `cp=` argument lets you center the arc somewhere other than the origin:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = arc(cp=[10,0], r=30, angle=120);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
The arc can also be given by three points on the arc:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
pts = [[-15,10],[0,20],[35,-5]];
|
||||||
|
path = arc(points=pts);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Turtle Graphics
|
||||||
|
Another way you can create a path is using the `turtle()` command. It implements a simple path
|
||||||
|
description language that is similar to LOGO Turtle Graphics. The concept is that you have a virtial
|
||||||
|
turtle or cursor walking a path. It can "move" forward or backward, or turn "left" or "right" in
|
||||||
|
place:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = turtle([
|
||||||
|
"move", 10,
|
||||||
|
"left", 90,
|
||||||
|
"move", 20,
|
||||||
|
"left", 135,
|
||||||
|
"move", 10*sqrt(2),
|
||||||
|
"right", 90,
|
||||||
|
"move", 10*sqrt(2),
|
||||||
|
"left", 135,
|
||||||
|
"move", 20
|
||||||
|
]);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = turtle([
|
||||||
|
"angle",360/6,
|
||||||
|
"length",10,
|
||||||
|
"move","turn",
|
||||||
|
"move","turn",
|
||||||
|
"move","turn",
|
||||||
|
"move","turn",
|
||||||
|
"move"
|
||||||
|
]);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use "scale" to relatively scale up the default motion length:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = turtle([
|
||||||
|
"angle",360/6,
|
||||||
|
"length",10,
|
||||||
|
"move","turn",
|
||||||
|
"move","turn",
|
||||||
|
"scale",2,
|
||||||
|
"move","turn",
|
||||||
|
"move","turn",
|
||||||
|
"scale",0.5,
|
||||||
|
"move"
|
||||||
|
]);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
Sequences of commands can be repeated using the "repeat" command:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path=turtle([
|
||||||
|
"angle",360/5,
|
||||||
|
"length",10,
|
||||||
|
"repeat",5,["move","turn"]
|
||||||
|
]);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
More complicated commands also exist, including those that form arcs:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = turtle([
|
||||||
|
"move", 10,
|
||||||
|
"left", 90,
|
||||||
|
"move", 20,
|
||||||
|
"arcleft", 10, 180,
|
||||||
|
"move", 20
|
||||||
|
]);
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
A comprehensive list of supported turtle commands can be found in the docs for [`turtle()`](shapes2d.scad#turtle).
|
||||||
|
|
||||||
|
### Transforming Paths and Polygons
|
||||||
|
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
|
||||||
|
path = move([-15,-30], p=square(50,center=true));
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = fwd(30, p=square(50,center=true));
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = left(30, p=square(50,center=true));
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
To scale a path, you can just pass it to the `scale()` (or [xyz]scale) function in the `p=` argument:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = scale([1.5,0.75], p=square(50,center=true));
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = xscale(1.5, p=square(50,center=true));
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = yscale(1.5, p=square(50,center=true));
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
To rotate a path, just can pass it to the `rot()` (or [xyz]rot) function in the `p=` argument:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = rot(30, p=square(50,center=true));
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = zrot(30, p=square(50,center=true));
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
To mirror a path, just can pass it to the `mirror()` (or [xyz]flip) function in the `p=` argument:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = mirror([1,1], p=trapezoid(w1=10, w2=0, h=5));
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = xflip(p=trapezoid(w1=10, w2=0, h=5));
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
path = yflip(p=trapezoid(w1=10, w2=0, h=5));
|
||||||
|
stroke(path, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
You can get raw transformation matrices for various transformations by calling them like a function without a `p=` argument:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
mat = move([5,10]);
|
||||||
|
multmatrix(mat) square(50,center=true);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
mat = scale([1.5,0.75]);
|
||||||
|
multmatrix(mat) square(50,center=true);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
mat = rot(30);
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
mat = move([5,10]) * rot(30, planar=true) * scale([1.5,0.75]);
|
||||||
|
multmatrix(mat) square(50,center=true);
|
||||||
|
```
|
||||||
|
|
||||||
|
To apply a compound transformation matrix to a path, you can use the `apply()` function:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
mat = move([5,10]) * rot(30, planar=true) * scale([1.5,0.75]);
|
||||||
|
path = square(50,center=true);
|
||||||
|
tpath = apply(mat, path);
|
||||||
|
stroke(tpath, endcap2="arrow2");
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Regions
|
||||||
|
A polygon is good to denote a single closed 2D shape with no holes in it. For more complex 2D
|
||||||
|
shapes, you will need to use regions. A region is a list of 2D polygons, where each polygon is
|
||||||
|
XORed against all the others. You can display a region using the `region()` module.
|
||||||
|
|
||||||
|
If you have a region with one polygon fully inside another, it makes a hole:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rgn = [square(50,center=true), circle(d=30)];
|
||||||
|
region(rgn);
|
||||||
|
```
|
||||||
|
|
||||||
|
If you have a region with multiple polygons that are not contained by any others, they make multiple discontiguous shapes:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rgn = [
|
||||||
|
move([-30, 20], p=square(20,center=true)),
|
||||||
|
move([ 0,-20], p=trapezoid(w1=20, w2=10, h=20)),
|
||||||
|
move([ 30, 20], p=square(20,center=true)),
|
||||||
|
];
|
||||||
|
region(rgn);
|
||||||
|
```
|
||||||
|
|
||||||
|
Region polygons can be nested abitrarily deep, in multiple discontiguous shapes:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rgn = [
|
||||||
|
for (d=[50:-10:10]) left(30, p=circle(d=d)),
|
||||||
|
for (d=[50:-10:10]) right(30, p=circle(d=d))
|
||||||
|
];
|
||||||
|
region(rgn);
|
||||||
|
```
|
||||||
|
|
||||||
|
A region with crossing polygons is somewhat poorly formed, but the intersection(s) of the polygons become holes:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rgn = [
|
||||||
|
left(15, p=circle(d=50)),
|
||||||
|
right(15, p=circle(d=50))
|
||||||
|
];
|
||||||
|
region(rgn);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Boolean Region Geometry
|
||||||
|
Similarly to how OpenSCAD can perform operations like union/difference/intersection/offset on shape geometry,
|
||||||
|
the BOSL2 library lets you perform those same operations on regions:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
|
||||||
|
rgn2 = [square([60,12], center=true)];
|
||||||
|
rgn = union(rgn1, rgn2);
|
||||||
|
region(rgn);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
|
||||||
|
rgn2 = [square([60,12], center=true)];
|
||||||
|
rgn = difference(rgn1, rgn2);
|
||||||
|
region(rgn);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
|
||||||
|
rgn2 = [square([60,12], center=true)];
|
||||||
|
rgn = exclusive_or(rgn1, rgn2);
|
||||||
|
region(rgn);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
|
||||||
|
rgn2 = [square([60,12], center=true)];
|
||||||
|
rgn = intersection(rgn1, rgn2);
|
||||||
|
region(rgn);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
orig_rgn = [star(n=5, step=2, d=50)];
|
||||||
|
rgn = offset(orig_rgn, r=-3, closed=true);
|
||||||
|
color("blue") region(orig_rgn);
|
||||||
|
region(rgn);
|
||||||
|
```
|
||||||
|
|
||||||
|
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()`:
|
||||||
|
|
||||||
|
```openscad-3D
|
||||||
|
rgn = [
|
||||||
|
circle(d=100),
|
||||||
|
star(n=5,step=2,d=100,spin=90)
|
||||||
|
];
|
||||||
|
difference() {
|
||||||
|
cyl(h=5, d=120);
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-3D
|
||||||
|
$fa=1; $fs=1;
|
||||||
|
rgn = [ for (d=[50:-10:10]) circle(d=d) ];
|
||||||
|
tforms = [
|
||||||
|
for (a=[90:-5:0]) xrot(a, cp=[0,-70]),
|
||||||
|
for (a=[0:5:90]) xrot(a, cp=[0,70]),
|
||||||
|
move([0,150,-70]) * xrot(90),
|
||||||
|
];
|
||||||
|
sweep(rgn, tforms, closed=false, caps=true);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
553
tutorials/Shapes2d.md
Normal file
553
tutorials/Shapes2d.md
Normal file
|
@ -0,0 +1,553 @@
|
||||||
|
# 2D Shapes Tutorial
|
||||||
|
|
||||||
|
## Primitives
|
||||||
|
There are two built-in 2D primitive shapes that OpenSCAD provides: `square()`, and `circle()`.
|
||||||
|
The BOSL2 library provides alternative to these shapes so that they support more features,
|
||||||
|
and more ways to simply reorient them.
|
||||||
|
|
||||||
|
|
||||||
|
### 2D Squares
|
||||||
|
You can still use the built-in `square()` in the familiar ways that OpenSCAD provides:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
square(100, center=false);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
square(100, center=true);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
square([60,40], center=true);
|
||||||
|
```
|
||||||
|
|
||||||
|
The BOSL2 library provides an enhanced equivalent to `square()` called `rect()`.
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], center=true, rounding=10);
|
||||||
|
```
|
||||||
|
|
||||||
|
Or chamfer them:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], center=true, chamfer=10);
|
||||||
|
```
|
||||||
|
|
||||||
|
You can even specify *which* corners get rounded or chamfered. If you pass a
|
||||||
|
list of four size numbers to the `rounding=` or `chamfer=` arguments, it will
|
||||||
|
give each corner its own size. In order, it goes from the back-right (quadrant I)
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2DImgOnly
|
||||||
|
module text3d(text) color("black") text(
|
||||||
|
text=text, font="Times", size=10,
|
||||||
|
halign="center", valign="center"
|
||||||
|
);
|
||||||
|
translate([ 50, 50]) text3d("I");
|
||||||
|
translate([-50, 50]) text3d("II");
|
||||||
|
translate([-50,-50]) text3d("III");
|
||||||
|
translate([ 50,-50]) text3d("IV");
|
||||||
|
rect([90,80], center=true);
|
||||||
|
```
|
||||||
|
|
||||||
|
If a size is given as `0`, then there is no rounding and/or chamfering for
|
||||||
|
that quadrant's corner:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], center=true, rounding=[0,5,10,15]);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], center=true, chamfer=[0,5,10,15]);
|
||||||
|
```
|
||||||
|
|
||||||
|
You can give both `rounding=` and `chamfer=` arguments to mix rounding and
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], center=true, rounding=[5,0,10,0], chamfer=[0,5,0,15]);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Anchors and Spin
|
||||||
|
Another way that `rect()` is enhanced over `square()`, is that you can anchor,
|
||||||
|
spin and attach it.
|
||||||
|
|
||||||
|
The `anchor=` argument is an alternative to `center=`, which allows more
|
||||||
|
alignment options. It takes a vector as a value, pointing roughly towards
|
||||||
|
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]`:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], anchor=[0,1]);
|
||||||
|
```
|
||||||
|
|
||||||
|
To align the front right corner to the origin:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], anchor=[1,-1]);
|
||||||
|
```
|
||||||
|
|
||||||
|
To center:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], anchor=[0,0]);
|
||||||
|
```
|
||||||
|
|
||||||
|
To make it clearer when giving vectors, there are several standard vector
|
||||||
|
constants defined:
|
||||||
|
|
||||||
|
Constant | Direction | Value
|
||||||
|
-------- | --------- | -----------
|
||||||
|
`LEFT` | X- | `[-1, 0, 0]`
|
||||||
|
`RIGHT` | X+ | `[ 1, 0, 0]`
|
||||||
|
`FRONT`/`FORWARD`/`FWD` | Y- | `[ 0,-1, 0]`
|
||||||
|
`BACK` | Y+ | `[ 0, 1, 0]`
|
||||||
|
`BOTTOM`/`BOT`/`BTM`/`DOWN` | Z- | `[ 0, 0,-1]` (3D only.)
|
||||||
|
`TOP`/`UP` | Z+ | `[ 0, 0, 1]` (3D only.)
|
||||||
|
`CENTER`/`CTR` | Centered | `[ 0, 0, 0]`
|
||||||
|
|
||||||
|
Note that even though these are 3D vectors, you can use most of them,
|
||||||
|
(except `UP`/`DOWN`, of course) for anchors in 2D shapes:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], anchor=BACK);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], anchor=CENTER);
|
||||||
|
```
|
||||||
|
|
||||||
|
You can add vectors together to point to corners:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], anchor=FRONT+RIGHT);
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, the `spin` argument can rotate the shape by a given number of degrees
|
||||||
|
clockwise:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], anchor=CENTER, spin=30);
|
||||||
|
```
|
||||||
|
|
||||||
|
Anchoring or centering is performed before the spin:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40], anchor=BACK, spin=30);
|
||||||
|
```
|
||||||
|
|
||||||
|
Anchor points double as attachment points, so that you can attach other shapes:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
rect([60,40],center=true)
|
||||||
|
show_anchors();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2D Circles and Ovals
|
||||||
|
The built-in `circle()` primitive can be used as expected:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
circle(r=50);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
circle(d=100);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
circle(d=100, $fn=8);
|
||||||
|
```
|
||||||
|
|
||||||
|
The BOSL2 library also provides an enhanced equivalent of `circle()` called `oval()`.
|
||||||
|
You can use it in the same way you use `circle()`, but it also provides extended
|
||||||
|
functionality. For example, it allows more control over its size and orientation.
|
||||||
|
|
||||||
|
Since a circle in OpenSCAD can only be approximated by a regular polygon with
|
||||||
|
a number of straight sides, this can lead to size and shape inaccuracies.
|
||||||
|
To counter this, the `realign=` and `circum=` arguments are also provided.
|
||||||
|
|
||||||
|
The `realign=` argument, if set `true`, rotates the `oval()` by half the angle
|
||||||
|
between the sides:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
oval(d=100, $fn=8, realign=true);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `circum=` argument, if true, makes it so that the polygon forming the
|
||||||
|
`oval()` circumscribes the ideal circle instead of inscribing it.
|
||||||
|
|
||||||
|
Inscribing the ideal circle:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
difference() {
|
||||||
|
circle(d=100, $fn=360);
|
||||||
|
oval(d=100, $fn=8);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Circumscribing the ideal circle:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
difference() {
|
||||||
|
oval(d=100, $fn=8, circum=true);
|
||||||
|
circle(d=100, $fn=360);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `oval()` module, as its name suggests, can be given separate X and Y radii
|
||||||
|
or diameters. To do this, just give `r=` or `d=` with a list of two radii or
|
||||||
|
diameters:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
oval(r=[30,20]);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
oval(d=[60,40]);
|
||||||
|
```
|
||||||
|
|
||||||
|
Another way that `oval()` is enhanced over `circle()`, is that you can anchor,
|
||||||
|
spin and attach it.
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
oval(r=50, anchor=BACK);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
oval(r=50, anchor=FRONT+RIGHT);
|
||||||
|
```
|
||||||
|
|
||||||
|
Using spin on a circle may not make initial sense, until you remember that
|
||||||
|
anchoring is performed before spin:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
oval(r=50, anchor=FRONT, spin=-30);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Trapezoids
|
||||||
|
|
||||||
|
OpenSCAD doesn't provide a simple way to make 2D triangles, trapezoids, or parallelograms.
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
trapezoid(w1=50, w2=0, h=50, shift=-25);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
trapezoid(w1=50, w2=0, h=50, shift=25);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
trapezoid(w1=0, w2=50, h=50, shift=-25);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
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=`):
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
trapezoid(w1=50, w2=30, shift=20, h=50);
|
||||||
|
```
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
trapezoid(w1=30, w2=50, h=50)
|
||||||
|
show_anchors();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Regular N-Gons
|
||||||
|
|
||||||
|
OpenSCAD lets you make regular N-gons (pentagon, hexagon, etc) by using `circle()` with `$fn`.
|
||||||
|
While this is concise, it may be less than obvious at first glance:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
circle(d=50, $fn=5);
|
||||||
|
```
|
||||||
|
|
||||||
|
The BOSL2 library has modules that are named more clearly:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
pentagon(d=50);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
hexagon(d=50);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
octagon(d=50);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
regular_ngon(n=7, d=50);
|
||||||
|
```
|
||||||
|
|
||||||
|
These modules also provide you with extra functionality.
|
||||||
|
|
||||||
|
They can be sized by side length:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
pentagon(side=20);
|
||||||
|
```
|
||||||
|
|
||||||
|
They can be sized by circumscribed circle radius/diameter:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
pentagon(ir=25);
|
||||||
|
pentagon(id=50);
|
||||||
|
```
|
||||||
|
|
||||||
|
They can be realigned by half a side's angle:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
left(30) pentagon(d=50, realign=true);
|
||||||
|
right(30) pentagon(d=50, realign=false);
|
||||||
|
```
|
||||||
|
|
||||||
|
They can be rounded:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
pentagon(d=50, rounding=10);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
hexagon(d=50, rounding=10);
|
||||||
|
```
|
||||||
|
|
||||||
|
They also have somewhat different attachment behavior:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
color("green") stroke(circle(d=50), closed=true);
|
||||||
|
oval(d=50,$fn=5)
|
||||||
|
attach(LEFT) color("blue") anchor_arrow2d();
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
pentagon(d=50)
|
||||||
|
attach(LEFT) color("blue") anchor_arrow2d();
|
||||||
|
```
|
||||||
|
|
||||||
|
You can use `anchor=` and `spin=`, just like with other attachable shapes. However, the anchor
|
||||||
|
points are based on where the anchor vector would intersect the side of the N-gon, and may not
|
||||||
|
be where you expect them:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
pentagon(d=50)
|
||||||
|
show_anchors(custom=false);
|
||||||
|
```
|
||||||
|
|
||||||
|
N-gons also have named anchor points for their sides and tips:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
pentagon(d=30)
|
||||||
|
show_anchors(std=false);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Stars
|
||||||
|
|
||||||
|
The BOSL2 library has stars as a basic supported shape. They can have any number of points.
|
||||||
|
You can specify a star's shape by point count, inner and outer vertex radius/diameters:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
star(n=3, id=10, d=50);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
star(n=5, id=15, r=25);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
star(n=10, id=30, d=50);
|
||||||
|
```
|
||||||
|
|
||||||
|
Or you can specify the star shape by point count and number of points to step:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
star(n=7, step=2, d=50);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
left(30) star(n=5, step=2, d=50);
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
star(n=5, ir=15, or=30, align_tip=BACK+LEFT)
|
||||||
|
attach("tip0") color("blue") anchor_arrow2d();
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
star(n=5, ir=15, or=30, align_tip=BACK+RIGHT)
|
||||||
|
attach("tip0") color("blue") anchor_arrow2d();
|
||||||
|
```
|
||||||
|
|
||||||
|
Similarly, the first indentation or pit can be oriented towards a specific vector with `align_pit=`:
|
||||||
|
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
star(n=5, ir=15, or=30, align_pit=BACK+LEFT)
|
||||||
|
attach("pit0") color("blue") anchor_arrow2d();
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
star(n=5, ir=15, or=30, align_pit=BACK+RIGHT)
|
||||||
|
attach("pit0") color("blue") anchor_arrow2d();
|
||||||
|
```
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
star(n=5, step=2, d=50)
|
||||||
|
show_anchors(custom=false);
|
||||||
|
```
|
||||||
|
|
||||||
|
Stars also have named anchor points for their pits, tips, and midpoints between tips:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
star(n=5, step=2, d=40)
|
||||||
|
show_anchors(std=false);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Teardrop2D
|
||||||
|
|
||||||
|
Often when 3D printing, you may want to make a circular hole in a vertical wall. If the hole is
|
||||||
|
too big, however, the overhang at the top of the hole can cause problems with printing on an
|
||||||
|
FDM/FFF printer. If you don't want to use support material, you can just use the teardrop shape.
|
||||||
|
The `teardrop2d()` module will let you make a 2D version of the teardrop shape, so that you can
|
||||||
|
extrude it later:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
teardrop2d(r=20);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
teardrop2d(d=50);
|
||||||
|
```
|
||||||
|
|
||||||
|
The default overhang angle is 45 degrees, but you can adjust that with the `ang=` argument:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
teardrop2d(d=50, ang=30);
|
||||||
|
```
|
||||||
|
|
||||||
|
If you prefer to flatten the top of the teardrop, to encourage bridging, you can use the `cap_h=`
|
||||||
|
argument:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
teardrop2d(d=50, cap_h=25);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
teardrop2d(d=50, ang=30, cap_h=30);
|
||||||
|
```
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
teardrop2d(d=50, ang=30, cap_h=30)
|
||||||
|
show_anchors();
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Glued Circles
|
||||||
|
|
||||||
|
A more unusal shape that BOSL2 provides is Glued Circles. It's basically a pair of circles,
|
||||||
|
connected by what looks like a gloopy glued miniscus:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
glued_circles(d=30, spread=40);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `r=`/`d=` arguments can specify the radius or diameter of the two circles:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
glued_circles(r=20, spread=45);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
glued_circles(d=40, spread=45);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `spread=` argument specifies the distance between the centers of the two circles:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
glued_circles(d=30, spread=30);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
glued_circles(d=30, spread=40);
|
||||||
|
```
|
||||||
|
|
||||||
|
The `tangent=` argument gives the angle of the tangent of the meniscus on the two circles:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
glued_circles(d=30, spread=30, tangent=45);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
glued_circles(d=30, spread=30, tangent=20);
|
||||||
|
```
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
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:
|
||||||
|
|
||||||
|
```openscad-3D
|
||||||
|
$fn=36; s=10;
|
||||||
|
linear_extrude(height=50,convexity=16,center=true)
|
||||||
|
xcopies(s*sqrt(2),n=3)
|
||||||
|
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
|
||||||
|
points are based on the furthest extents of the shape, and may not be where you expect them:
|
||||||
|
|
||||||
|
```openscad-2D
|
||||||
|
glued_circles(d=40, spread=40, tangent=45)
|
||||||
|
show_anchors();
|
||||||
|
```
|
||||||
|
|
|
@ -1,233 +1,13 @@
|
||||||
# Basic Shapes Tutorial
|
# Basic Shapes Tutorial
|
||||||
|
|
||||||
## Primitives
|
## Primitives
|
||||||
There are 5 built-in primitive shapes that OpenSCAD provides.
|
There are 3 built-in 3D primitive shapes that OpenSCAD provides: `cube()`, `cylinder()`,
|
||||||
`square()`, `circle()`, `cube()`, `cylinder()`, and `sphere()`.
|
and `sphere()`. The BOSL2 library extends and provides alternative to these shapes so
|
||||||
The BOSL2 library extends or provides alternative to these shapes so
|
|
||||||
that they support more features, and more ways to simply reorient them.
|
that they support more features, and more ways to simply reorient them.
|
||||||
|
|
||||||
|
|
||||||
### 2D Squares
|
|
||||||
You can still use the built-in `square()` in the familiar ways that OpenSCAD provides:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
square(100, center=false);
|
|
||||||
```
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
square(100, center=true);
|
|
||||||
```
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
square([60,40], center=true);
|
|
||||||
```
|
|
||||||
|
|
||||||
The BOSL2 library provides an enhanced equivalent to `square()` called `rect()`.
|
|
||||||
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:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], center=true, rounding=10);
|
|
||||||
```
|
|
||||||
|
|
||||||
Or chamfer them:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], center=true, chamfer=10);
|
|
||||||
```
|
|
||||||
|
|
||||||
You can even specify *which* corners get rounded or chamfered. If you pass a
|
|
||||||
list of four size numbers to the `rounding=` or `chamfer=` arguments, it will
|
|
||||||
give each corner its own size. In order, it goes from the back-right (quadrant I)
|
|
||||||
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:
|
|
||||||
|
|
||||||
```openscad-2DImgOnly
|
|
||||||
module text3d(text) color("black") text(
|
|
||||||
text=text, font="Times", size=10,
|
|
||||||
halign="center", valign="center"
|
|
||||||
);
|
|
||||||
translate([ 50, 50]) text3d("I");
|
|
||||||
translate([-50, 50]) text3d("II");
|
|
||||||
translate([-50,-50]) text3d("III");
|
|
||||||
translate([ 50,-50]) text3d("IV");
|
|
||||||
rect([90,80], center=true);
|
|
||||||
```
|
|
||||||
|
|
||||||
If a size is given as `0`, then there is no rounding and/or chamfering for
|
|
||||||
that quadrant's corner:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], center=true, rounding=[0,5,10,15]);
|
|
||||||
```
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], center=true, chamfer=[0,5,10,15]);
|
|
||||||
```
|
|
||||||
|
|
||||||
You can give both `rounding=` and `chamfer=` arguments to mix rounding and
|
|
||||||
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:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], center=true, rounding=[5,0,10,0], chamfer=[0,5,0,15]);
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Anchors and Spin
|
|
||||||
Another way that `rect()` is enhanced over `square()`, is that you can anchor,
|
|
||||||
spin and attach it.
|
|
||||||
|
|
||||||
The `anchor=` argument is an alternative to `center=`, which allows more
|
|
||||||
alignment options. It takes a vector as a value, pointing roughly towards
|
|
||||||
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]`:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], anchor=[0,1]);
|
|
||||||
```
|
|
||||||
|
|
||||||
To align the front right corner to the origin:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], anchor=[1,-1]);
|
|
||||||
```
|
|
||||||
|
|
||||||
To center:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], anchor=[0,0]);
|
|
||||||
```
|
|
||||||
|
|
||||||
To make it clearer when giving vectors, there are several standard vector
|
|
||||||
constants defined:
|
|
||||||
|
|
||||||
Constant | Direction | Value
|
|
||||||
-------- | --------- | -----------
|
|
||||||
`LEFT` | X- | `[-1, 0, 0]`
|
|
||||||
`RIGHT` | X+ | `[ 1, 0, 0]`
|
|
||||||
`FRONT`/`FORWARD`/`FWD` | Y- | `[ 0,-1, 0]`
|
|
||||||
`BACK` | Y+ | `[ 0, 1, 0]`
|
|
||||||
`BOTTOM`/`BOT`/`BTM`/`DOWN` | Z- | `[ 0, 0,-1]` (3D only.)
|
|
||||||
`TOP`/`UP` | Z+ | `[ 0, 0, 1]` (3D only.)
|
|
||||||
`CENTER`/`CTR` | Centered | `[ 0, 0, 0]`
|
|
||||||
|
|
||||||
Note that even though these are 3D vectors, you can use most of them,
|
|
||||||
(except `UP`/`DOWN`, of course) for anchors in 2D shapes:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], anchor=BACK);
|
|
||||||
```
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], anchor=CENTER);
|
|
||||||
```
|
|
||||||
|
|
||||||
You can add vectors together to point to corners:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], anchor=FRONT+RIGHT);
|
|
||||||
```
|
|
||||||
|
|
||||||
Finally, the `spin` argument can rotate the shape by a given number of degrees
|
|
||||||
clockwise:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], anchor=CENTER, spin=30);
|
|
||||||
```
|
|
||||||
|
|
||||||
Anchoring or centering is performed before the spin:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
rect([60,40], anchor=BACK, spin=30);
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### 2D Circles
|
|
||||||
The built-in `circle()` primitive can be used as expected:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
circle(r=50);
|
|
||||||
```
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
circle(d=100);
|
|
||||||
```
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
circle(d=100, $fn=8);
|
|
||||||
```
|
|
||||||
|
|
||||||
The BOSL2 library provides an enhanced equivalent of `circle()` called `oval()`.
|
|
||||||
You can use it in the same way you use `circle()`, but it also provides
|
|
||||||
extended functionality. For example, it allows more control over its size and
|
|
||||||
orientation.
|
|
||||||
|
|
||||||
Since a circle in OpenSCAD can only be approximated by a regular polygon with
|
|
||||||
a number of straight sides, this can lead to size and shape inaccuracies.
|
|
||||||
To counter this, the `realign=` and `circum=` arguments are also provided.
|
|
||||||
|
|
||||||
The `realign=` argument, if set `true`, rotates the `oval()` by half the angle
|
|
||||||
between the sides:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
oval(d=100, $fn=8, realign=true);
|
|
||||||
```
|
|
||||||
|
|
||||||
The `circum=` argument, if true, makes it so that the polygon forming the
|
|
||||||
`oval()` circumscribes the ideal circle instead of inscribing it.
|
|
||||||
|
|
||||||
Inscribing the ideal circle:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
difference() {
|
|
||||||
circle(d=100, $fn=360);
|
|
||||||
oval(d=100, $fn=8);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Circumscribing the ideal circle:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
difference() {
|
|
||||||
oval(d=100, $fn=8, circum=true);
|
|
||||||
circle(d=100, $fn=360);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `oval()` module, as its name suggests, can be given separate X and Y radii
|
|
||||||
or diameters. To do this, just give `r=` or `d=` with a list of two radii or
|
|
||||||
diameters:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
oval(r=[30,20]);
|
|
||||||
```
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
oval(d=[60,40]);
|
|
||||||
```
|
|
||||||
|
|
||||||
Another way that `oval()` is enhanced over `circle()`, is that you can anchor,
|
|
||||||
spin and attach it.
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
oval(r=50, anchor=BACK);
|
|
||||||
```
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
oval(r=50, anchor=FRONT+RIGHT);
|
|
||||||
```
|
|
||||||
|
|
||||||
Using spin on a circle may not make initial sense, until you remember that
|
|
||||||
anchoring is performed before spin:
|
|
||||||
|
|
||||||
```openscad-2D
|
|
||||||
oval(r=50, anchor=FRONT, spin=-30);
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### 3D Cubes
|
### 3D Cubes
|
||||||
BOSL2 overrides the built-in `cube()` module. It still can be used as you
|
BOSL2 overrides the built-in `cube()` module. It still can be used as you expect from the built-in:
|
||||||
expect from the built-in:
|
|
||||||
|
|
||||||
```openscad-3D
|
```openscad-3D
|
||||||
cube(100);
|
cube(100);
|
||||||
|
@ -243,7 +23,7 @@ expect from the built-in:
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
You can use `anchor=` similarly to how you use it with `square()` or `rect()`,
|
You can use `anchor=` similarly to how you use it with `rect()` or `oval()`,
|
||||||
except you can also anchor vertically in 3D, allowing anchoring to faces, edges,
|
except you can also anchor vertically in 3D, allowing anchoring to faces, edges,
|
||||||
and corners:
|
and corners:
|
||||||
|
|
||||||
|
@ -546,11 +326,20 @@ The "stagger" style will stagger the triangulation of the vertical rows:
|
||||||
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
|
||||||
sphere surface:
|
sphere surface, based on subdividing an icosahedron. This style will round the
|
||||||
|
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
|
||||||
|
sphere surface, but based on subdividing an octahedron. This is useful in that it
|
||||||
|
guarantees vertices at the axis extrema. This style will round the effective `$fn`
|
||||||
|
to a multiple of 4 when constructing the spheroid:
|
||||||
|
|
||||||
|
```openscad-3D
|
||||||
|
spheroid(d=100, style="octa", $fn=20);
|
||||||
|
```
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
BOSL_VERSION = [2,0,486];
|
BOSL_VERSION = [2,0,487];
|
||||||
|
|
||||||
|
|
||||||
// Section: BOSL Library Version Functions
|
// Section: BOSL Library Version Functions
|
||||||
|
|
Loading…
Reference in a new issue