use crate::{Ball, Float, Pi};
use num::{One, Zero};
impl Ball<2> {
pub fn area(&self) -> Float {
self.radius.powi(2) * Pi
}
pub fn perimeter(&self) -> Float {
2. * self.radius * Pi
}
}
impl<const N: usize> Ball<N> {
pub fn unit(center: [Float; N]) -> Self {
Self { center, radius: Float::one() }
}
pub fn volume(&self) -> Float {
let dim = self.center.len() as i32;
let c = match dim % 2 {
0 => Pi.powi(dim / 2) / factorial(dim / 2),
_ => 2.0 * factorial(dim / 2) * (4.0 * Pi).powi(dim / 2) / dim as Float,
};
c * self.radius.powi(dim)
}
pub fn surface_area(&self) -> Float {
let dim = self.center.len() as Float;
dim * self.volume() / self.radius
}
pub fn is_inside(&self, point: [Float; N]) -> bool {
let mut dist = Float::zero();
for (x, y) in self.center.iter().zip(point.iter()) {
dist += (x - y).powi(2);
}
dist <= self.radius.powi(2)
}
}
fn factorial(n: i32) -> Float {
assert!(n > 0);
(1..=n).map(|i| i as Float).product()
}