Skip to content

Commit

Permalink
Add n_EA_E_and_n_EB_E2p_AB_E function
Browse files Browse the repository at this point in the history
  • Loading branch information
ezzatron committed Apr 28, 2024
1 parent a86511b commit 46d297e
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { lat_lon2n_E } from "./lat_lon2n_E.js";
export { n_E2lat_lon } from "./n_E2lat_lon.js";
export { n_EA_E_and_n_EB_E2p_AB_E } from "./n_EA_E_and_n_EB_E2p_AB_E.js";
export { n_EB_E2p_EB_E } from "./n_EB_E2p_EB_E.js";
export { p_EB_E2n_EB_E } from "./p_EB_E2n_EB_E.js";
49 changes: 49 additions & 0 deletions src/n_EA_E_and_n_EB_E2p_AB_E.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { WGS_84 } from "./ellipsoid.js";
import type { Matrix3x3 } from "./matrix.js";
import { n_EB_E2p_EB_E } from "./n_EB_E2p_EB_E.js";
import { ROTATION_MATRIX_e } from "./rotation.js";
import type { Vector3 } from "./vector.js";

/**
* Calculates the delta vector from position A to B decomposed in E.
*
* Defaults to the WGS-84 ellipsoid. If `f` is `0`, then spherical Earth with
* radius `a` is used instead of WGS-84.
*
* @param n_EA_E - An n-vector of position A, decomposed in E.
* @param n_EB_E - An n-vector of position B, decomposed in E.
* @param z_EA - The depth in meters of system A, relative to the ellipsoid.
* @param z_EB - The depth in meters of system B, relative to the ellipsoid.
* @param a - The semi-major axis of the Earth ellipsoid given in meters.
* @param f - The flattening of the Earth ellipsoid.
* @param R_Ee - A rotation matrix defining the axes of the coordinate frame E.
*
* @returns A Cartesian position vector in meters from A to B, decomposed in E.
*/
export function n_EA_E_and_n_EB_E2p_AB_E(
n_EA_E: Vector3,
n_EB_E: Vector3,
z_EA: number = 0,
z_EB: number = 0,
a: number = WGS_84.a,
f: number = WGS_84.f,
R_Ee: Matrix3x3 = ROTATION_MATRIX_e,
): Vector3 {
// Based on https://github.com/pbrod/nvector/blob/b8afd89a860a4958d499789607aacb4168dcef87/src/nvector/core.py#L279
const [p_EA_E_x, p_EA_E_y, p_EA_E_z] = n_EB_E2p_EB_E(
n_EA_E,
z_EA,
a,
f,
R_Ee,
);
const [p_EB_E_x, p_EB_E_y, p_EB_E_z] = n_EB_E2p_EB_E(
n_EB_E,
z_EB,
a,
f,
R_Ee,
);

return [p_EB_E_x - p_EA_E_x, p_EB_E_y - p_EA_E_y, p_EB_E_z - p_EA_E_z];
}
16 changes: 16 additions & 0 deletions test/nvector-test-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { WebSocket } from "ws";
import type {
lat_lon2n_E,
n_E2lat_lon,
n_EA_E_and_n_EB_E2p_AB_E,
n_EB_E2p_EB_E,
p_EB_E2n_EB_E,
} from "../src/index.js";
Expand All @@ -10,6 +11,7 @@ import type { Vector3 } from "../src/vector.js";
export type NvectorTestClient = {
lat_lon2n_E: Async<typeof lat_lon2n_E>;
n_E2lat_lon: Async<typeof n_E2lat_lon>;
n_EA_E_and_n_EB_E2p_AB_E: Async<typeof n_EA_E_and_n_EB_E2p_AB_E>;
n_EB_E2p_EB_E: Async<typeof n_EB_E2p_EB_E>;
p_EB_E2n_EB_E: Async<typeof p_EB_E2n_EB_E>;

Expand Down Expand Up @@ -48,6 +50,20 @@ export async function createNvectorTestClient(): Promise<NvectorTestClient> {
return [latitude, longitude];
},

async n_EA_E_and_n_EB_E2p_AB_E(n_EA_E, n_EB_E, z_EA, z_EB, a, f, R_Ee) {
return unwrapVector3(
await call<WrappedVector3>("n_EA_E_and_n_EB_E2p_AB_E", {
n_EA_E: wrapVector3(n_EA_E),
n_EB_E: wrapVector3(n_EB_E),
z_EA,
z_EB,
a,
f,
R_Ee,
}),
);
},

async n_EB_E2p_EB_E(n_EB_E, depth, a, f, R_Ee) {
return unwrapVector3(
await call<WrappedVector3>("n_EB_E2p_EB_E", {
Expand Down
87 changes: 87 additions & 0 deletions test/vitest/n_EA_E_and_n_EB_E2p_AB_E.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { fc, it } from "@fast-check/vitest";
import { afterAll, beforeAll, describe, expect } from "vitest";
import { n_EA_E_and_n_EB_E2p_AB_E } from "../../src/index.js";
import {
arbitrary3dRotationMatrix,
arbitrary3dUnitVector,
arbitraryEllipsoid,
arbitraryEllipsoidDepth,
} from "../arbitrary.js";
import {
NvectorTestClient,
createNvectorTestClient,
} from "../nvector-test-api.js";

const TEST_DURATION = 5000;

describe("n_EA_E_and_n_EB_E2p_AB_E()", () => {
let nvectorTestClient: NvectorTestClient;

beforeAll(async () => {
nvectorTestClient = await createNvectorTestClient();
});

afterAll(() => {
nvectorTestClient?.close();
});

it.prop(
[
arbitrary3dUnitVector(),
arbitrary3dUnitVector(),
arbitraryEllipsoid().chain((ellipsoid) => {
return fc.tuple(
fc.option(arbitraryEllipsoidDepth(ellipsoid), {
nil: undefined,
}),
fc.option(arbitraryEllipsoidDepth(ellipsoid), {
nil: undefined,
}),
fc.option(fc.constant(ellipsoid.a), { nil: undefined }),
fc.option(fc.constant(ellipsoid.f), { nil: undefined }),
);
}),
fc.option(arbitrary3dRotationMatrix(), { nil: undefined }),
],
{ interruptAfterTimeLimit: TEST_DURATION, numRuns: Infinity },
)(
"matches the Python implementation",
async (n_EA_E, n_EB_E, [z_EA, z_EB, a, f], R_Ee) => {
const expected = await nvectorTestClient.n_EA_E_and_n_EB_E2p_AB_E(
n_EA_E,
n_EB_E,
z_EA,
z_EB,
a,
f,
R_Ee,
);

expect(expected).toMatchObject([
expect.any(Number),
expect.any(Number),
expect.any(Number),
]);

const actual = n_EA_E_and_n_EB_E2p_AB_E(
n_EA_E,
n_EB_E,
z_EA,
z_EB,
a,
f,
R_Ee,
);

expect(actual).toMatchObject([
expect.any(Number),
expect.any(Number),
expect.any(Number),
]);
expect(actual[0]).toBeCloseTo(expected[0], 8);
expect(actual[1]).toBeCloseTo(expected[1], 8);
expect(actual[2]).toBeCloseTo(expected[2], 8);
},
TEST_DURATION + 1000,
);
});

0 comments on commit 46d297e

Please sign in to comment.