rotation.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import compose from "./compose.js";
  2. import {abs, asin, atan2, cos, degrees, pi, radians, sin, tau} from "./math.js";
  3. function rotationIdentity(lambda, phi) {
  4. if (abs(lambda) > pi) lambda -= Math.round(lambda / tau) * tau;
  5. return [lambda, phi];
  6. }
  7. rotationIdentity.invert = rotationIdentity;
  8. export function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
  9. return (deltaLambda %= tau) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
  10. : rotationLambda(deltaLambda))
  11. : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
  12. : rotationIdentity);
  13. }
  14. function forwardRotationLambda(deltaLambda) {
  15. return function(lambda, phi) {
  16. lambda += deltaLambda;
  17. if (abs(lambda) > pi) lambda -= Math.round(lambda / tau) * tau;
  18. return [lambda, phi];
  19. };
  20. }
  21. function rotationLambda(deltaLambda) {
  22. var rotation = forwardRotationLambda(deltaLambda);
  23. rotation.invert = forwardRotationLambda(-deltaLambda);
  24. return rotation;
  25. }
  26. function rotationPhiGamma(deltaPhi, deltaGamma) {
  27. var cosDeltaPhi = cos(deltaPhi),
  28. sinDeltaPhi = sin(deltaPhi),
  29. cosDeltaGamma = cos(deltaGamma),
  30. sinDeltaGamma = sin(deltaGamma);
  31. function rotation(lambda, phi) {
  32. var cosPhi = cos(phi),
  33. x = cos(lambda) * cosPhi,
  34. y = sin(lambda) * cosPhi,
  35. z = sin(phi),
  36. k = z * cosDeltaPhi + x * sinDeltaPhi;
  37. return [
  38. atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
  39. asin(k * cosDeltaGamma + y * sinDeltaGamma)
  40. ];
  41. }
  42. rotation.invert = function(lambda, phi) {
  43. var cosPhi = cos(phi),
  44. x = cos(lambda) * cosPhi,
  45. y = sin(lambda) * cosPhi,
  46. z = sin(phi),
  47. k = z * cosDeltaGamma - y * sinDeltaGamma;
  48. return [
  49. atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
  50. asin(k * cosDeltaPhi - x * sinDeltaPhi)
  51. ];
  52. };
  53. return rotation;
  54. }
  55. export default function(rotate) {
  56. rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
  57. function forward(coordinates) {
  58. coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
  59. return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;
  60. }
  61. forward.invert = function(coordinates) {
  62. coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
  63. return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;
  64. };
  65. return forward;
  66. }