You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

131 lines
2.7 KiB

  1. use std::ops::{Add, Div, Mul, Neg, Sub};
  2. use serde::{Deserialize, Serialize};
  3. pub use super::numeric::{Float, Numeric};
  4. /* Angle */
  5. #[derive(Debug, Clone, Copy)]
  6. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
  7. pub enum Angle<T> {
  8. Deg(T),
  9. Rad(T),
  10. }
  11. impl<T> Angle<T>
  12. where
  13. T: Numeric,
  14. {
  15. pub fn into_inner(self) -> T {
  16. match self {
  17. Self::Deg(v) => v,
  18. Self::Rad(v) => v,
  19. }
  20. }
  21. pub fn into_deg(self) -> Self {
  22. match self {
  23. Self::Deg(v) => Self::Deg(v),
  24. Self::Rad(v) => Self::Rad(T::to_degrees(v)),
  25. }
  26. }
  27. pub fn into_rad(self) -> Self {
  28. match self {
  29. Self::Deg(v) => Self::Deg(T::to_radians(v)),
  30. Self::Rad(v) => Self::Rad(v),
  31. }
  32. }
  33. pub fn abs(self) -> Self {
  34. match self {
  35. Self::Deg(value) => Self::Deg(value.abs()),
  36. Self::Rad(value) => Self::Rad(value.abs()),
  37. }
  38. }
  39. }
  40. impl<T> Angle<T>
  41. where
  42. T: Float,
  43. {
  44. pub fn sin(self) -> T {
  45. T::sin(self.into_rad().into_inner())
  46. }
  47. pub fn cos(self) -> T {
  48. T::cos(self.into_rad().into_inner())
  49. }
  50. }
  51. impl<T> Neg for Angle<T>
  52. where
  53. T: Neg + Numeric,
  54. {
  55. type Output = Angle<T>;
  56. fn neg(self) -> Self::Output {
  57. match self {
  58. Self::Deg(value) => Self::Deg(-value),
  59. Self::Rad(value) => Self::Rad(-value),
  60. }
  61. }
  62. }
  63. impl<T> Add for Angle<T>
  64. where
  65. T: Add<T, Output = T> + Numeric,
  66. {
  67. type Output = Angle<T>;
  68. fn add(self, v: Self) -> Self::Output {
  69. match self {
  70. Self::Deg(value) => Self::Deg(value + v.into_deg().into_inner()),
  71. Self::Rad(value) => Self::Rad(value + v.into_rad().into_inner()),
  72. }
  73. }
  74. }
  75. impl<T> Sub for Angle<T>
  76. where
  77. T: Sub<T, Output = T> + Numeric,
  78. {
  79. type Output = Angle<T>;
  80. fn sub(self, v: Self) -> Self::Output {
  81. match self {
  82. Self::Deg(value) => Self::Deg(value - v.into_deg().into_inner()),
  83. Self::Rad(value) => Self::Rad(value - v.into_rad().into_inner()),
  84. }
  85. }
  86. }
  87. impl<T> Mul<T> for Angle<T>
  88. where
  89. T: Mul<T, Output = T> + Numeric,
  90. {
  91. type Output = Angle<T>;
  92. fn mul(self, factor: T) -> Self::Output {
  93. match self {
  94. Self::Deg(value) => Self::Deg(value * factor),
  95. Self::Rad(value) => Self::Rad(value * factor),
  96. }
  97. }
  98. }
  99. impl<T> Div<T> for Angle<T>
  100. where
  101. T: Div<T, Output = T> + Numeric,
  102. {
  103. type Output = Angle<T>;
  104. fn div(self, factor: T) -> Self::Output {
  105. match self {
  106. Self::Deg(value) => Self::Deg(value / factor),
  107. Self::Rad(value) => Self::Rad(value / factor),
  108. }
  109. }
  110. }