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.

Learn about rotation at MathIsFun.com

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 { degToRad } = require('@jscad/modeling').utils
 
const myshape = cuboid({size: [5, 20, 5]})
const newshape = rotate([degToRad(90), degToRad(15), degToRad(30)], myshape)
const newshape = rotateX(degToRad(90), myshape)

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.

Learn about the scaling shapes at Wikipedia.org

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.

Learn about translation at MathIsFun.com

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.

Learn about reflection at MathIsFun.com

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.

Learn about matrix mathematics at MathIsFun.com

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