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