modeling/src/operations/transforms/rotate.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. * Rotate the given objects using the given options.
  8. * @param {Array} angles - angle (RADIANS) of rotations about X, Y, and Z axis
  9. * @param {...Object} objects - the objects to rotate
  10. * @return {Object|Array} the rotated object, or a list of rotated objects
  11. * @alias module:modeling/transforms.rotate
  12. *
  13. * @example
  14. * const newsphere = rotate([TAU / 8, 0, 0], sphere())
  15. */
  16. const rotate = (angles, ...objects) => {
  17. if (!Array.isArray(angles)) throw new Error('angles must be an array')
  18. objects = flatten(objects)
  19. if (objects.length === 0) throw new Error('wrong number of arguments')
  20. // adjust the angles if necessary
  21. angles = angles.slice() // don't modify the original
  22. while (angles.length < 3) angles.push(0)
  23. const yaw = angles[2]
  24. const pitch = angles[1]
  25. const roll = angles[0]
  26. const matrix = mat4.fromTaitBryanRotation(mat4.create(), yaw, pitch, roll)
  27. const results = objects.map((object) => {
  28. if (path2.isA(object)) return path2.transform(matrix, object)
  29. if (geom2.isA(object)) return geom2.transform(matrix, object)
  30. if (geom3.isA(object)) return geom3.transform(matrix, object)
  31. return object
  32. })
  33. return results.length === 1 ? results[0] : results
  34. }
  35. /**
  36. * Rotate the given objects about the X axis, using the given options.
  37. * @param {Number} angle - angle (RADIANS) of rotations about X
  38. * @param {...Object} objects - the objects to rotate
  39. * @return {Object|Array} the rotated object, or a list of rotated objects
  40. * @alias module:modeling/transforms.rotateX
  41. */
  42. const rotateX = (angle, ...objects) => rotate([angle, 0, 0], objects)
  43. /**
  44. * Rotate the given objects about the Y axis, using the given options.
  45. * @param {Number} angle - angle (RADIANS) of rotations about Y
  46. * @param {...Object} objects - the objects to rotate
  47. * @return {Object|Array} the rotated object, or a list of rotated objects
  48. * @alias module:modeling/transforms.rotateY
  49. */
  50. const rotateY = (angle, ...objects) => rotate([0, angle, 0], objects)
  51. /**
  52. * Rotate the given objects about the Z axis, using the given options.
  53. * @param {Number} angle - angle (RADIANS) of rotations about Z
  54. * @param {...Object} objects - the objects to rotate
  55. * @return {Object|Array} the rotated object, or a list of rotated objects
  56. * @alias module:modeling/transforms.rotateZ
  57. */
  58. const rotateZ = (angle, ...objects) => rotate([0, 0, angle], objects)
  59. module.exports = {
  60. rotate,
  61. rotateX,
  62. rotateY,
  63. rotateZ
  64. }