1# Transforms Tutorial
  2
  3<!-- TOC -->
  4
  5## Translation
  6The `translate()` command is very simple:
  7```openscad
  8include <BOSL2/std.scad>
  9#sphere(d=20);
 10translate([0,0,30]) sphere(d=20);
 11```
 12
 13But at a glance, or when the formula to calculate the move is complex, it can be difficult to see
 14just what axis is being moved along, and in which direction.  It's also a bit verbose for such a
 15frequently used command.  For these reasons, BOSL2 provides you with shortcuts for each direction.
 16These shortcuts are `up()`, `down()`, `fwd()`, `back()`, `left()`, and `right()`:
 17```openscad
 18include <BOSL2/std.scad>
 19#sphere(d=20);
 20up(30) sphere(d=20);
 21```
 22
 23```openscad
 24include <BOSL2/std.scad>
 25#sphere(d=20);
 26down(30) sphere(d=20);
 27```
 28
 29```openscad
 30include <BOSL2/std.scad>
 31#sphere(d=20);
 32fwd(30) sphere(d=20);
 33```
 34
 35```openscad
 36include <BOSL2/std.scad>
 37#sphere(d=20);
 38back(30) sphere(d=20);
 39```
 40
 41```openscad
 42include <BOSL2/std.scad>
 43#sphere(d=20);
 44left(30) sphere(d=20);
 45```
 46
 47```openscad
 48include <BOSL2/std.scad>
 49#sphere(d=20);
 50right(30) sphere(d=20);
 51```
 52
 53There is also a more generic `move()` command that can work just like `translate()`:
 54```openscad
 55include <BOSL2/std.scad>
 56#sphere(d=20);
 57move([30,-10]) sphere(d=20);
 58```
 59
 60## Scaling
 61The `scale()` command is also fairly simple:
 62```openscad
 63include <BOSL2/std.scad>
 64scale(2) cube(10, center=true);
 65```
 66
 67```openscad
 68include <BOSL2/std.scad>
 69scale([1,2,3]) cube(10, center=true);
 70```
 71
 72If you want to only change the scaling on one axis, though, BOSL2 provides clearer
 73commands to do just that; `xscale()`, `yscale()`, and `zscale()`:
 74```openscad
 75include <BOSL2/std.scad>
 76xscale(2) cube(10, center=true);
 77```
 78```openscad
 79include <BOSL2/std.scad>
 80yscale(2) cube(10, center=true);
 81```
 82```openscad
 83include <BOSL2/std.scad>
 84zscale(2) cube(10, center=true);
 85```
 86
 87
 88## Rotation
 89The `rotate()` command is fairly straightforward:
 90```openscad
 91include <BOSL2/std.scad>
 92rotate([0,30,0]) cube(20, center=true);
 93```
 94
 95It is also a bit verbose, and can, at a glance, be difficult to tell just how it is rotating.
 96BOSL2 provides shortcuts for rotating around each axis, for clarity; `xrot()`, `yrot()`, and `zrot()`:
 97```openscad
 98include <BOSL2/std.scad>
 99xrot(30) cube(20, center=true);
100```
101
102```openscad
103include <BOSL2/std.scad>
104yrot(30) cube(20, center=true);
105```
106
107```openscad
108include <BOSL2/std.scad>
109zrot(30) cube(20, center=true);
110```
111
112The `rot()` command is a more generic rotation command, and shorter to type than `rotate()`:
113```openscad
114include <BOSL2/std.scad>
115rot([0,30,15]) cube(20, center=true);
116```
117
118All of the rotation shortcuts can take a `cp=` argument, that lets you specify a
119centerpoint to rotate around:
120```openscad
121include <BOSL2/std.scad>
122cp = [0,0,40];
123color("blue") move(cp) sphere(d=3);
124#cube(20, center=true);
125xrot(45, cp=cp) cube(20, center=true);
126```
127
128```openscad
129include <BOSL2/std.scad>
130cp = [0,0,40];
131color("blue") move(cp) sphere(d=3);
132#cube(20, center=true);
133yrot(45, cp=cp) cube(20, center=true);
134```
135
136```openscad
137include <BOSL2/std.scad>
138cp = [0,40,0];
139color("blue") move(cp) sphere(d=3);
140#cube(20, center=true);
141zrot(45, cp=cp) cube(20, center=true);
142```
143
144You can also do a new trick with it.  You can rotate from pointing in one direction, towards another.
145You give these directions using vectors:
146```openscad
147include <BOSL2/std.scad>
148#cylinder(d=10, h=50);
149rot(from=[0,0,1], to=[1,0,1]) cylinder(d=10, h=50);
150```
151
152There are several direction vectors constants and aliases you can use for clarity:
153
154Constant                       | Value        | Direction
155------------------------------ | ------------ | --------------
156`CENTER`, `CTR`                | `[ 0, 0, 0]` | Centered
157`LEFT`                         | `[-1, 0, 0]` | Towards X-
158`RIGHT`                        | `[ 1, 0, 0]` | Towards X+
159`FWD`, `FORWARD`, `FRONT`      | `[ 0,-1, 0]` | Towards Y-
160`BACK`                         | `[ 0, 1, 0]` | Towards Y+
161`DOWN`, `BOTTOM`, `BOT`, `BTM` | `[ 0, 0,-1]` | Towards Z-
162`UP`, `TOP`                    | `[ 0, 0, 1]` | Towards Z+
163`ALLNEG`                       | `[-1,-1,-1]` | Towards X-Y-Z-
164`ALLPOS`                       | `[ 1, 1, 1]` | Towards X+Y+Z+
165
166This lets you rewrite the above vector rotation more clearly as:
167```openscad
168include <BOSL2/std.scad>
169#cylinder(d=10, h=50);
170rot(from=UP, to=UP+RIGHT) cylinder(d=10, h=50);
171```
172
173
174## Mirroring
175The standard `mirror()` command works like this:
176```openscad
177include <BOSL2/std.scad>
178#yrot(60) cylinder(h=50, d1=20, d2=10);
179mirror([1,0,0]) yrot(60) cylinder(h=50, d1=20, d2=10);
180```
181
182BOSL2 provides shortcuts for mirroring across the standard axes; `xflip()`, `yflip()`, and `zflip()`:
183```openscad
184include <BOSL2/std.scad>
185#yrot(60) cylinder(h=50, d1=20, d2=10);
186xflip() yrot(60) cylinder(h=50, d1=20, d2=10);
187```
188
189```openscad
190include <BOSL2/std.scad>
191#xrot(60) cylinder(h=50, d1=20, d2=10);
192yflip() xrot(60) cylinder(h=50, d1=20, d2=10);
193```
194
195```openscad
196include <BOSL2/std.scad>
197#cylinder(h=50, d1=20, d2=10);
198zflip() cylinder(h=50, d1=20, d2=10);
199```
200
201All of the flip commands can offset where the mirroring is performed:
202```openscad
203include <BOSL2/std.scad>
204#zrot(30) cube(20, center=true);
205xflip(x=-20) zrot(30) cube(20, center=true);
206color("blue",0.25) left(20) cube([0.1,50,50], center=true);
207```
208
209```openscad
210include <BOSL2/std.scad>
211#zrot(30) cube(20, center=true);
212yflip(y=20) zrot(30) cube(20, center=true);
213color("blue",0.25) back(20) cube([40,0.1,40], center=true);
214```
215
216```openscad
217include <BOSL2/std.scad>
218#xrot(30) cube(20, center=true);
219zflip(z=-20) xrot(30) cube(20, center=true);
220color("blue",0.25) down(20) cube([40,40,0.1], center=true);
221```
222
223
224## Skewing
225One transform that OpenSCAD does not perform natively is skewing.
226BOSL2 provides the `skew()` command for that.  You give it multipliers
227for the skews you want to perform.  The arguments used all start with `s`,
228followed by the axis you want to skew along, followed by the axis that
229the skewing will increase along.  For example, to skew along the X axis as
230you get farther along the Y axis, use the `sxy=` argument.  If you give it
231a multiplier of `0.5`, then for each unit further along the Y axis you get,
232you will add `0.5` units of skew to the X axis.  Giving a negative multiplier
233reverses the direction it skews:
234```openscad
235include <BOSL2/std.scad>
236skew(sxy=0.5) cube(10,center=false);
237```
238
239```openscad
240include <BOSL2/std.scad>
241skew(sxz=-0.5) cube(10,center=false);
242```
243
244```openscad
245include <BOSL2/std.scad>
246skew(syx=-0.5) cube(10,center=false);
247```
248
249```openscad
250include <BOSL2/std.scad>
251skew(syz=0.5) cube(10,center=false);
252```
253
254```openscad
255include <BOSL2/std.scad>
256skew(szx=-0.5) cube(10,center=false);
257```
258
259```openscad
260include <BOSL2/std.scad>
261skew(szy=0.5) cube(10,center=false);
262```
263
264