modeling/src/operations/transforms/scale.js

  1. const flatten = require('../../utils/flatten')
  2. const mat4 = require('../../maths/mat4')
  3. const geom2 = require('../../geometries/geom2')
  4. const geom3 = require('../../geometries/geom3')
  5. const path2 = require('../../geometries/path2')
  6. /**
  7. * Scale the given objects using the given options.
  8. * @param {Array} factors - X, Y, Z factors by which to scale the objects
  9. * @param {...Object} objects - the objects to scale
  10. * @return {Object|Array} the scaled object, or a list of scaled objects
  11. * @alias module:modeling/transforms.scale
  12. *
  13. * @example
  14. * let myshape = scale([5, 0, 10], sphere())
  15. */
  16. const scale = (factors, ...objects) => {
  17. if (!Array.isArray(factors)) throw new Error('factors must be an array')
  18. objects = flatten(objects)
  19. if (objects.length === 0) throw new Error('wrong number of arguments')
  20. // adjust the factors if necessary
  21. factors = factors.slice() // don't modify the original
  22. while (factors.length < 3) factors.push(1)
  23. if (factors[0] <= 0 || factors[1] <= 0 || factors[2] <= 0) throw new Error('factors must be positive')
  24. const matrix = mat4.fromScaling(mat4.create(), factors)
  25. const results = objects.map((object) => {
  26. if (path2.isA(object)) return path2.transform(matrix, object)
  27. if (geom2.isA(object)) return geom2.transform(matrix, object)
  28. if (geom3.isA(object)) return geom3.transform(matrix, object)
  29. return object
  30. })
  31. return results.length === 1 ? results[0] : results
  32. }
  33. /**
  34. * Scale the given objects about the X axis using the given options.
  35. * @param {Number} factor - X factor by which to scale the objects
  36. * @param {...Object} objects - the objects to scale
  37. * @return {Object|Array} the scaled object, or a list of scaled objects
  38. * @alias module:modeling/transforms.scaleX
  39. */
  40. const scaleX = (factor, ...objects) => scale([factor, 1, 1], objects)
  41. /**
  42. * Scale the given objects about the Y axis using the given options.
  43. * @param {Number} factor - Y factor by which to scale the objects
  44. * @param {...Object} objects - the objects to scale
  45. * @return {Object|Array} the scaled object, or a list of scaled objects
  46. * @alias module:modeling/transforms.scaleY
  47. */
  48. const scaleY = (factor, ...objects) => scale([1, factor, 1], objects)
  49. /**
  50. * Scale the given objects about the Z axis using the given options.
  51. * @param {Number} factor - Z factor by which to scale the objects
  52. * @param {...Object} objects - the objects to scale
  53. * @return {Object|Array} the scaled object, or a list of scaled objects
  54. * @alias module:modeling/transforms.scaleZ
  55. */
  56. const scaleZ = (factor, ...objects) => scale([1, 1, factor], objects)
  57. module.exports = {
  58. scale,
  59. scaleX,
  60. scaleY,
  61. scaleZ
  62. }