@@ -20,60 +20,38 @@ def __init__(self, x, y, z):
2020 self .y = y
2121 self .z = z
2222
23+ # tiny constant
24+ EPSILON = 1e-12
25+
2326 # cylindrical coordinates
2427 self .rh = np .sqrt (self .x ** 2 + self .y ** 2 )
25- # rtheta is defined between [-pi; pi] and is 0 for x = y = 0
26- self .r_theta = np .atan2 (self .y , self .x )
28+ self .rh_not0 = np .where (self .rh != 0 , self .rh , EPSILON )
2729
2830 # spherical coordinates
29- self .r = np .sqrt (self .x ** 2 + self .y ** 2 + self .z ** 2 )
31+ r = np .sqrt (self .x ** 2 + self .y ** 2 + self .z ** 2 )
32+ self .r_not0 = np .where (r != 0 , r , EPSILON )
3033
31- def compute_cylindrical_components (self , vx , vy , vz ):
32- """
33- Convert (vx, vy, vz) in cylindrical coordinates (vh, vt, vz)
34- """
34+ def compute_r_theta (self ):
35+ """r_theta is defined between [-pi; pi] and is 0 for x = y = 0"""
36+ return np .atan2 (self .y , self .x )
3537
36- with np .errstate (divide = "ignore" , invalid = "ignore" ):
37- vh = np .where (self .rh != 0 , (self .x * vx + self .y * vy ) / self .rh , 0 )
38- vt = np .where (self .rh != 0 , (- self .y * vx + self .x * vy ) / self .rh , 0 )
38+ def compute_cylindrical_components (self , vx , vy , vz ):
39+ """Convert (vx, vy, vz) in cylindrical coordinates (vh, vt, vz)"""
3940
41+ vh = (self .x * vx + self .y * vy ) / self .rh_not0
42+ vt = (- self .y * vx + self .x * vy ) / self .rh_not0
4043 return vh , vt , vz
4144
4245 def compute_radial_component (self , vx , vy , vz ):
43- """
44- Compute radial component vr along r
45- """
46-
47- with np .errstate (divide = "ignore" , invalid = "ignore" ):
48- vr = np .where (
49- self .r != 0 , (self .x * vx + self .y * vy + self .z * vz ) / self .r , 0
50- )
51-
52- return vr
46+ """Compute radial component"""
47+ return (self .x * vx + self .y * vy + self .z * vz ) / self .r_not0
5348
5449 def compute_spherical_components (self , vx , vy , vz ):
55- """
56- Convert vx, vy, vz in spherical coordinates (vr, vt, vp)
57- """
58-
59- with np .errstate (divide = "ignore" , invalid = "ignore" ):
60- self .rp = np .where (
61- self .r != 0 , np .arccos (np .clip (self .z / self .r , - 1 , 1 )), 0
62- )
63-
64- vr = np .where (
65- self .r != 0 , (self .x * vx + self .y * vy + self .z * vz ) / self .r , 0
66- )
67-
68- vt = np .where (self .rh != 0 , (- self .y * vx + self .x * vy ) / self .rh , 0 )
69-
70- vp = np .where (
71- self .r != 0 ,
72- (self .z * (self .x * vx + self .y * vy ) - self .rh ** 2 * vz )
73- / (self .r * self .rh ),
74- 0 ,
75- )
76- # Alternative for vp when rh = 0
77- vp = np .where (self .rh != 0 , vp , 0 )
78-
50+ """Convert (vx, vy, vz) in spherical coordinates (vr, vt, vp)"""
51+ vr = self .compute_radial_component (vx , vy , vz )
52+ vt = (- self .y * vx + self .x * vy ) / self .rh_not0
53+ vp = (
54+ (self .z * (self .x * vx + self .y * vy ) - self .rh ** 2 * vz )
55+ / (self .r_not0 * self .rh_not0 ),
56+ )
7957 return vr , vt , vp
0 commit comments