use num::Zero;
use alga::general::Real;
use alga::linear::FiniteDimVectorSpace;
use na::{self, Unit};
use math::Point;
use query::Contact;
use shape::Ball;
/// Contact between balls.
#[inline]
pub fn ball_against_ball
(
center1: &P,
b1: &Ball,
center2: &P,
b2: &Ball,
prediction: P::Real,
) -> Option>
where
P: Point,
{
let r1 = b1.radius();
let r2 = b2.radius();
let delta_pos = *center2 - *center1;
let distance_squared = na::norm_squared(&delta_pos);
let sum_radius = r1 + r2;
let sum_radius_with_error = sum_radius + prediction;
if distance_squared < sum_radius_with_error * sum_radius_with_error {
let mut normal = Unit::new_normalize(delta_pos);
if distance_squared.is_zero() {
normal = Unit::new_unchecked(P::Vector::canonical_basis_element(0));
}
Some(Contact::new(
*center1 + *normal * r1,
*center2 + (-*normal * r2),
normal,
sum_radius - distance_squared.sqrt(),
))
} else {
None
}
}