Skip to content

Commit

Permalink
Reorganize the entire library
Browse files Browse the repository at this point in the history
- Improve all function and argument names.
- Improve examples.
  • Loading branch information
ezzatron committed May 28, 2024
1 parent fc8e6e4 commit 28b572e
Show file tree
Hide file tree
Showing 64 changed files with 2,581 additions and 2,625 deletions.
879 changes: 540 additions & 339 deletions README.md

Large diffs are not rendered by default.

63 changes: 0 additions & 63 deletions src/R2xyz.ts

This file was deleted.

66 changes: 0 additions & 66 deletions src/R2zyx.ts

This file was deleted.

16 changes: 0 additions & 16 deletions src/R_EL2n_E.ts

This file was deleted.

16 changes: 0 additions & 16 deletions src/R_EN2n_E.ts

This file was deleted.

25 changes: 25 additions & 0 deletions src/angle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Converts angle in radians to degrees.
*
* @see https://github.com/FFI-no/n-vector/blob/f77f43d18ddb6b8ea4e1a8bb23a53700af965abb/nvector/deg.m
*
* @param radians - Angle in radians.
*
* @returns Angle in degrees.
*/
export function degrees(radians: number): number {
return (radians * 180) / Math.PI;
}

/**
* Converts angle in degrees to radians.
*
* @see https://github.com/FFI-no/n-vector/blob/f77f43d18ddb6b8ea4e1a8bb23a53700af965abb/nvector/rad.m
*
* @param degrees - Angle in degrees.
*
* @returns Angle in radians.
*/
export function radians(degrees: number): number {
return (degrees * Math.PI) / 180;
}
26 changes: 3 additions & 23 deletions src/rotation.ts → src/coord-frame.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { Matrix3x3 } from "./matrix.js";
import type { Vector3 } from "./vector.js";
import type { Matrix } from "./matrix.js";

