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