| import compose from "./compose.js"; |
| import {abs, asin, atan2, cos, degrees, pi, radians, sin, tau} from "./math.js"; |
|
|
| function rotationIdentity(lambda, phi) { |
| if (abs(lambda) > pi) lambda -= Math.round(lambda / tau) * tau; |
| return [lambda, phi]; |
| } |
|
|
| rotationIdentity.invert = rotationIdentity; |
|
|
| export function rotateRadians(deltaLambda, deltaPhi, deltaGamma) { |
| return (deltaLambda %= tau) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma)) |
| : rotationLambda(deltaLambda)) |
| : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma) |
| : rotationIdentity); |
| } |
|
|
| function forwardRotationLambda(deltaLambda) { |
| return function(lambda, phi) { |
| lambda += deltaLambda; |
| if (abs(lambda) > pi) lambda -= Math.round(lambda / tau) * tau; |
| return [lambda, phi]; |
| }; |
| } |
|
|
| function rotationLambda(deltaLambda) { |
| var rotation = forwardRotationLambda(deltaLambda); |
| rotation.invert = forwardRotationLambda(-deltaLambda); |
| return rotation; |
| } |
|
|
| function rotationPhiGamma(deltaPhi, deltaGamma) { |
| var cosDeltaPhi = cos(deltaPhi), |
| sinDeltaPhi = sin(deltaPhi), |
| cosDeltaGamma = cos(deltaGamma), |
| sinDeltaGamma = sin(deltaGamma); |
|
|
| function rotation(lambda, phi) { |
| var cosPhi = cos(phi), |
| x = cos(lambda) * cosPhi, |
| y = sin(lambda) * cosPhi, |
| z = sin(phi), |
| k = z * cosDeltaPhi + x * sinDeltaPhi; |
| return [ |
| atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi), |
| asin(k * cosDeltaGamma + y * sinDeltaGamma) |
| ]; |
| } |
|
|
| rotation.invert = function(lambda, phi) { |
| var cosPhi = cos(phi), |
| x = cos(lambda) * cosPhi, |
| y = sin(lambda) * cosPhi, |
| z = sin(phi), |
| k = z * cosDeltaGamma - y * sinDeltaGamma; |
| return [ |
| atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi), |
| asin(k * cosDeltaPhi - x * sinDeltaPhi) |
| ]; |
| }; |
|
|
| return rotation; |
| } |
|
|
| export default function(rotate) { |
| rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0); |
|
|
| function forward(coordinates) { |
| coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians); |
| return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates; |
| } |
|
|
| forward.invert = function(coordinates) { |
| coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians); |
| return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates; |
| }; |
|
|
| return forward; |
| } |
|
|