cvmath/
polar.rs

1use super::*;
2
3/// Polar coordinates.
4#[derive(Copy, Clone, Default, PartialEq)]
5#[repr(C)]
6pub struct Polar<T> {
7	pub radius: T,
8	pub theta: Angle<T>,
9}
10
11/// Polar constructor.
12#[allow(non_snake_case)]
13#[inline]
14pub const fn Polar<T>(radius: T, theta: Angle<T>) -> Polar<T> {
15	Polar { radius, theta }
16}
17
18#[cfg(feature = "dataview")]
19unsafe impl<T: dataview::Pod> dataview::Pod for Polar<T> {}
20
21impl<T> Polar<T> {
22	/// Constructs a new polar coordinate from components.
23	#[inline]
24	pub const fn new(radius: T, theta: Angle<T>) -> Polar<T> {
25		Polar { radius, theta }
26	}
27}
28
29impl<T: Float> Polar<T> {
30	#[inline]
31	pub fn complex(self) -> Complex<T> {
32		let (re, im) = self.theta.sin_cos();
33		Complex {
34			re: self.radius * re,
35			im: self.radius * im,
36		}
37	}
38}
39
40//----------------------------------------------------------------
41// Operators
42
43impl<T: ops::Mul<Output = T> + ops::Add<Output = T>> ops::Mul<Polar<T>> for Polar<T> {
44	type Output = Polar<T>;
45
46	#[inline]
47	fn mul(self, rhs: Polar<T>) -> Polar<T> {
48		Polar {
49			radius: self.radius * rhs.radius,
50			theta: self.theta + rhs.theta,
51		}
52	}
53}
54
55macro_rules! impl_fmt {
56	($fmt:path) => {
57		impl<T: $fmt> $fmt for Polar<T> where Angle<T>: $fmt {
58			fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59				self.radius.fmt(f)?;
60				let symbol = if f.alternate() { " angle " } else { " ∠ " };
61				f.write_str(symbol)?;
62				<Angle<T> as $fmt>::fmt(&self.theta, f)
63			}
64		}
65	};
66}
67
68impl_fmt!(fmt::Display);
69impl_fmt!(fmt::Debug);
70impl_fmt!(fmt::Binary);
71impl_fmt!(fmt::Octal);
72impl_fmt!(fmt::LowerHex);
73impl_fmt!(fmt::UpperHex);
74impl_fmt!(fmt::LowerExp);
75impl_fmt!(fmt::UpperExp);
76
77//----------------------------------------------------------------
78// Serialization
79
80#[cfg(feature = "serde")]
81impl<T: serde::Serialize + 'static> serde::Serialize for Polar<T> {
82	fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
83		use serde::ser::SerializeTupleStruct;
84		let mut state = serializer.serialize_tuple_struct("Polar", 2)?;
85		state.serialize_field(&self.radius)?;
86		state.serialize_field(&self.theta)?;
87		state.end()
88	}
89}
90
91#[cfg(feature = "serde")]
92impl<'de, T: serde::Deserialize<'de> + 'static> serde::Deserialize<'de> for Polar<T> {
93	fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
94		let (radius, theta) = {
95			#[derive(serde::Deserialize)]
96			struct Polar<T: 'static>(T, Angle<T>);
97			let Polar(radius, theta) = Polar::<T>::deserialize(deserializer)?;
98			(radius, theta)
99		};
100		Ok(Polar { radius, theta })
101	}
102}