use nalgebra::{Matrix3, Vector3, Point3, Isometry3};
pub type Transform3d = Isometry3<f64>;
pub type RotationMatrix = Matrix3<f64>;
pub type TranslationVector = Vector3<f64>;
pub type Point3d = Point3<f64>;
pub type Vector3d = Vector3<f64>;
pub mod constants {
pub const PI: f64 = std::f64::consts::PI;
pub const TAU: f64 = 2.0 * PI;
pub const HALF_PI: f64 = PI / 2.0;
pub const DEG_TO_RAD: f64 = PI / 180.0;
pub const RAD_TO_DEG: f64 = 180.0 / PI;
pub const EPS: f64 = 1e-10;
}
pub fn deg_to_rad(degrees: f64) -> f64 {
degrees * constants::DEG_TO_RAD
}
pub fn rad_to_deg(radians: f64) -> f64 {
radians * constants::RAD_TO_DEG
}
pub fn approx_equal(a: f64, b: f64, eps: f64) -> bool {
(a - b).abs() < eps
}
pub fn normalize_angle(angle: f64) -> f64 {
let mut normalized = angle % constants::TAU;
if normalized > constants::PI {
normalized -= constants::TAU;
} else if normalized < -constants::PI {
normalized += constants::TAU;
}
if (normalized - constants::PI).abs() < constants::EPS {
normalized = -constants::PI;
} else if (normalized + constants::PI).abs() < constants::EPS {
normalized = constants::PI;
}
normalized
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_angle_conversion() {
let degrees = 90.0;
let radians = deg_to_rad(degrees);
assert!(approx_equal(radians, constants::HALF_PI, constants::EPS));
let back_to_degrees = rad_to_deg(radians);
assert!(approx_equal(back_to_degrees, degrees, constants::EPS));
}
#[test]
fn test_normalize_angle() {
assert!(approx_equal(normalize_angle(3.0 * constants::PI), -constants::PI, constants::EPS));
assert!(approx_equal(normalize_angle(-3.0 * constants::PI), constants::PI, constants::EPS));
assert!(approx_equal(normalize_angle(constants::PI / 2.0), constants::PI / 2.0, constants::EPS));
}
#[test]
fn test_approx_equal() {
assert!(approx_equal(1.0, 1.0 + constants::EPS / 2.0, constants::EPS));
assert!(!approx_equal(1.0, 1.0 + constants::EPS * 2.0, constants::EPS));
}
}