code: function rotate (options, ...shapes) {
    const defaults = {
      angle: 1,
      axes: [0, 0, 0]
    }
    if (isArray(options)) {
      options.axes = options
    }
    const {angle, axes} = Object.assign({}, defaults, options)
    shapes = flatten(toArray(shapes))
  
    const results = shapes.map(function (shape) {
      const typeOp = isShape2(shape) ? shape2 : shape3
      if (angle !== 1) {
        return typeOp.rotate([0, 0, 0], shape) // shape.rotate([0, 0, 0], axes, angle)
      } else {
        return typeOp.rotate(...axes, shape)
        return pipe(
          shape => shape,
          typeOp.rotateX(axes[0]),
          typeOp.rotateY(axes[1]),
          typeOp.rotateZ(axes[2])
        )
          // typeOp.rotateZ(axes[2], typeOp.rotateY(axes[1], typeOp.rotateX(axes[0], shape)))
  
          // shape.rotateX(axes[0]).rotateY(axes[1]).rotateZ(axes[2])
      }
    })
  
    // if there is more than one result, return them all , otherwise a single one
    return results.length === 1 ? results[0] : results
  }
docs: rotate an object in 2D/3D space
  @param {Float|Array} rotation - either an array or simple number to rotate object(s) by
  @param {Object(s)|Array} shapes either a single or multiple Shape3/Shape2 shapes to rotate
  @returns {Shape3} new Shape3 object , rotated by the given amount
  
  @example
  let rotatedSphere = rotate([0.2,15,1], spheroid())
  rotate(r,[x,y,z],o) ????
  rotate([x,y,z],o) ????