rfa/vector_matrix/spherical_cartesian/pv2s.rs
1
2use crate::utils::*;
3/// Convert position/velocity from Cartesian to spherical coordinates.
4///
5/// Given:
6/// * pv pv-vector
7///
8/// Returned:
9/// * theta double longitude angle (radians)
10/// * phi double latitude angle (radians)
11/// * r double radial distance
12/// * td double rate of change of theta
13/// * pd double rate of change of phi
14/// * rd double rate of change of r
15///
16/// Notes:
17/// * If the position is a pole, theta, td and pd are indeterminate.
18/// In such cases zeroes are returned for all three.
19///
20/// This revision: 2021 May 11
21pub fn pv2s(pv: &[[f64; 3]; 2], theta: &mut f64, phi: &mut f64, r: &mut f64,
22 td: &mut f64, pd: &mut f64 , rd:& mut f64)
23{
24 /* Components of position/velocity vector. */
25 let mut x = pv[0][0];
26 let mut y = pv[0][1];
27 let mut z = pv[0][2];
28 let xd = pv[1][0];
29 let yd = pv[1][1];
30 let zd = pv[1][2];
31
32 /* Component of r in XY plane squared. */
33 let mut rxy2 = x*x + y*y;
34
35 /* Modulus squared. */
36 let mut r2 = rxy2 + z*z;
37
38 /* Modulus. */
39 let rtrue = r2.sqrt();
40
41 /* If null vector, move the origin along the direction of movement. */
42 let mut rw = rtrue;
43 if rtrue == 0.0 {
44 x = xd;
45 y = yd;
46 z = zd;
47 rxy2 = x*x + y*y;
48 r2 = rxy2 + z*z;
49 rw = r2.sqrt();
50 }
51
52 /* Position and velocity in spherical coordinates. */
53 let rxy = sqrt(rxy2);
54 let xyp = x*xd + y*yd;
55 if rxy2 != 0.0 {
56 *theta = atan2(y, x);
57 *phi = atan2(z, rxy);
58 *td = (x*yd - y*xd) / rxy2;
59 *pd = (zd*rxy2 - z*xyp) / (r2*rxy);
60 } else {
61 *theta = 0.0;
62 *phi = if z != 0.0{atan2(z, rxy)}else{ 0.0};
63 *td = 0.0;
64 *pd = 0.0;
65 }
66 *r = rtrue;
67 *rd = if rw != 0.0{ (xyp + z*zd) / rw } else { 0.0 };
68
69 /* Finished. */
70
71}