1# Mutators Tutorial
2
3<!-- TOC -->
4
5## 3D Space Halving
6Sometimes you want to take a 3D shape like a sphere, and cut it in half.
7The BOSL2 library provides a number of ways to do this:
8
9```openscad-3D
10include <BOSL2/std.scad>
11left_half() sphere(d=100);
12```
13
14```openscad-3D
15include <BOSL2/std.scad>
16right_half() sphere(d=100);
17```
18
19```openscad-3D
20include <BOSL2/std.scad>
21front_half() sphere(d=100);
22```
23
24```openscad-3D
25include <BOSL2/std.scad>
26back_half() sphere(d=100);
27```
28
29```openscad-3D
30include <BOSL2/std.scad>
31bottom_half() sphere(d=100);
32```
33
34```openscad-3D
35include <BOSL2/std.scad>
36top_half() sphere(d=100);
37```
38
39You can use the `half_of()` module if you want to split space in a way not aligned with an axis:
40
41```openscad-3D
42include <BOSL2/std.scad>
43half_of([-1,0,-1]) sphere(d=100);
44```
45
46The plane of dissection can be shifted along the axis of any of these operators:
47
48```openscad-3D
49include <BOSL2/std.scad>
50left_half(x=20) sphere(d=100);
51```
52
53```openscad-3D
54include <BOSL2/std.scad>
55back_half(y=-20) sphere(d=100);
56```
57
58```openscad-3D
59include <BOSL2/std.scad>
60bottom_half(z=20) sphere(d=100);
61```
62
63```openscad-3D
64include <BOSL2/std.scad>
65half_of([-1,0,-1], cp=[20,0,20]) sphere(d=100);
66```
67
68By default, these operators can be applied to objects that fit in a cube 1000 on a side. If you need
69to apply these halving operators to objects larger than this, you can give the size in the `s=`
70argument:
71
72```openscad-3D
73include <BOSL2/std.scad>
74bottom_half(s=2000) sphere(d=1500);
75```
76
77## 2D Plane Halving
78To cut 2D shapes in half, you will need to add the `planar=true` argument:
79
80```openscad-3D
81include <BOSL2/std.scad>
82left_half(planar=true) circle(d=100);
83```
84
85```openscad-3D
86include <BOSL2/std.scad>
87right_half(planar=true) circle(d=100);
88```
89
90```openscad-3D
91include <BOSL2/std.scad>
92front_half(planar=true) circle(d=100);
93```
94
95```openscad-3D
96include <BOSL2/std.scad>
97back_half(planar=true) circle(d=100);
98```
99
100## Chained Mutators
101If you have a set of shapes that you want to do pair-wise hulling of, you can use `chain_hull()`:
102
103```openscad-3D
104include <BOSL2/std.scad>
105chain_hull() {
106 cube(5, center=true);
107 translate([30, 0, 0]) sphere(d=15);
108 translate([60, 30, 0]) cylinder(d=10, h=20);
109 translate([60, 60, 0]) cube([10,1,20], center=false);
110}
111```
112
113## Extrusion Mutators
114The OpenSCAD `linear_extrude()` module can take a 2D shape and extrude it vertically in a line:
115
116```openscad-3D
117include <BOSL2/std.scad>
118linear_extrude(height=30) zrot(45) square(40,center=true);
119```
120
121The `rotate_extrude()` module can take a 2D shape and rotate it around the Z axis.
122
123```openscad-3D
124include <BOSL2/std.scad>
125linear_extrude(height=30) left(30) zrot(45) square(40,center=true);
126```
127
128In a similar manner, the BOSL2 `cylindrical_extrude()` module can take a 2d shape and extrude it
129out radially from the center of a cylinder:
130
131```openscad-3D
132include <BOSL2/std.scad>
133cylindrical_extrude(or=40, ir=35)
134 text(text="Hello World!", size=10, halign="center", valign="center");
135```
136
137
138## Offset Mutators
139
140### Minkowski Difference
141Openscad provides the `minkowski()` module to trace a shape over the entire surface of another shape:
142
143```openscad-3D
144include <BOSL2/std.scad>
145minkowski() {
146 union() {
147 cube([100,33,33], center=true);
148 cube([33,100,33], center=true);
149 cube([33,33,100], center=true);
150 }
151 sphere(r=8);
152}
153```
154
155However, it doesn't provide the inverse of this operation; to remove a shape from the entire surface
156of another object. For this, the BOSL2 library provides the `minkowski_difference()` module:
157
158```openscad-3D
159include <BOSL2/std.scad>
160minkowski_difference() {
161 union() {
162 cube([100,33,33], center=true);
163 cube([33,100,33], center=true);
164 cube([33,33,100], center=true);
165 }
166 sphere(r=8);
167}
168```
169
170To perform a `minkowski_difference()` on 2D shapes, you need to supply the `planar=true` argument:
171
172```openscad-2D
173include <BOSL2/std.scad>
174minkowski_difference(planar=true) {
175 union() {
176 square([100,33], center=true);
177 square([33,100], center=true);
178 }
179 circle(r=8);
180}
181```
182
183### Round2d
184The `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=`:
185
186```openscad-2D
187include <BOSL2/std.scad>
188round2d(or=8) star(6, step=2, d=100);
189```
190
191```openscad-2D
192include <BOSL2/std.scad>
193round2d(ir=12) star(6, step=2, d=100);
194```
195
196```openscad-2D
197include <BOSL2/std.scad>
198round2d(or=8,ir=12) star(6, step=2, d=100);
199```
200
201You can use `r=` to effectively set both `ir=` and `or=` to the same value:
202
203```openscad-2D
204include <BOSL2/std.scad>
205round2d(r=8) star(6, step=2, d=100);
206```
207
208### Shell2d
209With the `shell2d()` module, you can take an arbitrary shape, and get the shell outline of it.
210With a positive thickness, the shell is offset outwards from the original shape:
211
212```openscad-2D
213include <BOSL2/std.scad>
214shell2d(thickness=5) star(5,step=2,d=100);
215color("blue") stroke(star(5,step=2,d=100),closed=true);
216```
217
218With a negative thickness, the shell if inset from the original shape:
219
220```openscad-2D
221include <BOSL2/std.scad>
222shell2d(thickness=-5) star(5,step=2,d=100);
223color("blue") stroke(star(5,step=2,d=100),closed=true);
224```
225
226You can give a pair of thickness values if you want it both inset and outset from the original shape:
227
228```openscad-2D
229include <BOSL2/std.scad>
230shell2d(thickness=[-5,5]) star(5,step=2,d=100);
231color("blue") stroke(star(5,step=2,d=100),closed=true);
232```
233
234You can add rounding to the outside by passing a radius to the `or=` argument.
235
236```openscad-2D
237include <BOSL2/std.scad>
238shell2d(thickness=-5,or=5) star(5,step=2,d=100);
239```
240
241If you need to pass different radii for the convex and concave corners of the outside, you can pass them as `or=[CONVEX,CONCAVE]`:
242
243```openscad-2D
244include <BOSL2/std.scad>
245shell2d(thickness=-5,or=[5,10]) star(5,step=2,d=100);
246```
247
248A radius of 0 can be used to specify no rounding:
249
250```openscad-2D
251include <BOSL2/std.scad>
252shell2d(thickness=-5,or=[5,0]) star(5,step=2,d=100);
253```
254
255You can add rounding to the inside by passing a radius to the `ir=` argument.
256
257```openscad-2D
258include <BOSL2/std.scad>
259shell2d(thickness=-5,ir=5) star(5,step=2,d=100);
260```
261
262If you need to pass different radii for the convex and concave corners of the inside, you can pass them as `ir=[CONVEX,CONCAVE]`:
263
264```openscad-2D
265include <BOSL2/std.scad>
266shell2d(thickness=-5,ir=[8,3]) star(5,step=2,d=100);
267```
268
269You can use `or=` and `ir=` together to get nice combined rounding effects:
270
271```openscad-2D
272include <BOSL2/std.scad>
273shell2d(thickness=-5,or=[7,2],ir=[7,2]) star(5,step=2,d=100);
274```
275
276```openscad-2D
277include <BOSL2/std.scad>
278shell2d(thickness=-5,or=[5,0],ir=[5,0]) star(5,step=2,d=100);
279```
280
281
282### Round3d
283### Offset3d
284(To be Written)
285
286
287## Color Manipulators
288The built-in OpenSCAD `color()` module can let you set the RGB color of an object, but it's often
289easier to select colors using other color schemes. You can use the HSL or Hue-Saturation-Lightness
290color scheme with the `hsl()` module:
291
292```openscad-3D
293include <BOSL2/std.scad>
294n = 10; size = 100/n;
295for (a=count(n), b=count(n), c=count(n)) {
296 let( h=360*a/n, s=1-b/(n-1), l=c/(n-1))
297 translate(size*[a,b,c]) {
298 hsl(h,s,l) cube(size);
299 }
300}
301```
302
303You can use the HSV or Hue-Saturation-Value color scheme with the `hsv()` module:
304
305```openscad-3D
306include <BOSL2/std.scad>
307n = 10; size = 100/n;
308for (a=count(n), b=count(n), c=count(n)) {
309 let( h=360*a/n, s=1-b/(n-1), v=c/(n-1))
310 translate(size*[a,b,c]) {
311 hsv(h,s,v) cube(size);
312 }
313}
314```
315
316