You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.5 KiB
77 lines
2.5 KiB
1 year ago
|
import compose from "./compose";
|
||
|
import {asin, atan2, cos, degrees, pi, radians, sin, tau} from "./math";
|
||
|
|
||
|
function rotationIdentity(lambda, phi) {
|
||
|
return [lambda > pi ? lambda - tau : lambda < -pi ? lambda + tau : 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) {
|
||
|
return lambda += deltaLambda, [lambda > pi ? lambda - tau : lambda < -pi ? lambda + tau : 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;
|
||
|
}
|