use num::{Bounded, Float};
use std::convert::{AsMut, AsRef, TryInto};
use std::fmt::Debug;
use std::ops::{Deref, DerefMut};
use crate::FP;
#[derive(Debug, Clone)]
pub struct Point<P, const DIM: usize> {
pub coords: [P; DIM],
}
impl<P: FP, const DIM: usize> Point<P, DIM> {
pub fn new(coords: [P; DIM]) -> Point<P, DIM> {
for coord in &coords {
assert!(Float::is_finite(*coord), "{:?} should be finite", coord);
}
Point { coords }
}
pub fn from_slice(slice: &[P]) -> Point<P, DIM> {
Point::new(slice.try_into().unwrap())
}
}
impl<P: FP, const DIM: usize> Deref for Point<P, DIM> {
type Target = [P];
fn deref(&self) -> &[P] {
&self.coords
}
}
impl<P: FP, const DIM: usize> DerefMut for Point<P, DIM> {
fn deref_mut(&mut self) -> &mut [P] {
&mut self.coords
}
}
impl<P: FP, const DIM: usize> AsRef<[P]> for Point<P, DIM> {
fn as_ref(&self) -> &[P] {
&self.coords
}
}
impl<P: FP, const DIM: usize> AsMut<[P]> for Point<P, DIM> {
fn as_mut(&mut self) -> &mut [P] {
&mut self.coords
}
}
#[derive(Debug, Clone)]
pub struct LineSegment<P: FP, const DIM: usize> {
pub x: Point<P, DIM>,
pub y: Point<P, DIM>,
}
impl<P: FP, const DIM: usize> LineSegment<P, DIM> {
pub fn new(x: [P; DIM], y: [P; DIM]) -> LineSegment<P, DIM> {
LineSegment {
x: Point::new(x),
y: Point::new(y),
}
}
pub fn from_slices(x: &[P], y: &[P]) -> LineSegment<P, DIM> {
LineSegment {
x: Point::from_slice(x),
y: Point::from_slice(y),
}
}
}
#[derive(Debug, Clone)]
pub struct Rect<P: FP, const DIM: usize> {
pub edges: [(P, P); DIM],
}
impl<P: FP, const DIM: usize> Rect<P, DIM> {
pub fn new(mut edges: [(P, P); DIM]) -> Rect<P, DIM> {
for &mut (ref mut x, ref mut y) in &mut edges {
assert!(Float::is_finite(*x), "{:?} should be finite", x);
assert!(Float::is_finite(*y), "{:?} should be finite", y);
*x = Float::min(*x, *y);
*y = Float::max(*x, *y);
}
Rect { edges }
}
pub fn from_corners(x: [P; DIM], y: [P; DIM]) -> Rect<P, DIM> {
use crate::tree::mbr::MbrLeafGeometry;
let mut edges = Rect::max_inverted();
Point::new(x).expand_mbr_to_fit(&mut edges);
Point::new(y).expand_mbr_to_fit(&mut edges);
edges
}
pub fn max_inverted() -> Rect<P, DIM> {
let edges = [(Bounded::max_value(), Bounded::min_value()); DIM];
Rect { edges }
}
pub fn max() -> Rect<P, DIM> {
let edges = [(Bounded::min_value(), Bounded::max_value()); DIM];
Rect { edges }
}
}
impl<P: FP, const DIM: usize> Deref for Rect<P, DIM> {
type Target = [(P, P)];
fn deref(&self) -> &[(P, P)] {
&self.edges
}
}
impl<P: FP, const DIM: usize> DerefMut for Rect<P, DIM> {
fn deref_mut(&mut self) -> &mut [(P, P)] {
&mut self.edges
}
}
impl<P: FP, const DIM: usize> AsRef<[(P, P)]> for Rect<P, DIM> {
fn as_ref(&self) -> &[(P, P)] {
self.deref()
}
}
impl<P: FP, const DIM: usize> AsMut<[(P, P)]> for Rect<P, DIM> {
fn as_mut(&mut self) -> &mut [(P, P)] {
self.deref_mut()
}
}
#[derive(Debug, Clone)]
pub enum Shapes<P: FP, const DIM: usize> {
Point(Point<P, DIM>),
LineSegment(LineSegment<P, DIM>),
Rect(Rect<P, DIM>), }