## Transforms

All shapes can be transformed, i.e. translated to another location, rotated by certain angles, etc. In all cases, the transform function returns a new shape, not the original.

```const myshape = circle({radius: 5})
const newshape = scale([5, 10], circleA) // a new cicle, scaled as requested```

So, in order to modify the original, place the original on the left-hand side of the expression.

```let myshape = circle({radius: 5})
myshape = scale([5, 10], myshape) // a new circle, scaled as requested, reassigned to the original```

In fact, the two lines above can be combined into a single line.

`let myshape = scale([5, 10]). circle({radius: 5})) // a new circle, and scaled as requested`

Transforms can also be chained together, but keep in mind that the order of transforms is important.

```let myshape = scale([5, 10]). circle({radius: 5}))
myshape = translate([0, 0, 10]), rotateX(45, myshape))```

The original shape can be transformed any number of times. For example, the a single cylinder can be rotated and translated to make multiple copies of the original. And then, the set of cylinders can be combined together using union. This is a common pattern when creating complex designs.

The transforms return a single shape or an array of shapes depending on the given shapes.

```const newshape = align({modes: ['none', 'center', 'none']}, oldshape)  /* Returns a single shape */
const newshapes = align({modes: ['min', 'center', 'none'], alignTo: [10, null, 10], grouped: true }, oldshape, [oldshape0, oldshape1])  /* Returns an array of new shapes*/```

### Orientation

The standard for all 3D systems today, including graphics cards, design tools, etc. is orientating shapes using the right-hand rule. JSCAD follows the same rules internally, and produces shapes, applies transforms, etc. using the right-hand rule of orientation. See Orientation for more information.

### Rotate

Shapes can be rotated by any given angle about the X, Y, and Z axis. The `angles` can be specified as either positive or negative values, in RADIANS.

Defaults:

• angles : [0, 0, 0]
```const { cuboid } = require('@jscad/modeling').primitives
const { rotate } = require('@jscad/modeling').transforms

const myshape = cuboid({size: [5, 20, 5]})
const newshape = rotate([(Math.PI * 2 / 4), (Math.PI * 2 / 24), (Math.PI * 2 / 12)], myshape)```

In addition, there are simple versions of the same function for rotating about a single axis.

```const { cuboid } = require('@jscad/modeling').primitives
const { rotateX,rotateY,rotateZ } = require('@jscad/modeling').transforms

const myshape = cuboid({size: [5, 20, 5]})
let newshape = rotateX((Math.PI * 2 / 4), myshape)
newshape = rotateY((Math.PI * 2 / 24), newshape)
newshape = rotateZ((Math.PI * 2 / 12), newshape)```

There is a utility function to convert DEGREE to RADIAN values.

```const { cuboid } = require('@jscad/modeling').primitives
const { rotateX,rotate } = require('@jscad/modeling').transforms

const myshape = cuboid({size: [5, 20, 5]})

### Scale

Shapes can be scaled by any factor, enlarging (increasing) or shrinking (diminishing) shapes by the `factors` about X, Y, and Z axis. The result of scaling is a similar shape (in the geometric sense) to the original.

Defaults:

• factors : [1.0, 1.0, 1.0]
```const myshape = sphere({radius: 5})
const newshape = scale([2, 4, 6], myshape)```

In addition, there are simple versions of the same function for scaling about a single axis.

```const myshape = sphere({radius: 5})
let newshape = scaleX(2, myshape)
newshape = scaleY(4, newshape)
newshape = scaleZ(6, newshape)```

### Translate

Shapes can be translated (moved) to another location. In other words, every point in the shape is moved by a fixed distance as given by the `offset`. The `offset` can be positive or negative.

Defaults:

• offset : [0, 0, 0]
```const myshape = sphere([radius: 5})
const newshape = translate([3, 7, -10], myshape)```

In addition, there are simple versions of the same function for translating about a single axis.

```const myshape = sphere([radius: 5})
let newshape = translateX(3, myshape)
newshape = translateY(7, newshape)
newshape = translateZ(-10, newshape)```

### Align

Shapes can be aligned across X, Y, and Z axis. In other words, each shape is translated to the requested position, aligning the boundaries of the shapes. The `modes` of alignment control which position to use, with values 'center', 'min', 'max', or 'none'. The alignment can also be positioned to a specific point, `relativeTo`.

Defaults:

• modes : ['center', 'center', 'min']
• group : false (do not align all shapes as a group)
• relativeTo : [0, 0, 0]
```const newshapes = align({modes: ['min', 'none', 'none'], myshape1, myshape2, myshape3) // align shapes at the minimum X
const newshapes = align({modes: ['min', 'center', 'none'], relativeTo: [10, null, 10], grouped: true}, myshape1, myshape2, myshape3)```

### Center

Shapes can be centered about the X, Y or Z axis, or centered relative to a given point.

Note: The center of a shape is calculated as the midpoint between minimum and maximum points.

Defaults:

• axes : [true, true, true]
• relativeTo : [0, 0, 0]
```const myshape = sphere({radius: 5})
let newshape = center({}, myshape)  // center the shape across all axes
newshape = center({axes: [true, true, false]}, myshape)  // center the object across only X and Y axis
newshape = center({relativeTo: [5, 6, 7]}, myshape)  // center the shape relative to the given point```

There are also simple versions of this function to center the shape about the origin.

```const myshape = sphere({radius: 5})
let newshape = centerX(myshape)
newshape = centerY(newshape)
newshape = centerZ(newshape)```

### Mirror

Shapes can mirror (reflect) about the X, Y, or Z axis, and more specifically about any `origin`.

Defaults:

• origin : [0, 0, 0]
• normal : [0, 0, 1] (mirror about the Z axis)
```const myshape = cube({size: [5, 20, 5]})
const newshape = mirror({origin: 3, 3, 3], normal: [1, 0, 1]}, myshape)```

There are simple versions of this function to mirror a single axis about the origin.

```const myshape = cube({size: [5, 20, 5]})
let newshape = mirrorX(myshape)
newshape = mirrorY(newshape)
newshape = mirrorZ(newshape)```

### Matrix Transform

The previous transforms are actually simplified versions of matrix mathematics. For example, translate is just applying addition using a matrix.

```let matrix = mat4.create()
matrix = mat4.multiply(mat4.rotationX(40))
matrix = mat4.multiply(mat4.rotationZ(40))
matrix = mat4.multiply(mat4.translation([-.5, 0, 0]))
matrix = mat4.multiply(mat4.scaling([1.1, 1.2, 1.3]))

// and apply the transform
const myshape = transform(matrix, cube())```