mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-04 03:09:45 +00:00
Merge pull request #779 from revarbat/revarbat_dev
Fixed double-includes in tutorials.
This commit is contained in:
commit
9d55a7b6bf
10 changed files with 466 additions and 43 deletions
|
@ -269,7 +269,7 @@ Which outputs Markdown code that renders like:
|
|||
> The golden ration phi.
|
||||
|
||||
|
||||
The `Module` header is used to document a module. It should have a Description sub-block. It is recommended to also have Usage, Arguments, and Example/Examples sub-blocks:
|
||||
The `Module` header is used to document a module. It should have a Description sub-block. It is recommended to also have Usage, Arguments, and Example/Examples sub-blocks. The Usage sub-block body lines are also used when constructing the Cheat Sheet index file:
|
||||
|
||||
// Module: cross()
|
||||
// Usage:
|
||||
|
@ -306,7 +306,7 @@ Which outputs Markdown code that renders like:
|
|||
> GENERATED IMAGE GOES HERE
|
||||
|
||||
|
||||
The `Function` header is used to document a function. It should have a Description sub-block. It is recommended to also have Usage, Arguments, and Example/Examples sub-blocks. By default, Examples will not generate images for function blocks:
|
||||
The `Function` header is used to document a function. It should have a Description sub-block. It is recommended to also have Usage, Arguments, and Example/Examples sub-blocks. By default, Examples will not generate images for function blocks. Usage sub-block body lines are also used when constructing the Cheat Sheet index file:
|
||||
|
||||
// Function: vector_angle()
|
||||
// Usage:
|
||||
|
@ -347,8 +347,7 @@ Which outputs Markdown code that renders like:
|
|||
> // Returns: 45
|
||||
> ```
|
||||
|
||||
The `Function&Module` header is used to document a function which has a related module of the same name. It should have a Description sub-block. It is recommended to also have Usage, Arguments, and Example/Examples sub-blocks. You should have Usage blocks for both calling as a function, and calling as a
|
||||
module:
|
||||
The `Function&Module` header is used to document a function which has a related module of the same name. It should have a Description sub-block. It is recommended to also have Usage, Arguments, and Example/Examples sub-blocks. You should have Usage blocks for both calling as a function, and calling as a module. Usage sub-block body lines are also used in constructing the Cheat Sheet index file:
|
||||
|
||||
// Function&Module: oval()
|
||||
// Topics: 2D Shapes, Geometry
|
||||
|
@ -464,7 +463,7 @@ Which outputs Markdown code that renders like:
|
|||
Usage Block
|
||||
-----------
|
||||
|
||||
The Usage block describes the various ways that the current function or module can be called, with the names of the arguments. By convention, the first few arguments that can be called positionally just have their name shown. The remaining arguments that should be passed by name, will have the name followed by an `=` (equal sign). Arguments that are optional in the given Usage context are shown in `<` and `>` angle brackets:
|
||||
The Usage block describes the various ways that the current function or module can be called, with the names of the arguments. By convention, the first few arguments that can be called positionally just have their name shown. The remaining arguments that should be passed by name, will have the name followed by an `=` (equal sign). Arguments that are optional in the given Usage context are shown in `[` and `]` angle brackets. Usage sub-block body lines are also used when constructing the Cheat Sheet index file:
|
||||
|
||||
// Usage: As a Module
|
||||
// oval(rx, ry, <spin=>);
|
||||
|
@ -608,7 +607,8 @@ metadata directives:
|
|||
- `Big`: Make the image big sized.
|
||||
- `Huge`: Make the image huge sized.
|
||||
- `Size=880x640`: Make the image 880 by 640 pixels in size.
|
||||
- `Render`: Force full rendering from OpenSCAD, instead of the normal preview.
|
||||
- `ThrownTogether`: Render in Thrown Together view mode instead of Preview mode.
|
||||
- `Render`: Force full rendering from OpenSCAD, instead of the normal Preview mode.
|
||||
- `Edges`: Highlight face edges.
|
||||
- `NoAxes`: Hides the axes and scales.
|
||||
- `NoScales`: Hides the scale numbers along the axes.
|
||||
|
|
|
@ -17,16 +17,19 @@ corner that will be aligned to. For example, a vector of [1,0,-1] refers to the
|
|||
edge of the shape. Each vector component should be -1, 0, or 1:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
// Anchor at upper-front-left corner
|
||||
cube([40,30,50], anchor=[-1,-1,1]);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
// Anchor at upper-right edge
|
||||
cube([40,30,50], anchor=[1,0,1]);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
// Anchor at bottom face
|
||||
cube([40,30,50], anchor=[0,0,-1]);
|
||||
```
|
||||
|
@ -49,10 +52,12 @@ constants together like `BOTTOM + LEFT`. Ths will result in a vector of `[-1,0,
|
|||
that to the `anchor=` argument for a clearly understandable anchoring:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([40,30,50], anchor=BACK+TOP);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([40,30,50], anchor=FRONT);
|
||||
```
|
||||
|
||||
|
@ -65,14 +70,17 @@ These combined let you point at any place on the bottom or top rims, or at an ar
|
|||
side wall:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(r1=25, r2=15, h=60, anchor=TOP+LEFT);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(r1=25, r2=15, h=60, anchor=BOTTOM+FRONT);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(r1=25, r2=15, h=60, anchor=UP+spherical_to_xyz(1,30,90));
|
||||
```
|
||||
|
||||
|
@ -82,14 +90,17 @@ For Spherical type attachables, you can pass a vector that points at any arbitra
|
|||
the surface of the sphere:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
sphere(r=50, anchor=TOP);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
sphere(r=50, anchor=TOP+FRONT);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
sphere(r=50, anchor=spherical_to_xyz(1,-30,60));
|
||||
```
|
||||
|
||||
|
@ -100,6 +111,7 @@ will be given as strings and will be specific to that type of attachable. For e
|
|||
`teardrop()` attachable has a named anchor called "cap":
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
teardrop(d=100, l=20, anchor="cap");
|
||||
```
|
||||
|
||||
|
@ -111,10 +123,12 @@ A `center=false` argument can mean `anchor=[-1,-1,-1]` for a cube, or `anchor=BO
|
|||
cylinder, to make them behave just like the builtin versions:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,30],center=true);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,30],center=false);
|
||||
```
|
||||
|
||||
|
@ -125,18 +139,22 @@ modules have been overridden to enable attachability and anchoring. The `anchor
|
|||
shapes can accept 3D vectors, but only the X and Y components will be used:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([40,30], anchor=BACK+LEFT);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50, anchor=BACK);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
hexagon(d=50, anchor=LEFT);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ellipse(d=[50,30], anchor=FRONT);
|
||||
```
|
||||
|
||||
|
@ -148,6 +166,7 @@ clockwise spin around the Z axis (as seen from above), and a negative number wil
|
|||
spin:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([20,20,40], center=true, spin=45);
|
||||
```
|
||||
|
||||
|
@ -156,16 +175,19 @@ You can even spin around each of the three axes in one pass, by giving 3 angles
|
|||
the order given, X-axis spin, then Y-axis, then Z-axis:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([20,20,40], center=true, spin=[10,20,30]);
|
||||
```
|
||||
|
||||
You can also apply spin to 2D shapes from BOSL2, though only by scalar angle:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([40,30], spin=30);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ellipse(d=[40,30], spin=30);
|
||||
```
|
||||
|
||||
|
@ -176,6 +198,7 @@ Another way to specify a rotation for an attachable shape, is to pass a 3D vecto
|
|||
For example, you can make a cone that is tilted up and to the right like this:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(h=100, r1=50, r2=20, orient=UP+RIGHT);
|
||||
```
|
||||
|
||||
|
@ -187,24 +210,28 @@ When giving `anchor=`, `spin=`, and `orient=`, they are applied anchoring first,
|
|||
then orient last. For example, here's a cube:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([20,20,50]);
|
||||
```
|
||||
|
||||
You can center it with an `anchor=CENTER` argument:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([20,20,50], anchor=CENTER);
|
||||
```
|
||||
|
||||
Add a 45 degree spin:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([20,20,50], anchor=CENTER, spin=45);
|
||||
```
|
||||
|
||||
Now tilt the top up and forward:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([20,20,50], anchor=CENTER, spin=45, orient=UP+FWD);
|
||||
```
|
||||
|
||||
|
@ -212,12 +239,14 @@ Something that may confuse new users is that adding spin to a cylinder may seem
|
|||
However, since spin is applied *after* anchoring, it can actually have a significant effect:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(d=50, l=40, anchor=FWD, spin=-30);
|
||||
```
|
||||
|
||||
For 2D shapes, you can mix `anchor=` with `spin=`, but not with `orient=`.
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([40,30], anchor=BACK+LEFT, spin=30);
|
||||
```
|
||||
|
||||
|
@ -228,6 +257,7 @@ You can do that by making one attachable shape be a child of another attachable
|
|||
By default, the child of an attachable is attached to the center of the parent shape.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(50,center=true)
|
||||
cylinder(d1=50,d2=20,l=50);
|
||||
```
|
||||
|
@ -237,6 +267,7 @@ this will attach the bottom of the child to the given position on the parent. T
|
|||
of the child will be overridden to point outwards from the center of the parent, more or less:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(50,center=true)
|
||||
attach(TOP) cylinder(d1=50,d2=20,l=20);
|
||||
```
|
||||
|
@ -245,6 +276,7 @@ If you give `attach()` a second anchor argument, it attaches that anchor on the
|
|||
first anchor on the parent:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(50,center=true)
|
||||
attach(TOP,TOP) cylinder(d1=50,d2=20,l=20);
|
||||
```
|
||||
|
@ -255,12 +287,14 @@ it's useful to have the child overlap the parent by insetting a bit. You can do
|
|||
a negative value will outset out from the parent:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(50,center=true)
|
||||
attach(TOP,overlap=10)
|
||||
cylinder(d=20,l=20);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(50,center=true)
|
||||
attach(TOP,overlap=-20)
|
||||
cylinder(d=20,l=20);
|
||||
|
@ -270,6 +304,7 @@ If you want to position the child at the parent's anchorpoint, without re-orient
|
|||
use the `position()` module:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(50,center=true)
|
||||
position(RIGHT) cylinder(d1=50,d2=20,l=20);
|
||||
```
|
||||
|
@ -277,6 +312,7 @@ cube(50,center=true)
|
|||
You can attach or position more than one child at a time by enclosing them all in braces:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(50, center=true) {
|
||||
attach(TOP) cylinder(d1=50,d2=20,l=20);
|
||||
position(RIGHT) cylinder(d1=50,d2=20,l=20);
|
||||
|
@ -287,11 +323,13 @@ If you want to attach the same shape to multiple places on the same parent, you
|
|||
desired anchors as a list to the `attach()` or `position()` modules:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(50, center=true)
|
||||
attach([RIGHT,FRONT],TOP) cylinder(d1=50,d2=20,l=20);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(50, center=true)
|
||||
position([TOP,RIGHT,FRONT]) cylinder(d1=50,d2=20,l=20);
|
||||
```
|
||||
|
@ -300,12 +338,14 @@ cube(50, center=true)
|
|||
You can use attachments in 2D as well, but only in the XY plane:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square(50,center=true)
|
||||
attach(RIGHT,FRONT)
|
||||
trapezoid(w1=30,w2=0,h=30);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50)
|
||||
attach(BACK,FRONT,overlap=5)
|
||||
trapezoid(w1=30,w2=0,h=30);
|
||||
|
@ -316,6 +356,7 @@ One way that is useful to show the position and orientation of an anchorpoint is
|
|||
an anchor arrow to that anchor.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(40, center=true)
|
||||
attach(LEFT+TOP)
|
||||
anchor_arrow();
|
||||
|
@ -324,6 +365,7 @@ cube(40, center=true)
|
|||
For large objects, you can change the size of the arrow with the `s=` argument.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
sphere(d=100)
|
||||
attach(LEFT+TOP)
|
||||
anchor_arrow(s=30);
|
||||
|
@ -332,16 +374,19 @@ sphere(d=100)
|
|||
To show all the standard cardinal anchorpoints, you can use the `show_anchors()` module.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(40, center=true)
|
||||
show_anchors();
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(h=40, d=40, center=true)
|
||||
show_anchors();
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
sphere(d=40)
|
||||
show_anchors();
|
||||
```
|
||||
|
@ -349,6 +394,7 @@ sphere(d=40)
|
|||
For large objects, you can again change the size of the arrows with the `s=` argument.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(h=100, d=100, center=true)
|
||||
show_anchors(s=30);
|
||||
```
|
||||
|
@ -369,6 +415,7 @@ For example, to difference away a child cylinder from the middle of a parent cub
|
|||
do this:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
diff("hole")
|
||||
cube(100, center=true)
|
||||
cylinder(h=101, d=50, center=true, $tags="hole");
|
||||
|
@ -379,6 +426,7 @@ given to `neg=` will be differenced away from the shapes marked with tags given
|
|||
Everything else will be unioned to the result.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
diff("hole", "post")
|
||||
cube(100, center=true)
|
||||
attach([RIGHT,TOP]) {
|
||||
|
@ -390,6 +438,7 @@ cube(100, center=true)
|
|||
The `keep=` argument takes tags for shapes that you want to keep in the output.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
diff("dish", keep="antenna")
|
||||
cube(100, center=true)
|
||||
attach([FRONT,TOP], overlap=33) {
|
||||
|
@ -401,6 +450,7 @@ cube(100, center=true)
|
|||
If you need to mark multiple children with a tag, you can use the `tags()` module.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
diff("hole")
|
||||
cube(100, center=true)
|
||||
attach([FRONT,TOP], overlap=20)
|
||||
|
@ -414,6 +464,7 @@ The parent object can be differenced away from other shapes. Tags are inherited
|
|||
though, so you will need to set the tags of the children as well as the parent.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
diff("hole")
|
||||
cube([20,11,45], center=true, $tags="hole")
|
||||
cube([40,10,90], center=true, $tags="body");
|
||||
|
@ -429,6 +480,7 @@ To allow you to use tags-based operations with non-attachable shapes, you can wr
|
|||
`tags()` module to specify their tags. For example:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
diff("hole")
|
||||
cuboid(50)
|
||||
attach(TOP)
|
||||
|
@ -445,6 +497,7 @@ argument to `a=`, the parent and all children *not* tagged with that will be int
|
|||
everything that *is* tagged with it.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
intersect("bounds")
|
||||
cube(100, center=true)
|
||||
cylinder(h=100, d1=120, d2=95, center=true, $fn=72, $tags="bounds");
|
||||
|
@ -454,6 +507,7 @@ If given both the `a=` and `b=` arguments, then shapes marked with tags given to
|
|||
intersected with shapes marked with tags given to `b=`, then unioned with all other shapes.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
intersect("pole", "cap")
|
||||
cube(100, center=true)
|
||||
attach([TOP,RIGHT]) {
|
||||
|
@ -466,6 +520,7 @@ If the `keep=` argument is given, anything marked with tags passed to it will be
|
|||
the result of the union:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
intersect("bounds", keep="pole")
|
||||
cube(100, center=true) {
|
||||
cylinder(h=100, d1=120, d2=95, center=true, $fn=72, $tags="bounds");
|
||||
|
@ -478,6 +533,7 @@ You can use the `hulling()` module to hull shapes marked with a given tag togeth
|
|||
unioning the result with every other shape.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
hulling("hull")
|
||||
cube(50, center=true, $tags="hull") {
|
||||
cyl(h=100, d=20);
|
||||
|
@ -498,6 +554,7 @@ edges. The shape will be tagged as a "mask" so that you can use `diff("mask")`.
|
|||
here's a shape for rounding an edge:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module round_edge(l,r) difference() {
|
||||
translate([-1,-1,-l/2])
|
||||
cube([r+1,r+1,l]);
|
||||
|
@ -510,6 +567,7 @@ round_edge(l=30, r=19);
|
|||
You can use that mask to round various edges of a cube:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module round_edge(l,r) difference() {
|
||||
translate([-1,-1,-l/2])
|
||||
cube([r+1,r+1,l]);
|
||||
|
@ -530,6 +588,7 @@ will be tagged as a "mask" so that you can use `diff("mask")`. For example, her
|
|||
rounding a corner:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module round_corner(r) difference() {
|
||||
translate(-[1,1,1])
|
||||
cube(r+1);
|
||||
|
@ -542,6 +601,7 @@ round_corner(r=10);
|
|||
You can use that mask to round various corners of a cube:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module round_corner(r) difference() {
|
||||
translate(-[1,1,1])
|
||||
cube(r+1);
|
||||
|
@ -558,6 +618,7 @@ cube([50,60,70],center=true)
|
|||
You can use `edge_mask()` and `corner_mask()` together as well:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module round_corner(r) difference() {
|
||||
translate(-[1,1,1])
|
||||
cube(r+1);
|
||||
|
@ -593,12 +654,14 @@ re-oriented towards the edges of the parent shape. A typical mask profile for c
|
|||
edge may look like:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
mask2d_roundover(10);
|
||||
```
|
||||
|
||||
Using that mask profile, you can mask the edges of a cube like:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
diff("mask")
|
||||
cube([50,60,70],center=true)
|
||||
edge_profile("ALL")
|
||||
|
@ -609,6 +672,7 @@ cube([50,60,70],center=true)
|
|||
You can use the same profile to make a rounded corner mask as well:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
diff("mask")
|
||||
cube([50,60,70],center=true)
|
||||
corner_profile("ALL", r=10)
|
||||
|
@ -620,6 +684,7 @@ As a simple shortcut to apply a profile mask to all edges and corners of a face,
|
|||
`face_profile()` module:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
diff("mask")
|
||||
cube([50,60,70],center=true)
|
||||
face_profile(TOP, r=10)
|
||||
|
@ -632,6 +697,7 @@ Usually, when coloring a shape with the `color()` module, the parent color overr
|
|||
all children. This is often not what you want:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
$fn = 24;
|
||||
color("red") spheroid(d=3) {
|
||||
attach(CENTER,BOT) color("white") cyl(h=10, d=1) {
|
||||
|
@ -644,6 +710,7 @@ If you use the `recolor()` module, however, the child's color overrides the colo
|
|||
This is probably easier to understand by example:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
$fn = 24;
|
||||
recolor("red") spheroid(d=3) {
|
||||
attach(CENTER,BOT) recolor("white") cyl(h=10, d=1) {
|
||||
|
@ -667,6 +734,7 @@ In the most basic form, where the shape is fully cuboid, with top and bottom of
|
|||
and directly over one another, you can just use `size=`.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module cubic_barbell(s=100, anchor=CENTER, spin=0, orient=UP) {
|
||||
attachable(anchor,spin,orient, size=[s*3,s,s]) {
|
||||
union() {
|
||||
|
@ -684,6 +752,7 @@ the `size2=` argument as well. While `size=` takes all three axes sizes, the `si
|
|||
only takes the [X,Y] sizes of the top of the shape.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module prismoidal(size=[100,100,100], scale=0.5, anchor=CENTER, spin=0, orient=UP) {
|
||||
attachable(anchor,spin,orient, size=size, size2=[size.x, size.y]*scale) {
|
||||
hull() {
|
||||
|
@ -705,6 +774,7 @@ the `shift=` argument. The `shift=` argument takes an [X,Y] vector of the offse
|
|||
of the top from the XY center of the bottom of the shape.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module prismoidal(size=[100,100,100], scale=0.5, shift=[0,0], anchor=CENTER, spin=0, orient=UP) {
|
||||
attachable(anchor,spin,orient, size=size, size2=[size.x, size.y]*scale, shift=shift) {
|
||||
hull() {
|
||||
|
@ -726,6 +796,7 @@ arguments should refer to a plane other than XY) you can use the `axis=` argumen
|
|||
you make prismoids naturally oriented forwards/backwards or sideways.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module yprismoidal(
|
||||
size=[100,100,100], scale=0.5, shift=[0,0],
|
||||
anchor=CENTER, spin=0, orient=UP
|
||||
|
@ -754,6 +825,7 @@ yprismoidal([100,60,30], scale=1.5, shift=[20,20]) show_anchors(20);
|
|||
To make a cylindrical shape attachable, you use the `l`, and `r`/`d`, args of `attachable()`.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module twistar(l,r,d, anchor=CENTER, spin=0, orient=UP) {
|
||||
r = get_radius(r=r,d=d,dflt=1);
|
||||
attachable(anchor,spin,orient, r=r, l=l) {
|
||||
|
@ -769,6 +841,7 @@ If the cylinder is elipsoidal in shape, you can pass the inequal X/Y sizes as a
|
|||
to the `r=` or `d=` argument.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module ovalstar(l,rx,ry, anchor=CENTER, spin=0, orient=UP) {
|
||||
attachable(anchor,spin,orient, r=[rx,ry], l=l) {
|
||||
linear_extrude(height=l, center=true, convexity=4)
|
||||
|
@ -783,6 +856,7 @@ ovalstar(l=100, rx=50, ry=30) show_anchors(20);
|
|||
For cylindrical shapes that arent oriented vertically, use the `axis=` argument.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module ytwistar(l,r,d, anchor=CENTER, spin=0, orient=UP) {
|
||||
r = get_radius(r=r,d=d,dflt=1);
|
||||
attachable(anchor,spin,orient, r=r, l=l, axis=BACK) {
|
||||
|
@ -800,6 +874,7 @@ To make a conical shape attachable, you use the `l`, `r1`/`d1`, and `r2`/`d2`, a
|
|||
`attachable()`.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module twistar(l, r,r1,r2, d,d1,d2, anchor=CENTER, spin=0, orient=UP) {
|
||||
r1 = get_radius(r1=r1,r=r,d1=d1,d=d,dflt=1);
|
||||
r2 = get_radius(r1=r2,r=r,d1=d2,d=d,dflt=1);
|
||||
|
@ -816,6 +891,7 @@ If the cone is ellipsoidal in shape, you can pass the inequal X/Y sizes as a 2-i
|
|||
to the `r1=`/`r2=` or `d1=`/`d2=` arguments.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module ovalish(l,rx1,ry1,rx2,ry2, anchor=CENTER, spin=0, orient=UP) {
|
||||
attachable(anchor,spin,orient, r1=[rx1,ry1], r2=[rx2,ry2], l=l) {
|
||||
hull() {
|
||||
|
@ -836,6 +912,7 @@ For conical shapes that are not oriented vertically, use the `axis=` argument to
|
|||
direction of the primary shape axis:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module ytwistar(l, r,r1,r2, d,d1,d2, anchor=CENTER, spin=0, orient=UP) {
|
||||
r1 = get_radius(r1=r1,r=r,d1=d1,d=d,dflt=1);
|
||||
r2 = get_radius(r1=r2,r=r,d1=d2,d=d,dflt=1);
|
||||
|
@ -853,6 +930,7 @@ ytwistar(l=100, r1=40, r2=20) show_anchors(20);
|
|||
To make a spherical shape attachable, you use the `r`/`d` args of `attachable()`.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module spikeball(r, d, anchor=CENTER, spin=0, orient=UP) {
|
||||
r = get_radius(r=r,d=d,dflt=1);
|
||||
attachable(anchor,spin,orient, r=r*1.1) {
|
||||
|
@ -869,6 +947,7 @@ spikeball(r=50) show_anchors(20);
|
|||
If the shape is more of an ovoid, you can pass a 3-item vector of sizes to `r=` or `d=`.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module spikeball(r, d, scale, anchor=CENTER, spin=0, orient=UP) {
|
||||
r = get_radius(r=r,d=d,dflt=1);
|
||||
attachable(anchor,spin,orient, r=r*1.1*scale) {
|
||||
|
@ -892,6 +971,7 @@ to the furthest distance that intersects with the VNF shape. The anchorpoint is
|
|||
center of the points that still intersect that plane.
|
||||
|
||||
```openscad-FlatSpin,VPD=500
|
||||
include <BOSL2/std.scad>
|
||||
module stellate_cube(s=100, anchor=CENTER, spin=0, orient=UP) {
|
||||
s2 = 3 * s;
|
||||
verts = [
|
||||
|
@ -929,6 +1009,7 @@ face at the intersection. If the intersection is at an edge or corner, then the
|
|||
will bisect the angles between the faces.
|
||||
|
||||
```openscad-VPD=1250
|
||||
include <BOSL2/std.scad>
|
||||
module stellate_cube(s=100, anchor=CENTER, spin=0, orient=UP) {
|
||||
s2 = 3 * s;
|
||||
verts = [
|
||||
|
@ -956,6 +1037,7 @@ stellate_cube() show_anchors(50);
|
|||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
$fn=32;
|
||||
R = difference(circle(10), right(2, circle(9)));
|
||||
linear_sweep(R,height=10,atype="hull")
|
||||
|
@ -980,6 +1062,7 @@ To make a simple attachable shape similar to a `teardrop()` that provides a "cap
|
|||
define it like this:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module raindrop(r, thick, anchor=CENTER, spin=0, orient=UP) {
|
||||
anchors = [
|
||||
named_anchor("cap", [0,r/sin(45),0], BACK, 0)
|
||||
|
@ -998,6 +1081,7 @@ raindrop(r=25, thick=20, anchor="cap");
|
|||
If you want multiple named anchors, just add them to the list of anchors:
|
||||
|
||||
```openscad-FlatSpin,VPD=150
|
||||
include <BOSL2/std.scad>
|
||||
module raindrop(r, thick, anchor=CENTER, spin=0, orient=UP) {
|
||||
anchors = [
|
||||
named_anchor("captop", [0,r/sin(45), thick/2], BACK+UP, 0),
|
||||
|
|
|
@ -29,6 +29,7 @@ Using `xcopies()`, you can make a line of evenly spaced copies of a shape
|
|||
centered along the X axis. To make a line of 5 spheres, spaced every 20
|
||||
units along the X axis, do:
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
xcopies(20, n=5) sphere(d=10);
|
||||
```
|
||||
Note that the first expected argument to `xcopies()` is the spacing argument,
|
||||
|
@ -38,26 +39,31 @@ Similarly, `ycopies()` makes a line of evenly spaced copies centered along the
|
|||
Y axis. To make a line of 5 spheres, spaced every 20 units along the Y
|
||||
axis, do:
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ycopies(20, n=5) sphere(d=10);
|
||||
```
|
||||
|
||||
And, `zcopies()` makes a line of evenly spaced copies centered along the Z axis.
|
||||
To make a line of 5 spheres, spaced every 20 units along the Z axis, do:
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
zcopies(20, n=5) sphere(d=10);
|
||||
```
|
||||
|
||||
If you don't give the `n=` argument to `xcopies()`, `ycopies()` or `zcopies()`,
|
||||
then it defaults to 2 (two) copies. This actually is the most common usage:
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
xcopies(20) sphere(d=10);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ycopies(20) sphere(d=10);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
zcopies(20) sphere(d=10);
|
||||
```
|
||||
|
||||
|
@ -65,14 +71,17 @@ If you don't know the spacing you want, but instead know how long a line you
|
|||
want the copies distributed over, you can use the `l=` argument instead of
|
||||
the `spacing=` argument:
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
xcopies(l=100, n=5) sphere(d=10);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ycopies(l=100, n=5) sphere(d=10);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
zcopies(l=100, n=5) sphere(d=10);
|
||||
```
|
||||
|
||||
|
@ -80,34 +89,40 @@ If you don't want the line of copies centered on the origin, you can give a
|
|||
starting point `sp=`, and the line of copies will start there. For `xcopies()`,
|
||||
the line of copies will extend to the right of the starting point.
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
xcopies(20, n=5, sp=[0,0,0]) sphere(d=10);
|
||||
```
|
||||
|
||||
For `ycopies()`, the line of copies will extend to the back of the starting point.
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ycopies(20, n=5, sp=[0,0,0]) sphere(d=10);
|
||||
```
|
||||
|
||||
For `zcopies()`, the line of copies will extend upwards from the starting point.
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
zcopies(20, n=5, sp=[0,0,0]) sphere(d=10);
|
||||
```
|
||||
|
||||
If you need to distribute copies along an arbitrary line, you can use the
|
||||
`line_of()` command. You can give both the direction vector and the spacing
|
||||
of the line of copies with the `spacing=` argument:
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
line_of(spacing=(BACK+RIGHT)*20, n=5) sphere(d=10);
|
||||
```
|
||||
|
||||
With the `p1=` argument, you can specify the starting point of the line:
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
line_of(spacing=(BACK+RIGHT)*20, n=5, p1=[0,0,0]) sphere(d=10);
|
||||
```
|
||||
|
||||
If you give both `p1=` and `p2=`, you can nail down both the start and
|
||||
endpoints of the line of copies:
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
line_of(p1=[0,100,0], p2=[100,0,0], n=4)
|
||||
sphere(d=10);
|
||||
```
|
||||
|
@ -115,22 +130,26 @@ line_of(p1=[0,100,0], p2=[100,0,0], n=4)
|
|||
The `grid2d()` command will let you spread copies across both the X and Y
|
||||
axes at the same time:
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
grid2d(20, n=6) sphere(d=10);
|
||||
```
|
||||
|
||||
The spacing can be separately specified for both the X and Y axes, as can
|
||||
the count of rows and columns:
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
grid2d([20,30], n=[6,4]) sphere(d=10);
|
||||
```
|
||||
|
||||
Another neat trick of `grid2d()`, is that you can stagger the output:
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
grid2d(20, n=[12,6], stagger=true) sphere(d=10);
|
||||
```
|
||||
|
||||
You can get the alternate stagger pattern if you set `stagger="alt"`:
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
grid2d(20, n=[12,6], stagger="alt") sphere(d=10);
|
||||
```
|
||||
|
||||
|
@ -139,32 +158,39 @@ you a hexagonal grid, with the spacing being the distance from an item to all
|
|||
six of the surrounding items. If you give the spacing as a 2-item vector,
|
||||
then that will force the X and Y spacings between columns and rows instead.
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
grid2d([20,20], n=6, stagger=true) sphere(d=10);
|
||||
```
|
||||
|
||||
You can alternately specify a grid using size and spacing:
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
grid2d(20, size=100) sphere(d=10);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
grid2d(20, size=[100,80]) sphere(d=10);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
grid2d(20, size=[100,80], stagger=true) sphere(d=10);
|
||||
```
|
||||
|
||||
You can also make grids by specifying size and column/row count:
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
grid2d(n=5, size=100) sphere(d=10);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
grid2d(n=[4,5], size=100) sphere(d=10);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
grid2d(n=[4,5], size=[100,80]) sphere(d=10);
|
||||
```
|
||||
|
||||
|
@ -172,7 +198,8 @@ Finally, the `grid2d()` command will let you give a polygon or region shape
|
|||
to fill with items. Only the items in the grid whose center would be inside
|
||||
the polygon or region will be created. To fill a star shape with items, you
|
||||
can do something like:
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
poly = [for (i=[0:11]) polar_to_xy(50*(i%2+1), i*360/12-90)];
|
||||
grid2d(5, stagger=true, inside=poly) {
|
||||
cylinder(d=4,h=10,spin=90,$fn=6);
|
||||
|
@ -182,7 +209,8 @@ grid2d(5, stagger=true, inside=poly) {
|
|||
|
||||
### Rotational Distributors
|
||||
You can make six copies of a cone, rotated around a center:
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
zrot_copies(n=6) yrot(90) cylinder(h=50,d1=0,d2=20);
|
||||
```
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
Firstoff, include the BOSL2 library, then make a starting module that just has a tapered cylinder for the tree trunk.
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module tree(l=1500, sc=0.7)
|
||||
cylinder(l=l, d1=l/5, d2=l/5*sc);
|
||||
|
@ -17,7 +17,7 @@ tree();
|
|||
|
||||
You can attach a branch to the top of the trunk by using `attach()` as a child of the trunk cylinder.
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module tree(l=1500, sc=0.7)
|
||||
cylinder(l=l, d1=l/5, d2=l/5*sc)
|
||||
|
@ -30,7 +30,7 @@ tree();
|
|||
|
||||
Instead of attaching each branch individually, you can make multiple copies of one branch, that are rotated relative to each other.
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
module tree(l=1500, sc=0.7)
|
||||
cylinder(l=l, d1=l/5, d2=l/5*sc)
|
||||
|
@ -118,3 +118,4 @@ module tree(l=1500, sc=0.7, depth=10)
|
|||
tree();
|
||||
```
|
||||
|
||||
|
||||
|
|
|
@ -6,51 +6,62 @@
|
|||
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:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
left_half() sphere(d=100);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
right_half() sphere(d=100);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
front_half() sphere(d=100);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
back_half() sphere(d=100);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
bottom_half() sphere(d=100);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
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:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
half_of([-1,0,-1]) sphere(d=100);
|
||||
```
|
||||
|
||||
The plane of dissection can be shifted along the axis of any of these operators:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
left_half(x=20) sphere(d=100);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
back_half(y=-20) sphere(d=100);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
bottom_half(z=20) sphere(d=100);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
half_of([-1,0,-1], cp=[20,0,20]) sphere(d=100);
|
||||
```
|
||||
|
||||
|
@ -58,33 +69,39 @@ By default, these operators can be applied to objects that fit in a cube 1000 on
|
|||
to apply these halving operators to objects larger than this, you can give the size in the `s=`
|
||||
argument:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
bottom_half(s=2000) sphere(d=1500);
|
||||
```
|
||||
|
||||
## 2D Plane Halving
|
||||
To cut 2D shapes in half, you will need to add the `planar=true` argument:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
left_half(planar=true) circle(d=100);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
right_half(planar=true) circle(d=100);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
front_half(planar=true) circle(d=100);
|
||||
```
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
back_half(planar=true) circle(d=100);
|
||||
```
|
||||
|
||||
## Chained Mutators
|
||||
If you have a set of shapes that you want to do pair-wise hulling of, you can use `chain_hull()`:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
chain_hull() {
|
||||
cube(5, center=true);
|
||||
translate([30, 0, 0]) sphere(d=15);
|
||||
|
@ -96,20 +113,23 @@ chain_hull() {
|
|||
## Extrusion Mutators
|
||||
The OpenSCAD `linear_extrude()` module can take a 2D shape and extrude it vertically in a line:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
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.
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
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
|
||||
out radially from the center of a cylinder:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylindrical_extrude(or=40, ir=35)
|
||||
text(text="Hello World!", size=10, halign="center", valign="center");
|
||||
```
|
||||
|
@ -120,7 +140,8 @@ cylindrical_extrude(or=40, ir=35)
|
|||
### Minkowski Difference
|
||||
Openscad provides the `minkowski()` module to trace a shape over the entire surface of another shape:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
minkowski() {
|
||||
union() {
|
||||
cube([100,33,33], center=true);
|
||||
|
@ -134,7 +155,8 @@ minkowski() {
|
|||
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:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
minkowski_difference() {
|
||||
union() {
|
||||
cube([100,33,33], center=true);
|
||||
|
@ -148,6 +170,7 @@ minkowski_difference() {
|
|||
To perform a `minkowski_difference()` on 2D shapes, you need to supply the `planar=true` argument:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
minkowski_difference(planar=true) {
|
||||
union() {
|
||||
square([100,33], center=true);
|
||||
|
@ -161,20 +184,24 @@ minkowski_difference(planar=true) {
|
|||
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
|
||||
include <BOSL2/std.scad>
|
||||
round2d(or=8) star(6, step=2, d=100);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
round2d(ir=12) star(6, step=2, d=100);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
round2d(r=8) star(6, step=2, d=100);
|
||||
```
|
||||
|
||||
|
@ -183,6 +210,7 @@ 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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
shell2d(thickness=5) star(5,step=2,d=100);
|
||||
color("blue") stroke(star(5,step=2,d=100),closed=true);
|
||||
```
|
||||
|
@ -190,6 +218,7 @@ color("blue") stroke(star(5,step=2,d=100),closed=true);
|
|||
With a negative thickness, the shell if inset from the original shape:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
shell2d(thickness=-5) star(5,step=2,d=100);
|
||||
color("blue") stroke(star(5,step=2,d=100),closed=true);
|
||||
```
|
||||
|
@ -197,6 +226,7 @@ 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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
shell2d(thickness=[-5,5]) star(5,step=2,d=100);
|
||||
color("blue") stroke(star(5,step=2,d=100),closed=true);
|
||||
```
|
||||
|
@ -204,40 +234,47 @@ 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.
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
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]`:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
shell2d(thickness=-5,or=[5,10]) star(5,step=2,d=100);
|
||||
```
|
||||
|
||||
A radius of 0 can be used to specify no rounding:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
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.
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
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]`:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
shell2d(thickness=-5,or=[7,2],ir=[7,2]) star(5,step=2,d=100);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
shell2d(thickness=-5,or=[5,0],ir=[5,0]) star(5,step=2,d=100);
|
||||
```
|
||||
|
||||
|
@ -252,7 +289,8 @@ The built-in OpenSCAD `color()` module can let you set the RGB color of an objec
|
|||
easier to select colors using other color schemes. You can use the HSL or Hue-Saturation-Lightness
|
||||
color scheme with the `HSL()` module:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
n = 10; size = 100/n;
|
||||
for (a=count(n), b=count(n), c=count(n)) {
|
||||
let( h=360*a/n, s=1-b/(n-1), l=c/(n-1))
|
||||
|
@ -264,7 +302,8 @@ for (a=count(n), b=count(n), c=count(n)) {
|
|||
|
||||
You can use the HSV or Hue-Saturation-Value color scheme with the `HSV()` module:
|
||||
|
||||
```openscad
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
n = 10; size = 100/n;
|
||||
for (a=count(n), b=count(n), c=count(n)) {
|
||||
let( h=360*a/n, s=1-b/(n-1), v=c/(n-1))
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
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 point is a vector of X and Y axis position values. ie: `[3,4]` or `[7,-3]`.
|
||||
- A 3D point is a vector 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.
|
||||
|
@ -18,6 +18,7 @@ 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()`:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
polygon(path);
|
||||
```
|
||||
|
@ -26,6 +27,7 @@ Sometimes, however, it's easier to see just the path itself. For this, you can
|
|||
At its most basic, `stroke()` just shows the path's line segments:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path);
|
||||
```
|
||||
|
@ -33,6 +35,7 @@ stroke(path);
|
|||
You can vary the width of the drawn path with the `width=` argument:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path, width=3);
|
||||
```
|
||||
|
@ -40,6 +43,7 @@ stroke(path, width=3);
|
|||
You can vary the line length along the path by giving a list of widths, one per point:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path, width=[3,2,1,2,3]);
|
||||
```
|
||||
|
@ -47,6 +51,7 @@ 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
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path, closed=true);
|
||||
```
|
||||
|
@ -54,26 +59,31 @@ stroke(path, closed=true);
|
|||
The ends of the drawn path are normally capped with a "round" endcap, but there are other options:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path, endcaps="round");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path, endcaps="butt");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path, endcaps="line");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path, endcaps="tail");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path, endcaps="arrow2");
|
||||
```
|
||||
|
@ -83,16 +93,19 @@ 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=`:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path, endcap1="butt", endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = [[0,0], [-10,10], [0,20], [10,20], [10,10]];
|
||||
stroke(path, endcap1="tail", endcap2="arrow");
|
||||
```
|
||||
|
@ -100,6 +113,7 @@ 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
|
||||
include <BOSL2/std.scad>
|
||||
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");
|
||||
|
@ -114,6 +128,7 @@ line width size.
|
|||
Untrimmed:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
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);
|
||||
|
@ -122,6 +137,7 @@ stroke(path, endcaps=dblarrow);
|
|||
Trimmed:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
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);
|
||||
|
@ -131,36 +147,43 @@ stroke(path, trim=3.5, endcaps=dblarrow);
|
|||
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
|
||||
include <BOSL2/std.scad>
|
||||
path = square(40, center=true);
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = rect([40,30], rounding=5);
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = trapezoid(w1=40, w2=20, h=30);
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = circle(d=50);
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = ellipse(d=[50,30]);
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = pentagon(d=50);
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = star(n=5, step=2, d=50);
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
@ -169,11 +192,13 @@ stroke(path, closed=true, endcap2="arrow2");
|
|||
Often, when you are constructing a path, you will want to add an arc. The `arc()` command lets you do that:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = arc(r=30, angle=120);
|
||||
stroke(path, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = arc(d=60, angle=120);
|
||||
stroke(path, endcap2="arrow2");
|
||||
```
|
||||
|
@ -181,6 +206,7 @@ stroke(path, endcap2="arrow2");
|
|||
If you give the `N=` argument, you can control exactly how many points the arc is divided into:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = arc(N=5, r=30, angle=120);
|
||||
stroke(path, endcap2="arrow2");
|
||||
```
|
||||
|
@ -188,6 +214,7 @@ stroke(path, endcap2="arrow2");
|
|||
With the `start=` argument, you can start the arc somewhere other than the X+ axis:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = arc(start=45, r=30, angle=120);
|
||||
stroke(path, endcap2="arrow2");
|
||||
```
|
||||
|
@ -195,6 +222,7 @@ stroke(path, endcap2="arrow2");
|
|||
Alternatively, you can give starting and ending angles in a list in the `angle=` argument:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = arc(angle=[120,45], r=30);
|
||||
stroke(path, endcap2="arrow2");
|
||||
```
|
||||
|
@ -202,6 +230,7 @@ stroke(path, endcap2="arrow2");
|
|||
The `cp=` argument lets you center the arc somewhere other than the origin:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = arc(cp=[10,0], r=30, angle=120);
|
||||
stroke(path, endcap2="arrow2");
|
||||
```
|
||||
|
@ -209,6 +238,7 @@ stroke(path, endcap2="arrow2");
|
|||
The arc can also be given by three points on the arc:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
pts = [[-15,10],[0,20],[35,-5]];
|
||||
path = arc(points=pts);
|
||||
stroke(path, endcap2="arrow2");
|
||||
|
@ -222,6 +252,7 @@ turtle or cursor walking a path. It can "move" forward or backward, or turn "le
|
|||
place:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = turtle([
|
||||
"move", 10,
|
||||
"left", 90,
|
||||
|
@ -240,6 +271,7 @@ The position and the facing of the turtle/cursor updates after each command. Th
|
|||
commands can also have default distances or angles given:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = turtle([
|
||||
"angle",360/6,
|
||||
"length",10,
|
||||
|
@ -255,6 +287,7 @@ stroke(path, endcap2="arrow2");
|
|||
You can use "scale" to relatively scale up the default motion length:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = turtle([
|
||||
"angle",360/6,
|
||||
"length",10,
|
||||
|
@ -272,6 +305,7 @@ stroke(path, endcap2="arrow2");
|
|||
Sequences of commands can be repeated using the "repeat" command:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path=turtle([
|
||||
"angle",360/5,
|
||||
"length",10,
|
||||
|
@ -283,6 +317,7 @@ stroke(path, endcap2="arrow2");
|
|||
More complicated commands also exist, including those that form arcs:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = turtle([
|
||||
"move", 10,
|
||||
"left", 90,
|
||||
|
@ -299,16 +334,19 @@ 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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = move([-15,-30], p=square(50,center=true));
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = fwd(30, p=square(50,center=true));
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = left(30, p=square(50,center=true));
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
@ -316,16 +354,19 @@ 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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = scale([1.5,0.75], p=square(50,center=true));
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = xscale(1.5, p=square(50,center=true));
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = yscale(1.5, p=square(50,center=true));
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
@ -333,11 +374,13 @@ 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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = rot(30, p=square(50,center=true));
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = zrot(30, p=square(50,center=true));
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
@ -345,16 +388,19 @@ 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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = mirror([1,1], p=trapezoid(w1=40, w2=10, h=25));
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = xflip(p=trapezoid(w1=40, w2=10, h=25));
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
path = yflip(p=trapezoid(w1=40, w2=10, h=25));
|
||||
stroke(path, closed=true, endcap2="arrow2");
|
||||
```
|
||||
|
@ -362,16 +408,19 @@ 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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
mat = move([5,10,0]);
|
||||
multmatrix(mat) square(50,center=true);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
mat = scale([1.5,0.75,1]);
|
||||
multmatrix(mat) square(50,center=true);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
mat = rot(30);
|
||||
multmatrix(mat) square(50,center=true);
|
||||
```
|
||||
|
@ -379,6 +428,7 @@ 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
|
||||
include <BOSL2/std.scad>
|
||||
mat = move([5,10,0]) * rot(30) * scale([1.5,0.75,1]);
|
||||
multmatrix(mat) square(50,center=true);
|
||||
```
|
||||
|
@ -386,6 +436,7 @@ multmatrix(mat) square(50,center=true);
|
|||
To apply a compound transformation matrix to a path, you can use the `apply()` function:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
mat = move([5,10]) * rot(30) * scale([1.5,0.75]);
|
||||
path = square(50,center=true);
|
||||
tpath = apply(mat, path);
|
||||
|
@ -401,6 +452,7 @@ 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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rgn = [square(50,center=true), circle(d=30)];
|
||||
region(rgn);
|
||||
```
|
||||
|
@ -408,6 +460,7 @@ region(rgn);
|
|||
If you have a region with multiple polygons that are not contained by any others, they make multiple discontiguous shapes:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rgn = [
|
||||
move([-30, 20], p=square(20,center=true)),
|
||||
move([ 0,-20], p=trapezoid(w1=20, w2=10, h=20)),
|
||||
|
@ -419,6 +472,7 @@ region(rgn);
|
|||
Region polygons can be nested abitrarily deep, in multiple discontiguous shapes:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rgn = [
|
||||
for (d=[50:-10:10]) left(30, p=circle(d=d)),
|
||||
for (d=[50:-10:10]) right(30, p=circle(d=d))
|
||||
|
@ -429,6 +483,7 @@ region(rgn);
|
|||
A region with crossing polygons is somewhat poorly formed, but the intersection(s) of the polygons become holes:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rgn = [
|
||||
left(15, p=circle(d=50)),
|
||||
right(15, p=circle(d=50))
|
||||
|
@ -441,6 +496,7 @@ Similarly to how OpenSCAD can perform operations like union/difference/intersect
|
|||
the BOSL2 library lets you perform those same operations on regions:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
|
||||
rgn2 = [square([60,12], center=true)];
|
||||
rgn = union(rgn1, rgn2);
|
||||
|
@ -448,6 +504,7 @@ region(rgn);
|
|||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
|
||||
rgn2 = [square([60,12], center=true)];
|
||||
rgn = difference(rgn1, rgn2);
|
||||
|
@ -455,6 +512,7 @@ region(rgn);
|
|||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
|
||||
rgn2 = [square([60,12], center=true)];
|
||||
rgn = intersection(rgn1, rgn2);
|
||||
|
@ -462,6 +520,7 @@ region(rgn);
|
|||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rgn1 = [for (d=[40:-10:10]) circle(d=d)];
|
||||
rgn2 = [square([60,12], center=true)];
|
||||
rgn = exclusive_or(rgn1, rgn2);
|
||||
|
@ -469,6 +528,7 @@ region(rgn);
|
|||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
orig_rgn = [star(n=5, step=2, d=50)];
|
||||
rgn = offset(orig_rgn, r=-3, closed=true);
|
||||
color("blue") region(orig_rgn);
|
||||
|
@ -479,6 +539,7 @@ You can use regions for several useful things. If you wanted a grid of holes in
|
|||
form the shape given by a region, you can do that with `grid2d()`:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
rgn = [
|
||||
circle(d=100),
|
||||
star(n=5,step=2,d=100,spin=90)
|
||||
|
@ -492,6 +553,7 @@ difference() {
|
|||
You can also sweep a region through 3-space to make a solid:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
$fa=1; $fs=1;
|
||||
rgn = [ for (d=[50:-10:10]) circle(d=d) ];
|
||||
tforms = [
|
||||
|
|
|
@ -7,14 +7,17 @@ There are two built-in 2D primitive shapes that OpenSCAD provides: `square()`, a
|
|||
You can still use them in the familiar ways that OpenSCAD provides:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([60,40], center=true);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(r=50);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=100, $fn=8);
|
||||
```
|
||||
|
||||
|
@ -29,18 +32,21 @@ want to align to the origin. For example, to align the center of the back edge
|
|||
origin, set the anchor to `[0,1]`:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([60,40], anchor=[0,1]);
|
||||
```
|
||||
|
||||
To align the front right corner to the origin:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([60,40], anchor=[1,-1]);
|
||||
```
|
||||
|
||||
To center:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([60,40], anchor=[0,0]);
|
||||
```
|
||||
|
||||
|
@ -60,33 +66,39 @@ 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
|
||||
include <BOSL2/std.scad>
|
||||
square([60,40], anchor=BACK);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([60,40], anchor=CENTER);
|
||||
```
|
||||
|
||||
You can add vectors together to point to corners:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([60,40], anchor=FRONT+RIGHT);
|
||||
```
|
||||
|
||||
For `circle()`, the anchor vector can point at any part of the circle perimeter:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50, anchor=polar_to_xy(1,150));
|
||||
```
|
||||
|
||||
You can see the typical anchor points by making `show_anchors()` the child of the shape:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([60,40], center=true)
|
||||
show_anchors();
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50)
|
||||
show_anchors();
|
||||
```
|
||||
|
@ -97,24 +109,28 @@ the shape, you can spin it in place with the `spin=` argument. You just pass it
|
|||
degrees to rotate clockwise:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([60,40], anchor=CENTER, spin=30);
|
||||
```
|
||||
|
||||
Anchoring or centering is performed before the spin:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([60,40], anchor=BACK, spin=30);
|
||||
```
|
||||
|
||||
For circles, spin can be useful when `$fn=` is also given:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50, $fn=6, spin=15);
|
||||
```
|
||||
|
||||
Since anchoring is performed before spin, you can use them together to spin around the anchor:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50, $fn=6, anchor=LEFT, spin=15);
|
||||
```
|
||||
|
||||
|
@ -127,11 +143,13 @@ you want to attach to. By default, just making one shape a child of the other w
|
|||
the child shape at the center of the parent shape.
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square(50, center=true)
|
||||
#square(50, spin=45, center=true);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square(50, center=true)
|
||||
#square([20,40], anchor=FWD);
|
||||
```
|
||||
|
@ -139,18 +157,21 @@ square(50, center=true)
|
|||
By adding the `position()` module, you can position the child at any anchorpoint on the parent:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square(50, center=true)
|
||||
position(BACK)
|
||||
#square(25, spin=45, center=true);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square(50, center=true)
|
||||
position(FWD+RIGHT)
|
||||
#square(25, spin=45, center=true);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50)
|
||||
position(polar_to_xy(1,60))
|
||||
#circle(d=10);
|
||||
|
@ -162,11 +183,13 @@ cases, the orientation of an anchorpoint is outward away from the face of the wa
|
|||
from the center of the shape. You can see this with the `show_anchors()` module:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square(50, center=true)
|
||||
show_anchors();
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50)
|
||||
show_anchors();
|
||||
```
|
||||
|
@ -175,24 +198,28 @@ If you want to orient the child to match the orientation of an anchorpoint, you
|
|||
module. It does not position the child. It only rotates it:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square(50, center=true)
|
||||
orient(anchor=LEFT)
|
||||
#square([10,40], anchor=FWD);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square(50, center=true)
|
||||
orient(anchor=FWD)
|
||||
#square([10,40], anchor=FWD);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square(50, center=true)
|
||||
orient(anchor=RIGHT)
|
||||
#square([10,40], anchor=FWD);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50)
|
||||
orient(polar_to_xy(1,30))
|
||||
#square([10,40], anchor=FWD);
|
||||
|
@ -201,6 +228,7 @@ circle(d=50)
|
|||
You can use `position()` and `orient()` together to both position and orient to an anchorpoint:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square(50, center=true)
|
||||
position(RIGHT+BACK)
|
||||
orient(anchor=RIGHT+BACK)
|
||||
|
@ -208,6 +236,7 @@ square(50, center=true)
|
|||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50)
|
||||
position(polar_to_xy(1,30))
|
||||
orient(polar_to_xy(1,30))
|
||||
|
@ -217,12 +246,14 @@ circle(d=50)
|
|||
But it's simpler to just use the `attach()` module to do both at once:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square(50, center=true)
|
||||
attach(LEFT+BACK)
|
||||
#square([10,40], anchor=FWD);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50)
|
||||
attach(polar_to_xy(1,30))
|
||||
#square([10,40], center=true);
|
||||
|
@ -232,12 +263,14 @@ Instead of specifying the `anchor=` in the child, you can pass a second argument
|
|||
that tells it which side of the child to attach to the parent:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
square([10,50], center=true)
|
||||
attach(BACK, LEFT)
|
||||
#square([10,40], center=true);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50)
|
||||
attach(polar_to_xy(1,30), LEFT)
|
||||
#square([10,40], center=true);
|
||||
|
@ -252,12 +285,14 @@ called `rect()`. You can use it in the same way you use `square()`, but it also
|
|||
extended functionality. For example, it allows you to round the corners:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rect([60,40], rounding=10);
|
||||
```
|
||||
|
||||
Or chamfer them:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rect([60,40], chamfer=10);
|
||||
```
|
||||
|
||||
|
@ -268,6 +303,7 @@ 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
|
||||
include <BOSL2/std.scad>
|
||||
module text3d(text) color("black") text(
|
||||
text=text, font="Times", size=10,
|
||||
halign="center", valign="center"
|
||||
|
@ -283,10 +319,12 @@ If a size is given as `0`, then there is no rounding and/or chamfering for
|
|||
that quadrant's corner:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rect([60,40], rounding=[0,5,10,15]);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rect([60,40], chamfer=[0,5,10,15]);
|
||||
```
|
||||
|
||||
|
@ -295,6 +333,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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
rect([60,40], rounding=[5,0,10,0], chamfer=[0,5,0,15]);
|
||||
```
|
||||
|
||||
|
@ -312,6 +351,7 @@ The `realign=` argument, if set `true`, rotates the `ellipse()` by half the angl
|
|||
between the polygon sides:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ellipse(d=100, $fn=8);
|
||||
#ellipse(d=100, $fn=8, realign=true);
|
||||
```
|
||||
|
@ -322,6 +362,7 @@ The `circum=` argument, if true, makes it so that the polygon forming the
|
|||
Inscribing the ideal circle:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
color("green") ellipse(d=100, $fn=360);
|
||||
ellipse(d=100, $fn=6);
|
||||
```
|
||||
|
@ -329,6 +370,7 @@ ellipse(d=100, $fn=6);
|
|||
Circumscribing the ideal circle:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ellipse(d=100, $fn=6, circum=true);
|
||||
color("green") ellipse(d=100, $fn=360);
|
||||
```
|
||||
|
@ -338,24 +380,29 @@ or diameters. To do this, just give `r=` or `d=` with a list of two radii or
|
|||
diameters:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ellipse(r=[30,20]);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ellipse(d=[60,40]);
|
||||
```
|
||||
|
||||
Like `circle()`, you can anchor, spin and attach `ellipse()` shapes:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ellipse(d=50, anchor=BACK);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ellipse(d=50, anchor=FRONT+RIGHT);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
ellipse(d=50)
|
||||
attach(BACK+RIGHT, FRONT+LEFT)
|
||||
ellipse(d=30);
|
||||
|
@ -366,36 +413,43 @@ ellipse(d=50)
|
|||
The BOSL2 library provides a simple way to make a 2D right triangle by using the `right_triangle()` module:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
right_triangle([40,30]);
|
||||
```
|
||||
|
||||
You can use `xflip()` and `yflip()` to change which quadrant the triangle is formed in:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
xflip() right_triangle([40,30]);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
yflip() right_triangle([40,30]);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
xflip() yflip() right_triangle([40,30]);
|
||||
```
|
||||
|
||||
Or, alternatively, just rotate it into the correct quadrant with `spin=`:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
right_triangle([40,30], spin=90);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
right_triangle([40,30], spin=-90);
|
||||
```
|
||||
|
||||
You can also use anchoring with right triangles:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
right_triangle([40,30], anchor=FWD+RIGHT);
|
||||
```
|
||||
|
||||
|
@ -408,42 +462,50 @@ 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
|
||||
include <BOSL2/std.scad>
|
||||
trapezoid(w1=50, w2=0, h=40);
|
||||
```
|
||||
|
||||
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
|
||||
include <BOSL2/std.scad>
|
||||
trapezoid(w1=50, w2=0, h=50, shift=-25);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
trapezoid(w1=50, w2=0, h=50, shift=25);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
trapezoid(w1=0, w2=50, h=50, shift=-25);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
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
|
||||
include <BOSL2/std.scad>
|
||||
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
|
||||
include <BOSL2/std.scad>
|
||||
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
|
||||
include <BOSL2/std.scad>
|
||||
trapezoid(w1=50, w2=30, shift=20, h=50);
|
||||
```
|
||||
|
||||
|
@ -451,6 +513,7 @@ You can use `anchor=` and `spin=`, just like with other attachable shapes. Howe
|
|||
point orientations are based on the side angles of the faces, and may not be what you expect:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
trapezoid(w1=30, w2=50, h=50)
|
||||
show_anchors();
|
||||
```
|
||||
|
@ -461,36 +524,43 @@ 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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
circle(d=50, $fn=5);
|
||||
```
|
||||
|
||||
The BOSL2 library has modules that are named more clearly, for common N-gons:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
pentagon(d=50);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
hexagon(d=50);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
octagon(d=50);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
regular_ngon(n=7, d=50);
|
||||
```
|
||||
|
||||
These modules also provide you with extra functionality. They can be sized by side length:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
pentagon(side=20);
|
||||
```
|
||||
|
||||
They can be sized by circumscribed circle radius/diameter:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
pentagon(ir=25);
|
||||
pentagon(id=50);
|
||||
```
|
||||
|
@ -498,6 +568,7 @@ pentagon(id=50);
|
|||
They can be rotated by half a side:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
left(30) pentagon(d=50, realign=true);
|
||||
right(30) pentagon(d=50, realign=false);
|
||||
```
|
||||
|
@ -505,10 +576,12 @@ right(30) pentagon(d=50, realign=false);
|
|||
They can be rounded:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
pentagon(d=50, rounding=10);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
hexagon(d=50, rounding=10);
|
||||
```
|
||||
|
||||
|
@ -516,6 +589,7 @@ They also have somewhat different attachment behavior. A circle with a small `$
|
|||
attach things at the ideal circle, not along the created polygon:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
color("green") stroke(circle(d=50), closed=true);
|
||||
circle(d=50,$fn=6)
|
||||
show_anchors();
|
||||
|
@ -524,6 +598,7 @@ circle(d=50,$fn=6)
|
|||
While an N-gon will attach along the polygon itself:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
hexagon(d=50)
|
||||
show_anchors(custom=false);
|
||||
```
|
||||
|
@ -533,6 +608,7 @@ points are based on where the anchor vector would intersect the side of the N-go
|
|||
be where you expect them:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
pentagon(d=50)
|
||||
show_anchors(custom=false);
|
||||
```
|
||||
|
@ -540,6 +616,7 @@ pentagon(d=50)
|
|||
N-gons also have named anchor points for their sides and tips:
|
||||
|
||||
```openscad-2D,Med
|
||||
include <BOSL2/std.scad>
|
||||
pentagon(d=30)
|
||||
show_anchors(std=false);
|
||||
```
|
||||
|
@ -551,30 +628,36 @@ 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:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
star(n=3, id=10, d=50);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
star(n=5, id=15, r=25);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
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
|
||||
include <BOSL2/std.scad>
|
||||
star(n=7, step=2, d=50);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
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
|
||||
include <BOSL2/std.scad>
|
||||
left(30) star(n=5, step=2, d=50);
|
||||
right(30) star(n=5, step=2, d=50, realign=true);
|
||||
```
|
||||
|
@ -582,11 +665,13 @@ 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
|
||||
include <BOSL2/std.scad>
|
||||
star(n=5, ir=15, or=30, align_tip=BACK)
|
||||
attach("tip0") color("blue") anchor_arrow2d();
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
star(n=5, ir=15, or=30, align_tip=BACK+RIGHT)
|
||||
attach("tip0") color("blue") anchor_arrow2d();
|
||||
```
|
||||
|
@ -595,11 +680,13 @@ Similarly, the first indentation or pit can be oriented towards a specific vecto
|
|||
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
star(n=5, ir=15, or=30, align_pit=BACK)
|
||||
attach("pit0") color("blue") anchor_arrow2d();
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
star(n=5, ir=15, or=30, align_pit=BACK+RIGHT)
|
||||
attach("pit0") color("blue") anchor_arrow2d();
|
||||
```
|
||||
|
@ -608,6 +695,7 @@ You can use `anchor=` and `spin=`, just like with other attachable shapes. Howe
|
|||
points are based on the furthest extents of the shape, and may not be where you expect them:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
star(n=5, step=2, d=50)
|
||||
show_anchors(custom=false);
|
||||
```
|
||||
|
@ -615,6 +703,7 @@ star(n=5, step=2, d=50)
|
|||
Stars also have named anchor points for their pits, tips, and midpoints between tips:
|
||||
|
||||
```openscad-2D,Med
|
||||
include <BOSL2/std.scad>
|
||||
star(n=5, step=2, d=40)
|
||||
show_anchors(std=false);
|
||||
```
|
||||
|
@ -630,16 +719,19 @@ The `teardrop2d()` module will let you make a 2D version of the teardrop shape,
|
|||
extrude it later:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
teardrop2d(r=20);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
teardrop2d(d=50);
|
||||
```
|
||||
|
||||
The default overhang angle is 45 degrees, but you can adjust that with the `ang=` argument:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
teardrop2d(d=50, ang=30);
|
||||
```
|
||||
|
||||
|
@ -647,10 +739,12 @@ If you prefer to flatten the top of the teardrop, to encourage bridging, you can
|
|||
argument:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
teardrop2d(d=50, cap_h=25);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
teardrop2d(d=50, ang=30, cap_h=30);
|
||||
```
|
||||
|
||||
|
@ -658,6 +752,7 @@ You can use `anchor=` and `spin=`, just like with other attachable shapes. Howe
|
|||
points are based on the furthest extents of the shape, and may not be where you expect them:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
teardrop2d(d=50, ang=30, cap_h=30)
|
||||
show_anchors();
|
||||
```
|
||||
|
@ -669,46 +764,55 @@ A more unusal shape that BOSL2 provides is Glued Circles. It's basically a pair
|
|||
connected by what looks like a gloopy glued miniscus:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
glued_circles(d=30, spread=40);
|
||||
```
|
||||
|
||||
The `r=`/`d=` arguments can specify the radius or diameter of the two circles:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
glued_circles(r=20, spread=45);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
glued_circles(d=40, spread=45);
|
||||
```
|
||||
|
||||
The `spread=` argument specifies the distance between the centers of the two circles:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
glued_circles(d=30, spread=30);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
glued_circles(d=30, spread=40);
|
||||
```
|
||||
|
||||
The `tangent=` argument gives the angle of the tangent of the meniscus on the two circles:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
glued_circles(d=30, spread=30, tangent=45);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
glued_circles(d=30, spread=30, tangent=20);
|
||||
```
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
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
|
||||
include <BOSL2/std.scad>
|
||||
$fn=36; s=10;
|
||||
linear_extrude(height=50,convexity=16,center=true)
|
||||
xcopies(s*sqrt(2),n=3)
|
||||
|
@ -719,6 +823,7 @@ You can use `anchor=` and `spin=`, just like with other attachable shapes. Howe
|
|||
points are based on the furthest extents of the shape, and may not be where you expect them:
|
||||
|
||||
```openscad-2D
|
||||
include <BOSL2/std.scad>
|
||||
glued_circles(d=40, spread=40, tangent=45)
|
||||
show_anchors();
|
||||
```
|
||||
|
|
|
@ -12,14 +12,17 @@ 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:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(100);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube(100, center=true);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], center=true);
|
||||
```
|
||||
|
||||
|
@ -30,20 +33,24 @@ except you can also anchor vertically in 3D, allowing anchoring to faces, edges,
|
|||
and corners:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], anchor=BOTTOM);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], anchor=TOP+BACK);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], anchor=TOP+FRONT+LEFT);
|
||||
```
|
||||
|
||||
You can use `spin=` to rotate around the Z axis:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], anchor=FRONT, spin=30);
|
||||
```
|
||||
|
||||
|
@ -52,6 +59,7 @@ 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()`:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], anchor=FRONT, spin=[15,0,30]);
|
||||
```
|
||||
|
||||
|
@ -59,6 +67,7 @@ cube([50,40,20], anchor=FRONT, spin=[15,0,30]);
|
|||
to where the top of the shape should be rotated towards.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], orient=UP+BACK+RIGHT);
|
||||
```
|
||||
|
||||
|
@ -66,14 +75,17 @@ If you use `anchor=`, `spin=`, and `orient=` together, the anchor is performed
|
|||
first, then the spin, then the orient:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], anchor=FRONT);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], anchor=FRONT, spin=45);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cube([50,40,20], anchor=FRONT, spin=45, orient=UP+FWD+RIGHT);
|
||||
```
|
||||
|
||||
|
@ -84,12 +96,14 @@ except that `cuboid()` centers by default.
|
|||
You can round the edges with the `rounding=` argument:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=20);
|
||||
```
|
||||
|
||||
Similarly, you can chamfer the edges with the `chamfer=` argument:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], chamfer=10);
|
||||
```
|
||||
|
||||
|
@ -98,10 +112,12 @@ 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:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=20, edges=TOP);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=20, edges=RIGHT);
|
||||
```
|
||||
|
||||
|
@ -109,20 +125,24 @@ If you give `edges=` a vector pointing at a corner, it will round all edges
|
|||
that meet at that corner:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=20, edges=RIGHT+FRONT+TOP);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
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:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=10, edges=FRONT+TOP);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=10, edges=RIGHT+FRONT);
|
||||
```
|
||||
|
||||
|
@ -130,14 +150,17 @@ If you give the string "X", "Y", or "Z", then all edges aligned with the specifi
|
|||
axis will be rounded:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=10, edges="X");
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=10, edges="Y");
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=10, edges="Z");
|
||||
```
|
||||
|
||||
|
@ -145,6 +168,7 @@ If you give a list of edge specs, then all edges referenced in the list will
|
|||
be rounded:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=10, edges=[TOP,"Z",BOTTOM+RIGHT]);
|
||||
```
|
||||
|
||||
|
@ -152,6 +176,7 @@ 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:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=10, except_edges=BOTTOM+RIGHT);
|
||||
```
|
||||
|
||||
|
@ -159,18 +184,21 @@ You can give the `except_edges=` argument any type of argument that you can
|
|||
give to `edges=`:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=10, except_edges=[BOTTOM,"Z",TOP+RIGHT]);
|
||||
```
|
||||
|
||||
You can give both `edges=` and `except_edges=`, to simplify edge specs:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], rounding=10, edges=[TOP,FRONT], except_edges=TOP+FRONT);
|
||||
```
|
||||
|
||||
You can specify what edges to chamfer similarly:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cuboid([100,80,60], chamfer=10, edges=[TOP,FRONT], except_edges=TOP+FRONT);
|
||||
```
|
||||
|
||||
|
@ -180,36 +208,44 @@ BOSL2 overrides the built-in `cylinder()` module. It still can be used as you
|
|||
expect from the built-in:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(r=50,h=50);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(r=50,h=50,center=true);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(d=100,h=50,center=true);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(d1=100,d2=80,h=50,center=true);
|
||||
```
|
||||
|
||||
You can also anchor, spin, orient, and attach like the `cuboid()` module:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(r=50, h=50, anchor=TOP+FRONT);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(r=50, h=50, anchor=BOTTOM+LEFT);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(r=50, h=50, anchor=BOTTOM+LEFT, spin=30);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cylinder(r=50, h=50, anchor=BOTTOM, orient=UP+BACK+RIGHT);
|
||||
```
|
||||
|
||||
|
@ -219,54 +255,65 @@ rounding and chamfering of edges. You can use it similarly to `cylinder()`,
|
|||
except that `cyl()` centers the cylinder by default.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cyl(r=60, l=100);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cyl(d=100, l=100);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cyl(d=100, l=100, anchor=TOP);
|
||||
```
|
||||
|
||||
You can round the edges with the `rounding=` argument:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cyl(d=100, l=100, rounding=20);
|
||||
```
|
||||
|
||||
Similarly, you can chamfer the edges with the `chamfer=` argument:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cyl(d=100, l=100, chamfer=10);
|
||||
```
|
||||
|
||||
You can specify rounding and chamfering for each end individually:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cyl(d=100, l=100, rounding1=20);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cyl(d=100, l=100, rounding2=20);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cyl(d=100, l=100, chamfer1=10);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cyl(d=100, l=100, chamfer2=10);
|
||||
```
|
||||
|
||||
You can even mix and match rounding and chamfering:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cyl(d=100, l=100, rounding1=20, chamfer2=10);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
cyl(d=100, l=100, rounding2=20, chamfer1=10);
|
||||
```
|
||||
|
||||
|
@ -276,10 +323,12 @@ BOSL2 overrides the built-in `sphere()` module. It still can be used as you
|
|||
expect from the built-in:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
sphere(r=50);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
sphere(d=100);
|
||||
```
|
||||
|
||||
|
@ -287,14 +336,17 @@ You can anchor, spin, and orient `sphere()`s, much like you can with `cylinder()
|
|||
and `cube()`:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
sphere(d=100, anchor=FRONT);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
sphere(d=100, anchor=FRONT, spin=30);
|
||||
```
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
sphere(d=100, anchor=BOTTOM, orient=RIGHT+TOP);
|
||||
```
|
||||
|
||||
|
@ -305,6 +357,7 @@ You can use the `circum=true` argument to force the sphere to circumscribe the
|
|||
ideal sphere, as opposed to the default inscribing:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
spheroid(d=100, circum=true);
|
||||
```
|
||||
|
||||
|
@ -312,6 +365,7 @@ The `style=` argument can choose the way that the sphere will be constructed:
|
|||
The "orig" style matches the `sphere()` built-in's construction.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
spheroid(d=100, style="orig", $fn=20);
|
||||
```
|
||||
|
||||
|
@ -319,12 +373,14 @@ The "aligned" style will ensure that there is a vertex at each axis extrema,
|
|||
so long as `$fn` is a multiple of 4.
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
spheroid(d=100, style="aligned", $fn=20);
|
||||
```
|
||||
|
||||
The "stagger" style will stagger the triangulation of the vertical rows:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
spheroid(d=100, style="stagger", $fn=20);
|
||||
```
|
||||
|
||||
|
@ -333,6 +389,7 @@ 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
|
||||
include <BOSL2/std.scad>
|
||||
spheroid(d=100, style="icosa", $fn=20);
|
||||
```
|
||||
|
||||
|
@ -342,6 +399,7 @@ guarantees vertices at the axis extrema. This style will round the effective `$
|
|||
to a multiple of 4 when constructing the spheroid:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
spheroid(d=100, style="octa", $fn=20);
|
||||
```
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
## Translation
|
||||
The `translate()` command is very simple:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#sphere(d=20);
|
||||
translate([0,0,30]) sphere(d=20);
|
||||
```
|
||||
|
@ -14,31 +15,37 @@ 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.
|
||||
These shortcuts are `up()`, `down()`, `fwd()`, `back()`, `left()`, and `right()`:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#sphere(d=20);
|
||||
up(30) sphere(d=20);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#sphere(d=20);
|
||||
down(30) sphere(d=20);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#sphere(d=20);
|
||||
fwd(30) sphere(d=20);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#sphere(d=20);
|
||||
back(30) sphere(d=20);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#sphere(d=20);
|
||||
left(30) sphere(d=20);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#sphere(d=20);
|
||||
right(30) sphere(d=20);
|
||||
```
|
||||
|
@ -46,11 +53,13 @@ right(30) sphere(d=20);
|
|||
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:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#sphere(d=20);
|
||||
move([30,-10]) sphere(d=20);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#sphere(d=20);
|
||||
move(x=30,y=10) sphere(d=20);
|
||||
```
|
||||
|
@ -59,22 +68,27 @@ move(x=30,y=10) sphere(d=20);
|
|||
## Scaling
|
||||
The `scale()` command is also fairly simple:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
scale(2) cube(10, center=true);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
scale([1,2,3]) cube(10, center=true);
|
||||
```
|
||||
|
||||
If you want to only change the scaling on one axis, though, BOSL2 provides clearer
|
||||
commands to do just that; `xscale()`, `yscale()`, and `zscale()`:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
xscale(2) cube(10, center=true);
|
||||
```
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
yscale(2) cube(10, center=true);
|
||||
```
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
zscale(2) cube(10, center=true);
|
||||
```
|
||||
|
||||
|
@ -82,31 +96,37 @@ zscale(2) cube(10, center=true);
|
|||
## Rotation
|
||||
The `rotate()` command is fairly straightforward:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
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.
|
||||
BOSL2 provides shortcuts for rotating around each axis, for clarity; `xrot()`, `yrot()`, and `zrot()`:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
xrot(30) cube(20, center=true);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
yrot(30) cube(20, center=true);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
zrot(30) cube(20, center=true);
|
||||
```
|
||||
|
||||
The `rot()` command is a more generic rotation command, and shorter to type than `rotate()`:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
rot([0,30,15]) cube(20, center=true);
|
||||
```
|
||||
|
||||
All of the rotation shortcuts can take a `cp=` argument, that lets you specify a
|
||||
centerpoint to rotate around:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
cp = [0,0,40];
|
||||
color("blue") move(cp) sphere(d=3);
|
||||
#cube(20, center=true);
|
||||
|
@ -114,6 +134,7 @@ xrot(45, cp=cp) cube(20, center=true);
|
|||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
cp = [0,0,40];
|
||||
color("blue") move(cp) sphere(d=3);
|
||||
#cube(20, center=true);
|
||||
|
@ -121,6 +142,7 @@ yrot(45, cp=cp) cube(20, center=true);
|
|||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
cp = [0,40,0];
|
||||
color("blue") move(cp) sphere(d=3);
|
||||
#cube(20, center=true);
|
||||
|
@ -130,6 +152,7 @@ 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 give these directions using vectors:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#cylinder(d=10, h=50);
|
||||
rot(from=[0,0,1], to=[1,0,1]) cylinder(d=10, h=50);
|
||||
```
|
||||
|
@ -150,6 +173,7 @@ Constant | Value | Direction
|
|||
|
||||
This lets you rewrite the above vector rotation more clearly as:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#cylinder(d=10, h=50);
|
||||
rot(from=UP, to=UP+RIGHT) cylinder(d=10, h=50);
|
||||
```
|
||||
|
@ -158,40 +182,47 @@ rot(from=UP, to=UP+RIGHT) cylinder(d=10, h=50);
|
|||
## Mirroring
|
||||
The standard `mirror()` command works like this:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#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()`:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#yrot(60) cylinder(h=50, d1=20, d2=10);
|
||||
xflip() yrot(60) cylinder(h=50, d1=20, d2=10);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#xrot(60) cylinder(h=50, d1=20, d2=10);
|
||||
yflip() xrot(60) cylinder(h=50, d1=20, d2=10);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#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:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#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);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#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);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
#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);
|
||||
|
@ -209,26 +240,32 @@ a multiplier of `0.5`, then for each unit further along the Y axis you get,
|
|||
you will add `0.5` units of skew to the X axis. Giving a negative multiplier
|
||||
reverses the direction it skews:
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
skew(sxy=0.5) cube(10,center=false);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
skew(sxz=-0.5) cube(10,center=false);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
skew(syx=-0.5) cube(10,center=false);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
skew(syz=0.5) cube(10,center=false);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
skew(szx=-0.5) cube(10,center=false);
|
||||
```
|
||||
|
||||
```openscad
|
||||
include <BOSL2/std.scad>
|
||||
skew(szy=0.5) cube(10,center=false);
|
||||
```
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
The acronym VNF stands for Vertices 'N' Faces. You have probably already come across the concept of vertices and faces when working with the OpenSCAD built-in module `polyhedron()`. A `polyhedron()` in it's simplest form takes two arguments, the first being a list of vertices, and the second a list of faces, where each face is a lists of indices into the list of vertices. For example, to make a cube, you can do:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
verts = [
|
||||
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
|
||||
[-1,-1, 1], [1,-1, 1], [1,1, 1], [-1,1, 1]
|
||||
|
@ -26,6 +27,7 @@ A VNF structure (usually just called a VNF) is just a two item list where the fi
|
|||
The equivalent to the `polyhedron()` module that takes a VNF instead is `vnf_polyhedron()`. To make the same cube as a VNF, you can do it like:
|
||||
|
||||
```openscad-3D
|
||||
include <BOSL2/std.scad>
|
||||
vnf = [
|
||||
[
|
||||
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
|
||||
|
@ -49,6 +51,7 @@ A VNF does not have to contain a complete polyhedron, and the vertices contained
|
|||
As an example, consider a roughly spherical polyhedron with vertices at the top and bottom poles. You can break it down into three major parts: The top cap, the bottom cap, and the side wall. The top and bottom caps both have a ring of vertices linked to the top or bottom vertex in triangles, while the sides are multiple rings of vertices linked in squares. Lets create the top cap first:
|
||||
|
||||
```openscad-3D,ThrownTogether
|
||||
include <BOSL2/std.scad>
|
||||
cap_vnf = [
|
||||
[[0,0,1], for (a=[0:30:359.9]) spherical_to_xyz(1,a,30)], // Vertices
|
||||
[for (i=[1:12]) [0, i%12+1, i]] // Faces
|
||||
|
@ -59,6 +62,7 @@ vnf_polyhedron(cap_vnf);
|
|||
The bottom cap is exactly the same, just mirrored:
|
||||
|
||||
```openscad-3D,ThrownTogether
|
||||
include <BOSL2/std.scad>
|
||||
cap_vnf = [
|
||||
[[0,0,1], for (a=[0:30:359.9]) spherical_to_xyz(1,a,30)], // Vertices
|
||||
[for (i=[1:12]) [0, i%12+1, i]] // Faces
|
||||
|
@ -70,6 +74,7 @@ vnf_polyhedron(cap_vnf2);
|
|||
To create the sides, we can make use of the `vnf_vertex_array()` function to turn a row-column grid of vertices into a VNF. The `col_wrap=true` argument tells it to connect the vertices of the last column to the vertices of the first column. The `caps=false` argument tells it that we don't want it to create caps for the ends of the first and last rows:
|
||||
|
||||
```openscad-3D,ThrownTogether
|
||||
include <BOSL2/std.scad>
|
||||
wall_vnf = vnf_vertex_array(
|
||||
points=[
|
||||
for (phi = [30:30:179.9]) [
|
||||
|
@ -85,6 +90,7 @@ vnf_polyhedron(wall_vnf);
|
|||
Putting all the parts together with `vnf_join()`, we get:
|
||||
|
||||
```openscad-3D,ThrownTogether
|
||||
include <BOSL2/std.scad>
|
||||
cap_vnf = [
|
||||
[[0,0,1], for (a=[0:30:359.9]) spherical_to_xyz(1,a,30)], // Vertices
|
||||
[for (i=[1:12]) [0, i%12+1, i]] // Faces
|
||||
|
@ -110,6 +116,7 @@ Which is now a complete manifold polyhedron.
|
|||
One of the critical tasks in creating a polyhedron is making sure that all of your faces are facing the correct way. This is also true for VNFs. The best way to find reversed faces is simply to select the View→Thrown Together menu item in OpenSCAD while viewing your polyhedron or VNF. Any purple faces are reversed, and you will need to fix them. For example, one of the two top face triangles on this cube is reversed:
|
||||
|
||||
```openscad-3D,ThrownTogether
|
||||
include <BOSL2/std.scad>
|
||||
vnf = [
|
||||
[
|
||||
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
|
||||
|
@ -131,6 +138,7 @@ Another way to find problems with your VNF, is to use the `vnf_validate()` modul
|
|||
|
||||
|
||||
```openscad-3D,ThrownTogether
|
||||
include <BOSL2/std.scad>
|
||||
vnf = [
|
||||
[
|
||||
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
|
||||
|
@ -157,6 +165,7 @@ ECHO: "ERROR REVERSAL (violet): Faces Reverse Across Edge at [[1, 1, 1], [-1, -1
|
|||
The `vnf_validate()` module will stop after displaying the first found problem type, so once you fix those issues, you will want to run it again to display any other remaining issues. For example, the reversed face in the above example is hiding a non-manifold hole in the front face:
|
||||
|
||||
```openscad-3D,ThrownTogether
|
||||
include <BOSL2/std.scad>
|
||||
vnf = [
|
||||
[
|
||||
[-1,-1,-1], [1,-1,-1], [1,1,-1], [-1,1,-1],
|
||||
|
|
Loading…
Reference in a new issue