#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Circle
{
pub position: (f32, f32),
pub radius: f32
}
impl Circle
{
pub fn new(position: (f32, f32), radius: f32) -> Circle
{
return Circle { position, radius };
}
}
impl crate::Shape for Circle
{
fn position(&self) -> (f32, f32)
{
return self.position;
}
fn set_position(&mut self, position: (f32, f32))
{
self.position = position;
}
fn num_axes(&self) -> usize
{
return 1;
}
fn get_axis(&self, _index: usize, target: (f32, f32)) -> (f32, f32)
{
return (target.0 - self.position.0, target.1 - self.position.1);
}
fn project(&self, axis: (f32, f32), normalize: bool) -> (f32, f32)
{
let projection = (self.position.0 * axis.0) + (self.position.1 * axis.1);
let mut magnitude = 1.0;
if !normalize
{
magnitude = f32::sqrt((axis.0 * axis.0) + (axis.1 * axis.1));
}
return (projection - (self.radius * magnitude), projection + (self.radius * magnitude));
}
fn needs_closest(&self, _index: usize) -> bool
{
return true;
}
fn get_closest(&self, _target: (f32, f32)) -> (f32, f32)
{
return self.position;
}
fn point(&self, _index: usize) -> (f32, f32)
{
return self.position;
}
}
#[cfg(test)]
mod circle_tests
{
use super::*;
use crate::{float_equal, Shape};
#[test]
fn test_num_axes()
{
let circle = Circle::new((1.0, 2.0), 3.0);
assert_eq!(circle.num_axes(), 1);
}
#[test]
fn test_get_axis()
{
let circle = Circle::new((2.0, 3.0), 2.0);
let axis1 = circle.get_axis(0, (1.0, 0.0));
let axis2 = circle.get_axis(32, (13.0, 20.0));
assert!(float_equal(axis1.0, -1.0));
assert!(float_equal(axis1.1, -3.0));
assert!(float_equal(axis2.0, 11.0));
assert!(float_equal(axis2.1, 17.0));
}
#[test]
fn test_project()
{
let circle = Circle::new((1.0, 2.0), 2.0);
let axis1 = (1.0, 0.0);
let axis2 = (1.0, 1.0);
let projection1 = circle.project(axis1, true);
let projection2 = circle.project(axis2, false);
assert!(float_equal(projection1.0, -1.0));
assert!(float_equal(projection1.1, 3.0));
assert!(float_equal(projection2.0, 3.0 - 2.0 * f32::sqrt(2.0)));
assert!(float_equal(projection2.1, 3.0 + 2.0 * f32::sqrt(2.0)));
}
#[test]
fn test_needs_closest()
{
let circle = Circle::new((1.0, 2.0), 3.);
assert!(circle.needs_closest(3));
}
}