euclid/trig.rs
1// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10/// Trait for basic trigonometry functions, so they can be used on generic numeric types
11pub trait Trig {
12 fn sin(self) -> Self;
13 fn cos(self) -> Self;
14 fn tan(self) -> Self;
15 fn fast_atan2(y: Self, x: Self) -> Self;
16 fn degrees_to_radians(deg: Self) -> Self;
17 fn radians_to_degrees(rad: Self) -> Self;
18}
19
20macro_rules! trig {
21 ($ty:ident) => (
22 impl Trig for $ty {
23 #[inline]
24 fn sin(self) -> $ty { self.sin() }
25 #[inline]
26 fn cos(self) -> $ty { self.cos() }
27 #[inline]
28 fn tan(self) -> $ty { self.tan() }
29
30 /// A slightly faster approximation of `atan2`.
31 ///
32 /// Note that it does not deal with the case where both x and y are 0.
33 #[inline]
34 fn fast_atan2(y: $ty, x: $ty) -> $ty {
35 // This macro is used with f32 and f64 and clippy warns about the extra
36 // precision with f32.
37 #![cfg_attr(feature = "cargo-clippy", allow(excessive_precision))]
38
39 // See https://math.stackexchange.com/questions/1098487/atan2-faster-approximation#1105038
40 use core::$ty::consts;
41 let x_abs = x.abs();
42 let y_abs = y.abs();
43 let a = x_abs.min(y_abs) / x_abs.max(y_abs);
44 let s = a * a;
45 let mut result = ((-0.046_496_474_9 * s + 0.159_314_22) * s - 0.327_622_764) * s * a + a;
46 if y_abs > x_abs {
47 result = consts::FRAC_PI_2 - result;
48 }
49 if x < 0.0 {
50 result = consts::PI - result
51 }
52 if y < 0.0 {
53 result = -result
54 }
55
56 result
57 }
58
59 #[inline]
60 fn degrees_to_radians(deg: Self) -> Self {
61 deg.to_radians()
62 }
63
64 #[inline]
65 fn radians_to_degrees(rad: Self) -> Self {
66 rad.to_degrees()
67 }
68 }
69 )
70}
71
72trig!(f32);
73trig!(f64);