use crate::angle::Angle;
use nalgebra::RealField;
use quickcheck::{Arbitrary, Gen};
use rand::Rng;
#[quickcheck]
fn test_sin(angle: f64) {
let sin: f64 = Angle::from(angle).sin();
assert!((angle.sin() - sin).abs() < 0.00000000000001);
}
#[quickcheck]
fn test_cos(angle: f64) {
let cos: f64 = Angle::from(angle).cos::<f64>();
assert!((angle.cos() - cos).abs() < 0.00000000000001);
}
#[quickcheck]
fn test_tan(angle: f64) {
let tan: f64 = Angle::from(angle).tan();
let pass = (angle.tan() - tan).abs() < 0.000001;
if !pass {
if (angle.tan() > 1000.0 && tan > 1000.0) ||
(angle.tan() < -1000.0 && tan < -1000.0) { return;
}
println!("angle : {:?}", angle);
println!("mine : {:?}", tan);
println!("theirs: {:?}", angle.tan());
assert!(pass);
}
}
#[derive(Copy, Clone, PartialEq, PartialOrd, Debug, Default)]
struct SmallFloat {
x: f64
}
impl Arbitrary for SmallFloat {
fn arbitrary<G: Gen>(g: &mut G) -> Self {
SmallFloat { x: g.gen_range(-1.0, 1.0) }
}
}
#[quickcheck]
fn test_acos(x: SmallFloat) {
let x = x.x;
let angle: f64 = Angle::acos(x).into();
let other = x.acos();
if (angle - other).abs() >= 0.0000000000001 {
println!("Angle: {}\nMine : {}\nTheirs: {}\n", x, angle, other);
assert!(false);
}
}
#[quickcheck]
fn test_asin(x: SmallFloat) {
let x = x.x;
let angle: f64 = Angle::asin(x).into();
let other = x.asin();
if (angle - other).abs() >= 0.0000000000001 {
println!("Angle: {}\nMine : {}\nTheirs: {}\n", x, angle, other);
assert!(false);
}
}
#[quickcheck]
fn test_atan(x: f64) {
let angle: f64 = Angle::atan(x).into();
let other = x.atan();
if (angle - other).abs() >= 0.0000000000001 {
println!("Angle: {}\nMine : {}\nTheirs: {}\n", x, angle, other);
assert!(false);
}
}
#[quickcheck]
fn test_atan2(x: SmallFloat, y: SmallFloat) {
let x = x.x;
let y = y.x;
if x == 0.0 && y == 0.0 {
return;
}
let angle: f64 = Angle::atan2(y, x).unwrap().into();
let other = f64::atan2(y, x);
if (angle - other).abs() >= 0.000000000000001 {
println!("x: {}, y: {}\nMine : {}\nTheirs: {}\n", x, y, angle, other);
assert!(false);
}
}
#[quickcheck]
fn test_angle(angle: f64) {
let angle = if angle < 0.0 {
-(-angle).rem_euclid(f64::two_pi())
} else if angle > 0.0 {
angle.rem_euclid(f64::two_pi())
} else {
angle
};
let s = Angle::from(angle);
let pass = (s.into::<f64>() - angle).abs() < 0.00000000000001;
if !pass {
println!("start: {:?}", angle);
println!("end : {:?}", s.into::<f64>());
println!("middle: {:?}", s);
assert!(pass);
}
}
fn range_reduce(f: f64) -> f64 {
if f < 0.0 {
-(-f).rem_euclid(f64::two_pi())
} else if f > 0.0 {
f.rem_euclid(f64::two_pi())
} else {
f
}
}
#[quickcheck]
fn test_add(angle1: f64, angle2: f64) {
let angle1 = range_reduce(angle1);
let angle2 = range_reduce(angle2);
let angle = range_reduce(angle1 + angle2);
let a1 = Angle::from(angle1);
let a2 = Angle::from(angle2);
let result = a1 + a2;
let result_f64 = result.into::<f64>();
let pass = (result_f64 - angle).abs() < 0.0000000000001;
if !pass {
println!("angle1 : {:?}", angle1);
println!("angle2 : {:?}", angle2);
println!("correct: {:?}", angle);
println!("mine : {:?}", result_f64);
assert!(pass);
}
}