8.2 Translation

The translation operation moves an object by adding a vector to all its points, causing all these points to move a certain distance in a determined direction. The vector components indicate what is the displacement in relation to each coordinate axis.

To perform the translation operation, Khepri provides the move operation, which receives one object and one displacement vector. As an example, we have:

move(sphere(), vxyz(1, 2, 3))

Note that the function returns the object that suffered the translation to allow its combination with other operations.

For the previous example, it is simpler to immediately specify the sphere’s center by writing:

sphere(xyz(1, 2, 3))

However, in more complex cases, it can be advantageous to consider an object created at the origin and later translated to the desired position. Let us consider, for example, a papal cross, defined by the union of three horizontal cylinders of progressively decreasing length placed along a vertical cylinder, as can be seen in this figure.

A papal cross.

image

All cylinders have the same radius, and their length and position are defined according to that radius. The vertical cylinder of the papal cross has a length equal to \(20\) radii, while the horizontal cylinders have lengths equal to \(14\), \(10\) and \(6\) radii. Their axes are positioned at a height equal to \(9\), \(13\) and \(17\) radii. These proportions are implemented by the following function, which receives a reference point \(P\) and a radius \(r\):

papal_cross(p, r) =

  union(cylinder(p, r, p+vz(20*r)),

        cylinder(p+vxz(-7*r, 9*r), r, p+vxz(7*r, 9*r)),

        cylinder(p+vxz(-5*r, 13*r), r, p+vxz(5*r, 13*r)),

        cylinder(p+vxz(-3*r, 17*r), r, p+vxz(3*r, 17*r)))

However, if we assume that the cross is initially positioned at the origin, we can slightly simplify the previous definition:

papal_cross(r) =

  union(cylinder(u0(), r, z(20*r)),

        cylinder(xz(-7*r, 9*r), r, xz(7*r, 9*r)),

        cylinder(xz(-5*r, 13*r), r, xz(5*r, 13*r)),

        cylinder(xz(-3*r, 17*r), r, xz(3*r, 17*r)))

Naturally, if we want to place the cross at a specific position, for example, \((1,2)\), we should write:

move(papal_cross(1), vxy(1, 2))