Skip to main content

coord_transforms/
d2.rs

1use ::std;
2use na::Vector2;
3
4/// Converts 2-d polar coordinates to 2-d cartesian coordinates
5/// 
6/// # Arguments
7/// 
8/// * `pol_vec` - Vector2 reference to the polar vector (rho, theta) - theta in radians
9/// 
10/// # Return Value
11/// 
12/// * `nalgebra::Vector2<f64>` - x, y
13/// 
14/// # Formula
15/// 
16/// * x = rho * cos(theta)
17/// * y = rho * sin(theta)
18pub fn polar2cartesian(pol_vec: &Vector2<f64>) -> Vector2<f64> {
19	let mut ret_vec: Vector2<f64> = Vector2::new(0.0, 0.0);
20	ret_vec.x = pol_vec.x * pol_vec.y.cos();
21	ret_vec.y = pol_vec.x * pol_vec.y.sin();
22	ret_vec
23}
24
25/// Converts 2-d log polar coordinates to 2-d cartesian coordinates
26/// 
27/// # Arguments
28/// 
29/// * `logpol_vec` - Vector2 reference to the log polar vector (rho, theta) in radians
30/// 
31/// # Return Value
32/// 
33/// * `nalgebra::Vector2<f64>` - x, y
34/// 
35/// # Formula
36/// 
37/// * x = e^rho * cos(theta)
38/// * y = e^rho * sin(theta)
39pub fn logpolar2cartesian(logpol_vec: &Vector2<f64>) -> Vector2<f64> {
40	let mut ret_vec: Vector2<f64> = Vector2::new(0.0, 0.0);
41	ret_vec.x = std::f64::consts::E.powf(logpol_vec.x) * logpol_vec.y.cos();
42	ret_vec.y = std::f64::consts::E.powf(logpol_vec.x) * logpol_vec.y.sin();
43	ret_vec
44}
45
46/// Converts 2-d bipolar coordinates to 2-d cartesian coordinates
47/// 
48/// # Arguments
49/// 
50/// * `bipol_vec` - Vector2 reference to the bipolar vector (sigma, tau) in radians
51/// * `a` - f64 value for foci points (-a, 0) and (a, 0)
52/// 
53/// # Return Value
54/// 
55/// * `nalgebra::Vector2<f64>` - x, y
56/// 
57/// # Formula
58/// 
59/// * x = a * ((sinh(tau)) / (cosh(tau) - cos(sigma)))
60/// * y = a * ((sin(sigma)) / (cosh(tau) - cos(sigma)))
61pub fn bipolar2cartesian(bipol_vec: &Vector2<f64>, a: f64) -> Vector2<f64> {
62	let mut ret_vec: Vector2<f64> = Vector2::new(0.0, 0.0);
63	ret_vec.x = a * ((bipol_vec.y.sinh()) / (bipol_vec.y.cosh() - bipol_vec.x.cos()));
64	ret_vec.y = a * ((bipol_vec.x.sin()) / (bipol_vec.y.cosh() - bipol_vec.x.cos()));
65	ret_vec
66}
67
68
69/// Converts 2-d cartesian coordinates to 2-d polar coordinates
70/// 
71/// # Arguments
72/// 
73/// * `cart_vec` - Vector2 reference to the cartesian vector (x, y)
74/// 
75/// # Return Value
76/// 
77/// * `nalgebra::Vector2<f64>` - rho, theta (in radians)
78/// 
79/// # Formula
80/// 
81/// * r = sqrt( x^2 + y^2 )
82/// * theta = arctan(y / x)
83pub fn cartesian2polar(cart_vec: &Vector2<f64>) -> Vector2<f64> {
84	let mut ret_vec: Vector2<f64> = Vector2::new(0.0, 0.0);
85	ret_vec.x = (cart_vec.x.powi(2) + cart_vec.y.powi(2)).sqrt();
86	ret_vec.y = cart_vec.y.atan2(cart_vec.x);
87	ret_vec
88}
89
90/// Converts 2-d cartesian coordinates to 2-d log polar coordinates
91/// 
92/// # Arguments
93/// 
94/// * `cart_vec` - Vector2 reference to the cartesian vector (x, y)
95/// 
96/// # Return Value
97/// 
98/// * `nalgebra::Vector2<f64>` - rho, theta (in radians)
99/// 
100/// # Formula
101/// 
102/// * r = log(sqrt( x^2 + y^2 ))
103/// * theta = arctan(y / x)
104pub fn cartesian2logpolar(cart_vec: &Vector2<f64>) -> Vector2<f64> {
105	let mut ret_vec: Vector2<f64> = Vector2::new(0.0, 0.0);
106	ret_vec.x = ((cart_vec.x.powi(2) + cart_vec.y.powi(2)).sqrt()).ln();
107	ret_vec.y = cart_vec.y.atan2(cart_vec.x);
108	ret_vec
109}
110
111//Unit tests
112#[cfg(test)]
113mod tests {
114	use super::*;
115    use float_cmp::ApproxEqUlps;
116	#[test]
117	fn test_polar2cartesian() {
118        let pol_vec: Vector2<f64> = Vector2::new(3.0, 4.0);
119        let cart_vec = polar2cartesian(&pol_vec);
120
121        let test_x = -1.960930862590836;
122        let test_y = -2.2704074859237844;
123        assert!(cart_vec.x.approx_eq_ulps(&test_x, 2));
124        assert!(cart_vec.y.approx_eq_ulps(&test_y, 2));
125    }
126    #[test]
127    fn test_logpolar2cartesian() {
128        let logpol_vec: Vector2<f64> = Vector2::new(3.0, 4.0);
129        let cart_vec = logpolar2cartesian(&logpol_vec);
130
131        let test_x = -13.128783081462156;
132        let test_y = -15.20078446306795;
133        assert!(cart_vec.x.approx_eq_ulps(&test_x, 2));
134        assert!(cart_vec.y.approx_eq_ulps(&test_y, 2));
135    }
136    #[test]
137    fn test_bipolar2cartesian() {
138        let bipol_vec: Vector2<f64> = Vector2::new(3.0, 4.0);
139        let cart_vec = bipolar2cartesian(&bipol_vec, 1.0);
140
141        let test_x = 0.9643685028429331;
142        let test_y = 0.004986885446035738;
143        assert!(cart_vec.x.approx_eq_ulps(&test_x, 2));
144        assert!(cart_vec.y.approx_eq_ulps(&test_y, 2));
145    }
146    #[test]
147    fn test_cartesian2polar() {
148        let cart_vec: Vector2<f64> = Vector2::new(3.0, 4.0);
149        let polar_vec = cartesian2polar(&cart_vec);
150
151        let test_x = 5.0;
152        let test_y = 0.9272952180016122;
153        assert!(polar_vec.x.approx_eq_ulps(&test_x, 2));
154        assert!(polar_vec.y.approx_eq_ulps(&test_y, 2));
155    }
156	#[test]
157    fn test_cartesian2logpolar() {
158        let cart_vec: Vector2<f64> = Vector2::new(3.0, 4.0);
159        let logpolar_vec = cartesian2logpolar(&cart_vec);
160
161        let test_x = 1.6094379124341003;
162        let test_y = 0.9272952180016122;
163        assert!(logpolar_vec.x.approx_eq_ulps(&test_x, 2));
164        assert!(logpolar_vec.y.approx_eq_ulps(&test_y, 2));
165    }
166}