use crate::geometry::Geometry;
use crate::indexed_access::{IndexedAccess, corner};
use crate::point::PointMut;
use crate::segment::materialise;
use geometry_tag::BoxTag;
pub trait Box: Geometry<Kind = BoxTag> + IndexedAccess {}
pub fn box_min<B: Box>(b: &B) -> B::Point
where
B::Point: Default + PointMut,
{
materialise::<B, { corner::MIN }>(b)
}
pub fn box_max<B: Box>(b: &B) -> B::Point
where
B::Point: Default + PointMut,
{
materialise::<B, { corner::MAX }>(b)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::point::Point;
use geometry_cs::Cartesian;
use geometry_tag::PointTag;
#[derive(Default)]
struct Xy {
x: f64,
y: f64,
}
impl Geometry for Xy {
type Kind = PointTag;
type Point = Self;
}
impl Point for Xy {
type Scalar = f64;
type Cs = Cartesian;
const DIM: usize = 2;
fn get<const D: usize>(&self) -> f64 {
if D == 0 { self.x } else { self.y }
}
}
impl PointMut for Xy {
fn set<const D: usize>(&mut self, v: f64) {
if D == 0 {
self.x = v;
} else {
self.y = v;
}
}
}
struct MyBox {
c: [[f64; 2]; 2],
}
impl Geometry for MyBox {
type Kind = BoxTag;
type Point = Xy;
}
impl IndexedAccess for MyBox {
fn get_indexed<const I: usize, const D: usize>(&self) -> f64 {
self.c[I][D]
}
fn set_indexed<const I: usize, const D: usize>(&mut self, v: f64) {
self.c[I][D] = v;
}
}
impl Box for MyBox {}
#[test]
fn box_indexed_round_trip() {
let mut b = MyBox { c: [[0.0; 2]; 2] };
b.set_indexed::<{ corner::MIN }, 0>(1.0);
b.set_indexed::<{ corner::MIN }, 1>(2.0);
b.set_indexed::<{ corner::MAX }, 0>(3.0);
b.set_indexed::<{ corner::MAX }, 1>(4.0);
assert_eq!(
b.get_indexed::<{ corner::MIN }, 0>().to_bits(),
1.0_f64.to_bits()
);
assert_eq!(
b.get_indexed::<{ corner::MAX }, 1>().to_bits(),
4.0_f64.to_bits()
);
}
#[test]
fn box_corners_materialise() {
let mut b = MyBox { c: [[0.0; 2]; 2] };
b.set_indexed::<{ corner::MIN }, 0>(1.0);
b.set_indexed::<{ corner::MIN }, 1>(2.0);
b.set_indexed::<{ corner::MAX }, 0>(3.0);
b.set_indexed::<{ corner::MAX }, 1>(4.0);
let lo = box_min(&b);
let hi = box_max(&b);
assert_eq!(lo.get::<0>().to_bits(), 1.0_f64.to_bits());
assert_eq!(lo.get::<1>().to_bits(), 2.0_f64.to_bits());
assert_eq!(hi.get::<0>().to_bits(), 3.0_f64.to_bits());
assert_eq!(hi.get::<1>().to_bits(), 4.0_f64.to_bits());
}
}