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