use crate::Vect;
pub trait Entity {
fn position(&self) -> Vect;
fn velocity(&self) -> Vect;
}
pub trait Shooter: Entity {
fn bullet_speed(&self) -> f32;
}
#[inline]
pub fn predict<S: Shooter, T: Entity>(shooter: &S, target: &T) -> Option<Vect> {
low_predict(shooter.position(), shooter.bullet_speed(), target.velocity() - shooter.velocity(), target.position())
}
#[inline]
pub fn low_predict(s_pos: Vect, s_speed: f32, t_vel: Vect, t_pos: Vect ) -> Option<Vect> {
let d = t_pos - s_pos;
let mut a = t_vel.x * t_vel.x + t_vel.y * t_vel.y - s_speed * s_speed;
let b = 2.0 * (d.x * t_vel.x + d.y * t_vel.y);
let c = d.x * d.x + d.y * d.y;
let cof = b * b - 4.0 * a * c;
if cof < 0.0 {
return None
}
let dis = cof.sqrt();
a *= 2.0;
let (t1, t2) = ((-b + dis) / a, (-b - dis) / a);
if t1 >= 0.0 && (t1 < t2 || t2 < 0.0) {
return Some(t_pos + t_vel * t1);
}
Some(t_pos + t_vel * t2)
}