···1818 Float.is_finite x && Float.is_finite y && Float.is_finite z
1919 && Float.is_finite gmst
2020 then begin
2121- let v = Coordinate.vec3 x y z in
2121+ let v = Vec3.v x y z in
2222 let ecef = Coordinate.teme_to_ecef ~gmst v in
2323 let v' = Coordinate.ecef_to_teme ~gmst ecef in
2424 guard (Float.is_finite v'.x);
···106106107107(** At GMST=0, TEME and ECEF are aligned. *)
108108let test_teme_ecef_zero () =
109109- let v = Coordinate.vec3 1000. 2000. 3000. in
109109+ let v = Vec3.v 1000. 2000. 3000. in
110110 let ecef = Coordinate.teme_to_ecef ~gmst:0. v in
111111 check_float "x" 1e-6 1000. ecef.x;
112112 check_float "y" 1e-6 2000. ecef.y;
···115115(** At GMST=π/2: Rz(π/2)*(1000,0,0) = (0, -1000, 0). ECEF X' = cos θ · X + sin θ
116116 · Y = 0 ECEF Y' = -sin θ · X + cos θ · Y = -1000 *)
117117let test_teme_ecef_90deg () =
118118- let v = Coordinate.vec3 1000. 0. 0. in
118118+ let v = Vec3.v 1000. 0. 0. in
119119 let gmst = Float.pi /. 2. in
120120 let ecef = Coordinate.teme_to_ecef ~gmst v in
121121 check_float "x" 1e-6 0. ecef.x;
···124124125125(** Round-trip: TEME → ECEF → TEME should be identity. *)
126126let test_teme_ecef_roundtrip () =
127127- let v = Coordinate.vec3 6524.834 6862.875 6448.296 in
127127+ let v = Vec3.v 6524.834 6862.875 6448.296 in
128128 let gmst = 1.7 in
129129 let ecef = Coordinate.teme_to_ecef ~gmst v in
130130 let v' = Coordinate.ecef_to_teme ~gmst ecef in
···134134135135(** Rotation preserves vector length. *)
136136let test_rotation_preserves_length () =
137137- let v = Coordinate.vec3 7000. 1000. 3000. in
138138- let r0 = Coordinate.vec3_length v in
137137+ let v = Vec3.v 7000. 1000. 3000. in
138138+ let r0 = Vec3.length v in
139139 let ecef = Coordinate.teme_to_ecef ~gmst:2.345 v in
140140- let r1 = Coordinate.vec3_length ecef in
140140+ let r1 = Vec3.length ecef in
141141 check_float "length preserved" 1e-6 r0 r1
142142143143(* ================================================================== *)
···147147(** Point on equator at prime meridian: lat=0, lon=0, alt=0. ECEF = (a, 0, 0)
148148 where a = earth_radius. *)
149149let test_geodetic_equator_pm () =
150150- let v = Coordinate.vec3 Coordinate.earth_radius 0. 0. in
150150+ let v = Vec3.v Coordinate.earth_radius 0. 0. in
151151 let g = Coordinate.ecef_to_geodetic v in
152152 check_float "lat" 0.01 0. g.lat;
153153 check_float "lon" 0.01 0. g.lon;
···157157 a*(1-f). *)
158158let test_geodetic_north_pole () =
159159 let b = Coordinate.earth_radius *. (1. -. Coordinate.earth_flattening) in
160160- let v = Coordinate.vec3 0. 0. b in
160160+ let v = Vec3.v 0. 0. b in
161161 let g = Coordinate.ecef_to_geodetic v in
162162 check_float "north pole lat" 0.01 90. g.lat;
163163 check_float "north pole alt" 1. 0. g.alt
164164165165(** Point at lon=90°E on equator: ECEF = (0, a, 0). *)
166166let test_geodetic_lon90 () =
167167- let v = Coordinate.vec3 0. Coordinate.earth_radius 0. in
167167+ let v = Vec3.v 0. Coordinate.earth_radius 0. in
168168 let g = Coordinate.ecef_to_geodetic v in
169169 check_float "lat" 0.01 0. g.lat;
170170 check_float "lon" 0.01 90. g.lon
···205205let test_geodetic_iss_altitude () =
206206 (* ISS at ~408 km, circular orbit, position along X axis *)
207207 let r = Coordinate.earth_radius +. 408. in
208208- let v = Coordinate.vec3 r 0. 0. in
208208+ let v = Vec3.v r 0. 0. in
209209 let g = Coordinate.ecef_to_geodetic v in
210210 check_float "ISS alt" 5. 408. g.alt;
211211 check_float "ISS lat" 0.1 0. g.lat
···214214let test_geodetic_geo_altitude () =
215215 let r = 42164.0 in
216216 (* GEO radius *)
217217- let v = Coordinate.vec3 r 0. 0. in
217217+ let v = Vec3.v r 0. 0. in
218218 let g = Coordinate.ecef_to_geodetic v in
219219 let expected_alt = r -. Coordinate.earth_radius in
220220 check_float "GEO alt" 5. expected_alt g.alt
···223223 6862.875, 6448.296) km Expected: lat ≈ 34.35°, lon ≈ 46.45°, alt ≈ 5085 km.
224224*)
225225let test_vallado_3_3 () =
226226- let v = Coordinate.vec3 6524.834 6862.875 6448.296 in
226226+ let v = Vec3.v 6524.834 6862.875 6448.296 in
227227 let g = Coordinate.ecef_to_geodetic v in
228228 (* Approximate — the example uses a different reference ellipsoid *)
229229- let r = Coordinate.vec3_length v in
229229+ let r = Vec3.length v in
230230 Alcotest.(check (float 0.001)) "radius" 11456.572 r;
231231 Alcotest.(check (float 0.5)) "lat" 34.25 g.lat;
232232 Alcotest.(check (float 50.)) "alt" 5078. g.alt
···238238(** TEME position at equator, GMST=0, should give lon≈0. *)
239239let test_teme_geodetic_equator () =
240240 let r = Coordinate.earth_radius +. 400. in
241241- let v = Coordinate.vec3 r 0. 0. in
241241+ let v = Vec3.v r 0. 0. in
242242 let g = Coordinate.teme_to_geodetic ~gmst:0. v in
243243 check_float "equator lat" 0.1 0. g.lat;
244244 check_float "equator lon" 0.1 0. g.lon
···246246(** TEME position at equator with GMST=π/2: lon should shift by -90°. *)
247247let test_teme_geodetic_gmst_shift () =
248248 let r = Coordinate.earth_radius +. 400. in
249249- let v = Coordinate.vec3 r 0. 0. in
249249+ let v = Vec3.v r 0. 0. in
250250 let g0 = Coordinate.teme_to_geodetic ~gmst:0. v in
251251 let g90 = Coordinate.teme_to_geodetic ~gmst:(Float.pi /. 2.) v in
252252 let dlon = g0.lon -. g90.lon in