use std::ops::Add;
#[derive(Debug, Clone, Copy)]
pub struct ResActive(pub f64);
#[derive(Debug, Clone, Copy)]
pub struct ResReactive(pub f64);
#[derive(Debug, Clone, Copy)]
pub struct Pos2 {
pub x: f64,
pub y: f64,
}
impl Add for Pos2 {
type Output = Pos2;
fn add(self, rhs: Self) -> Self::Output {
Pos2 {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct Circle {
pub center: Pos2,
pub radius: f64,
}
#[derive(Debug, Clone, Copy)]
pub struct Angle(pub f64);
pub fn resistance_to_xy(res: ResActive, react: ResReactive, radius: f64) -> Pos2 {
let cx = {
let r = res.0;
let x = react.0;
let a = (r.powi(2) - 1. + x.powi(2)) / ((r + 1.0).powi(2) + x.powi(2));
a * radius + radius
};
let cy = {
let r = res.0;
let x = react.0;
let b = (2. * x) / ((r + 1.).powi(2) + x.powi(2));
-b * radius + radius
};
Pos2 { x: cx, y: cy }
}
pub fn res_circle(res: ResActive, radius: f64) -> Circle {
let cx = { res.0 * radius / (res.0 + 1.) + radius };
let cy = { radius };
let r = { radius / (res.0 + 1.) };
let pos = Pos2 { x: cx, y: cy };
Circle {
center: pos,
radius: r,
}
}
pub fn react_circle(react: ResReactive, radius: f64) -> Circle {
let magnitude = { react.0.abs() };
let cx = { radius + radius };
let cy = { radius / react.0 + radius };
let r = { radius / magnitude };
let pos = Pos2 { x: cx, y: cy };
Circle {
center: pos,
radius: r,
}
}
pub fn xy_to_resistance(xy: &Pos2) -> (ResActive, ResReactive) {
let b = xy.y;
let a = xy.x;
let x = (2. * b) / (a.powi(2) - 2. * a + b.powi(2) + 1.);
let r = {
let x = x.abs();
let b = b.abs();
let r = ((-b * x * (b * x - 2.)).sqrt() - b) / b;
r
};
(ResActive(r), ResReactive(x))
}