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[3][0] is multiplied by x, matrix[3][1] is multiplied by y, and matrix[3][2] 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[4];
          r[0].set(origin, 1, 1, 90);
          r[3] = r[2] = r[1] = r[0];
          Transform t;
          t.shift(1.5, 1.5);
          r[0] *= t;
          r[0].draw();
          t.shift_times(1.5, 1.5);
          r[1] *= t;
          r[1].draw();
          t.shift_times(1.5, 1.5);
          r[2] *= t;
          r[2].draw();
          t.shift_times(1.5, 1.5);
          r[3] *= t;
          r[3].draw();
          


[Figure 73. Not displayed.]

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();
          


[Figure 74. Not displayed.]

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.