rotation.js 2.5 KB

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