/**
* Axes of the coordinate frame E (Earth-Centred, Earth-Fixed, ECEF) when the
Expand All @@ -10,7 +9,7 @@ import type { Vector3 } from "./vector.js";
*
* @see https://github.com/FFI-no/n-vector/blob/f77f43d18ddb6b8ea4e1a8bb23a53700af965abb/nvector/R_Ee.m#L48
*/
export const R_Ee_NP_Z: Matrix3x3 = [
export const Z_AXIS_NORTH: Matrix = [
[0, 0, 1],
[0, 1, 0],
[-1, 0, 0],
Expand All @@ -29,27 +28,8 @@ export const R_Ee_NP_Z: Matrix3x3 = [
*
* @see https://github.com/FFI-no/n-vector/blob/f77f43d18ddb6b8ea4e1a8bb23a53700af965abb/nvector/R_Ee.m#L55
*/
export const R_Ee_NP_X: Matrix3x3 = [
export const X_AXIS_NORTH: Matrix = [
[1, 0, 0],
[0, 1, 0],
[0, 0, 1],
];

/**
* Rotates a vector by a rotation matrix.
*
* @param r - A rotation matrix.
* @param v - A vector to rotate.
*
* @returns The rotated vector.
*/
export function rotate(r: Matrix3x3, v: Vector3): Vector3 {
const [[r11, r12, r13], [r21, r22, r23], [r31, r32, r33]] = r;
const [x, y, z] = v;

return [
r11 * x + r12 * y + r13 * z,
r21 * x + r22 * y + r23 * z,
r31 * x + r32 * y + r33 * z,
];
}
63 changes: 63 additions & 0 deletions src/coords.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Z_AXIS_NORTH } from "./coord-frame.js";
import type { Matrix } from "./matrix.js";
import { transpose } from "./matrix.js";
import type { Vector } from "./vector.js";
import { transform } from "./vector.js";

/**
* Converts geodetic coordinates to an n-vector.
*
* @see https://github.com/FFI-no/n-vector/blob/82d749a67cc9f332f48c51aa969cdc277b4199f2/nvector/lat_long2n_E.m
*
* @param latitude - Geodetic latitude in radians.
* @param longitude - Geodetic longitude in radians.
* @param frame - Coordinate frame in which the n-vector is decomposed.
*
* @returns An n-vector.
*/
export function fromGeodeticCoordinates(
latitude: number,
longitude: number,
frame: Matrix = Z_AXIS_NORTH,
): Vector {
// Equation (3) from Gade (2010):
const cosLat = Math.cos(latitude);

// frame selects correct E-axes
return transform(transpose(frame), [
Math.sin(latitude),
Math.sin(longitude) * cosLat,
-Math.cos(longitude) * cosLat,
]);
}

/**
* Converts an n-vector to geodetic coordinates.
*
* @see https://github.com/FFI-no/n-vector/blob/82d749a67cc9f332f48c51aa969cdc277b4199f2/nvector/n_E2lat_long.m
*
* @param vector - An n-vector.
* @param frame - Coordinate frame in which the n-vector is decomposed.
*
* @returns Geodetic latitude and longitude in radians.
*/
export function toGeodeticCoordinates(
vector: Vector,
frame: Matrix = Z_AXIS_NORTH,
): [latitude: number, longitude: number] {
// Equation (5) in Gade (2010):
const [x, y, z] = transform(frame, vector);
const longitude = Math.atan2(y, -z);

// Equation (6) in Gade (2010) (Robust numerical solution)
// vector component in the equatorial plane
const ec = Math.hypot(y, z);
// atan() could also be used since latitude is within [-pi/2,pi/2]
const latitude = Math.atan2(x, ec);

// latitude = asin(x) is a theoretical solution, but close to the Poles it is
// ill-conditioned which may lead to numerical inaccuracies (and it will give
// imaginary results for norm(vector)>1)

return [latitude, longitude];
}
12 changes: 0 additions & 12 deletions src/deg.ts

This file was deleted.

63 changes: 63 additions & 0 deletions src/delta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Z_AXIS_NORTH } from "./coord-frame.js";
import { fromECEF, toECEF } from "./ecef.js";
import { WGS_84, type Ellipsoid } from "./ellipsoid.js";
import type { Matrix } from "./matrix.js";
import type { Vector } from "./vector.js";

/**
* Delta finds a delta ECEF position vector from a reference n-vector position,
* and a target n-vector position.
*
* @see https://github.com/FFI-no/n-vector/blob/f77f43d18ddb6b8ea4e1a8bb23a53700af965abb/nvector/n_EA_E_and_n_EB_E2p_AB_E.m
*
* @param from - An n-vector of position A.
* @param to - An n-vector of position B.
* @param fromDepth - Depth of position A in meters, relative to the ellipsoid.
* @param toDepth - Depth of position B in meters, relative to the ellipsoid.
* @param ellipsoid - A reference ellipsoid.
* @param frame - Coordinate frame in which the vectors are decomposed.
*
* @returns Position vector in meters from A to B, decomposed in E.
*/
export function delta(
from: Vector,
to: Vector,
fromDepth: number = 0,
toDepth: number = 0,
ellipsoid: Ellipsoid = WGS_84,
frame: Matrix = Z_AXIS_NORTH,
): Vector {
// Function 1. in Section 5.4 in Gade (2010):
const [ax, ay, az] = toECEF(from, fromDepth, ellipsoid, frame);
const [bx, by, bz] = toECEF(to, toDepth, ellipsoid, frame);

return [bx - ax, by - ay, bz - az];
}

/**
* From position A and delta, finds position B.
*
* @see https://github.com/FFI-no/n-vector/blob/f77f43d18ddb6b8ea4e1a8bb23a53700af965abb/nvector/n_EA_E_and_p_AB_E2n_EB_E.m
*
* @param from - An n-vector of position A.
* @param delta - ECEF position vector in meters from A to B.
* @param fromDepth - Depth of position A in meters, relative to the ellipsoid.
* @param ellipsoid - A reference ellipsoid.
* @param frame - Coordinate frame in which the vectors are decomposed.
*
* @returns An n-vector of position B, and depth of position B in meters,
* relative to the ellipsoid.
*/
export function destination(
from: Vector,
[dx, dy, dz]: Vector,
fromDepth: number = 0,
ellipsoid: Ellipsoid = WGS_84,
frame: Matrix = Z_AXIS_NORTH,
): [to: Vector, toDepth: number] {
// Function 2. in Section 5.4 in Gade (2010):
const [ax, ay, az] = toECEF(from, fromDepth, ellipsoid, frame);
const b: Vector = [ax + dx, ay + dy, az + dz];

return fromECEF(b, ellipsoid, frame);
}
Loading

0 comments on commit 28b572e

Please sign in to comment.