use std::f32::consts::PI;
use faer::linalg::solvers::Solve;
pub fn find_xy(a0: f32, b0: f32, c0: f32, a1: f32, b1: f32, c1: f32) -> (f32, f32) {
let a = faer::mat![[a0, b0], [a1, b1]];
let b = faer::mat![[-c0], [-c1]];
let plu = a.partial_piv_lu();
let x1 = plu.solve(&b);
unsafe { (*x1.get_unchecked(0, 0), *x1.get_unchecked(1, 0)) }
}
pub const fn theta_distance_degree(t0: f32, t1: f32) -> f32 {
let mut d = t0 - t1 + 90.0;
if d < 0.0 {
d += 180.0;
} else if d > 180.0 {
d -= 180.0;
}
if d > 90.0 { d - 90.0 } else { 90.0 - d }
}
pub const fn cross(v0: &(f32, f32), v1: &(f32, f32)) -> f32 {
v0.0 * v1.1 - v0.1 * v1.0
}
pub const fn dot(v0: &(f32, f32), v1: &(f32, f32)) -> f32 {
v0.0 * v1.0 + v0.1 * v1.1
}
pub fn angle_degree(v0: &(f32, f32), v1: &(f32, f32)) -> f32 {
(v1.1 * v0.0 - v1.0 * v0.1).atan2(v0.0 * v1.0 + v0.1 * v1.1) * 180.0 / PI
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_find_xy() {
let (x, y) = find_xy(1.0, 1.0, -2.0, 1.0, -1.0, 0.0);
assert!((x - 1.0).abs() < 1e-6);
assert!((y - 1.0).abs() < 1e-6);
}
#[test]
fn test_theta_distance_degree() {
assert!((theta_distance_degree(0.0, 0.0) - 0.0).abs() < 1e-6);
assert!((theta_distance_degree(0.0, 90.0) - 90.0).abs() < 1e-6);
assert!((theta_distance_degree(0.0, 45.0) - 45.0).abs() < 1e-6);
assert!((theta_distance_degree(0.0, 180.0) - 0.0).abs() < 1e-6);
assert!((theta_distance_degree(10.0, 20.0) - 10.0).abs() < 1e-6);
}
#[test]
fn test_cross() {
let v0 = (1.0, 0.0);
let v1 = (0.0, 1.0);
assert!((cross(&v0, &v1) - 1.0).abs() < 1e-6);
assert!((cross(&v1, &v0) - -1.0).abs() < 1e-6);
}
#[test]
fn test_dot() {
let v0 = (1.0, 0.0);
let v1 = (0.0, 1.0);
assert!((dot(&v0, &v1) - 0.0).abs() < 1e-6);
let v2 = (1.0, 1.0);
assert!((dot(&v0, &v2) - 1.0).abs() < 1e-6);
}
#[test]
fn test_angle_degree() {
let v0 = (1.0, 0.0);
let v1 = (0.0, 1.0);
assert!((angle_degree(&v0, &v1) - 90.0).abs() < 1e-6);
let v2 = (1.0, 1.0);
assert!((angle_degree(&v0, &v2) - 45.0).abs() < 1e-6);
}
}