Node: Affine Transformations for Transforms, Next: , Previous: Showing Transforms, Up: Transform Reference

### Affine Transformations

The affine transformation functions use their arguments to create a new `Transform` `t` (local to the function) representing the appropriate transformation. Then, `*this` is multiplied by `t` and `t` is returned. Returning `t` instead of `*this` makes it possible to put the affine transformation function at the end of a chain of invocations of `Transform::operator*=()`:

```     Transform t0, t1, t2, t3;
...
t0 *= t1 *= t2 *= t3.scale(2, 3.5, 9);
```

`t0`, `t1`, and `t2` are all multiplied by the `Transform` with

```     `matrix` =
2   0    0  0
0   3.5  0  0
0   0    9  0
0   0    0  1
```
representing the scaling operation, not `t3`, which may represent a combination of transformations.

 Transform scale (real x, [real y = 1, [real z = 1]]) Function
 Creates a `Transform t` representing the scaling operation locally, multiplies `*this` by `t`, and returns `t`. A `Transform` representing scaling only, when applied to a `Point p`, will cause its x-coordinate to be multiplied by x, its y-coordinate to be multiplied by y, and its z-coordinate to be multiplied by z. ``` `Transform t;` `t.scale(`x`, `y`, `z`);` ``` ``` => `t.matrix` = x 0 0 0 0 y 0 0 0 0 z 0 0 0 0 1 ``` ``` Transform t; t.scale(12.5, 20, 1.3); t.show("t:"); -| t: 12.5 0 0 0 0 20 0 0 0 0 1.3 0 0 0 0 1 ```

 Transform shear (real xy, [real xz = 0, [real yx = 0, [real yz = 0, [real zx = 0, [real zy = 0]]]]]) Function
 Creates a `Transform t` representing the shearing operation locally, multiplies `*this` by `t`, and returns `t`. When applied to a `Point`, shearing causes each coordinate to be modified according to the values of the other coordinates and the arguments to `shear`: ``` Point p(x,y,z); Transform t; t.shear(a, b, c, d, e, f); p *= t; ``` ``` => p = ((x + ay + bz), (y + cx + dz), (z + ex + fy)) ``` ``` Transform t; t.shear(2, 3, 4, 5, 6, 7); t.show("t:"); -| t: 1 4 6 0 2 1 7 0 3 5 1 0 0 0 0 1 ```

 Transform shift (real x, [real y = 0, [real z = 0]]) Function Transform shift (const Point& p) Function
 These functions create a `Transform t` representing the shifting operation locally, multiplies `*this` by `t`, and returns `t`. The version with the argument `const Point&` p passes the updated x, y, and z-coordinates of p (from `world_coordinates`) to the version with three `real` arguments. When a `Transform` representing a single shifting operation only is applied to a `Point`, the x, y, and z arguments are added to the corresponding coordinates of the `Point`: ``` Point p(x,y,z); Transform t; t.shift(a, b, c); p *= t; ``` ``` => p = (x + a, y + b, z + c) ```

 Transform shift_times (real x, [real y = 1, [real z = 1]]) Function
 Multiplies the corresponding elements of `matrix` by the `real` arguments, i.e., `matrix` is multiplied by x, `matrix` is multiplied by y, and `matrix` is multiplied by z. Returns `*this`. Ordinary shifting is additive, so a special function is needed to multiply the elements of `matrix` responsible for shifting. The effect of `shift_times()` is to modify a `Transform` representing a shifting operation such that the direction of the shift is maintained, while changing the distance. If the `Transform` represents other operations in addition to shifting, e.g., scaling and/or shearing, the effect of `shift_times()` may be unpredictable.1 ``` Transform t; t.shift(1, 2, 3); ``` ``` => `t.matrix` = 1 0 0 0 0 1 0 0 0 0 1 0 1 2 3 1 ``` ``` t.shift_times(2, 2, 2); ``` ``` => `t.matrix` = 1 0 0 0 0 1 0 0 0 0 1 0 2 4 6 1 ``` ``` Rectangle r; r.set(origin, 1, 1, 90); r = r = r = r; Transform t; t.shift(1.5, 1.5); r *= t; r.draw(); t.shift_times(1.5, 1.5); r *= t; r.draw(); t.shift_times(1.5, 1.5); r *= t; r.draw(); t.shift_times(1.5, 1.5); r *= t; r.draw(); ``` Fig. 73. ``` Cuboid c(origin, 1, 1, 1); c.draw(); Transform t; t.rotate(30, 30, 30); t.shift(1, 0, 1); c *= t; c.draw(); t.shift_times(1.5, 0, 1.5); c *= t; c.draw(); t.shift_times(1.5, 0, 1.5); c *= t; c.draw(); t.shift_times(1.5, 0, 1.5); c *= t; c.draw(); t.shift_times(1.5, 0, 1.5); c *= t; c.draw(); ``` Fig. 74.

 Transform rotate (real x, [real y = 0, [real z = 0]]) Function
 Rotation around the main axes. Creates a `Transform t` representing the rotation, multiplies `*this` by `t`, and returns `t`.

 Transform rotate (Point p0, Point p1, [const real angle = 180]) Function
 Rotation around an arbitrary axis. The `Point` arguments represent the end points of the axis, and angle is the angle of rotation. Since 180 degrees rotation is needed so often, 180 is the default for angle.

 Transform rotate (const Path& p, [const real angle = 180]) Function
 Rotation around an arbitrary axis. `Path` argument. The `Path` p must be linear, i.e., `p.is_linear()` must return `true`. See Path Reference; Querying.

#### Footnotes

1. For a person, not in the sense of the program behaving unpredictably.