Files
2026-05-27 23:29:53 +01:00

87 lines
3.5 KiB
Markdown

## ADDED Requirements
### Requirement: Ellipsoid definition
The system SHALL provide a way to define an ellipsoid from semi-major and semi-minor axes, deriving flattening and eccentricity automatically.
#### Scenario: Define WGS84 ellipsoid
- **WHEN** `defineEllipsoid(6378137, 6356752.314245)` is called
- **THEN** the returned `Ellipsoid` has `semiMajorAxis = 6378137`, `semiMinorAxis = 6356752.314245`, and derived `flattening` and `eccentricity` within floating-point tolerance
### Requirement: Spherical coordinate conversion
The system SHALL convert between spherical coordinates (latitude, longitude, altitude) and Cartesian vectors.
#### Scenario: Convert spherical to Cartesian and back
- **WHEN** a `SphericalCoord` with `latitude = 51.5074`, `longitude = -0.1278`, `altitude = 0` is converted to Cartesian via `sphericalToCartesian` using a WGS84 ellipsoid
- **THEN** converting the result back via `cartesianToSpherical` yields the original coordinates within `0.0001` degrees
### Requirement: Great-circle distance
The system SHALL compute great-circle distance between two spherical coordinates on a given ellipsoid.
#### Scenario: Distance between London and Paris
- **WHEN** `greatCircleDistance` is called with London (`51.5074, -0.1278`) and Paris (`48.8566, 2.3522`) on WGS84
- **THEN** the result is approximately `344000` metres
### Requirement: Vincenty distance
The system SHALL compute geodesic distance using Vincenty's formulae for high precision.
#### Scenario: Vincenty vs great-circle consistency
- **WHEN** both `greatCircleDistance` and `vincentyDistance` are called for the same nearby points (< 100 km)
- **THEN** the results differ by less than `0.1%`
### Requirement: Bearing and destination
The system SHALL compute initial bearing between two points and compute a destination point given start, bearing, and distance.
#### Scenario: Round-trip destination
- **WHEN** `destination(start, bearing, distance, ellipsoid)` is called
- **AND** `bearing` is computed from `start` to a known `end`
- **THEN** the computed destination equals `end` within `0.0001` degrees
### Requirement: Bounding boxes
The system SHALL provide bounding box creation, point containment, expansion, merging, and intersection.
#### Scenario: Box contains point
- **WHEN** a `BoundingBox` spanning `(-10, -10)` to `(10, 10)` is created
- **THEN** `containsPoint(box, { latitude: 0, longitude: 0 })` returns `true`
- **AND** `containsPoint(box, { latitude: 20, longitude: 0 })` returns `false`
### Requirement: Polygon operations
The system SHALL provide point-in-polygon, polygon area, perimeter, and simplification.
#### Scenario: Point inside a square polygon
- **WHEN** a square polygon with vertices at `(0,0)`, `(0,10)`, `(10,10)`, `(10,0)` is defined
- **THEN** `pointInPolygon({ latitude: 5, longitude: 5 }, polygon)` returns `true`
- **AND** `pointInPolygon({ latitude: 15, longitude: 5 }, polygon)` returns `false`
### Requirement: Distance unit conversion
The system SHALL convert distances between metres, kilometres, miles, and nautical miles.
#### Scenario: Convert metres to kilometres
- **WHEN** `convertDistance(1000, 'metre', 'kilometre')` is called
- **THEN** the result equals `1`
### Requirement: No planet-specific constants
The system SHALL NOT export any numeric constant for a specific celestial body.
#### Scenario: Inspect geo exports
- **WHEN** all exports from `@suaveplan/geo` are enumerated
- **THEN** no export named `EARTH`, `MARS`, `MOON`, or similar exists
- **AND** no hardcoded radius, mass, or orbital value for any body is present