vector-traits 0.6.2

Rust traits for 2D and 3D vector types.
Documentation
// SPDX-License-Identifier: MIT OR Apache-2.0
// Copyright (c) 2023, 2025 lacklustr@protonmail.com https://github.com/eadf

// This file is part of vector-traits.
use crate::prelude::*;
use std::{borrow::Borrow, fmt::Debug};

/// A simple 2d axis aligned bounding box
pub trait Aabb2: Sync + Send + Copy + Clone + Debug + Sized + Default + PartialEq {
    type Vector: GenericVector2;

    /// Creates an AABB from a single point (degenerate AABB)
    fn from_point(point: Self::Vector) -> Self;

    /// Creates an AABB enclosing two points (min and max)
    fn from_corners(min: Self::Vector, max: Self::Vector) -> Self;

    /// Creates an AABB from a center and half-extents
    fn from_center_and_half_extents(center: Self::Vector, half_extents: Self::Vector) -> Self;

    /// Creates an AABB from a center and full size
    fn from_center_and_size(center: Self::Vector, size: Self::Vector) -> Self;

    /// Creates an AABB from an iterator of points (borrowed or owned).
    /// Does not consume the original data.
    fn from_points<I>(points: I) -> Self
    where
        I: IntoIterator,
        I::Item: Borrow<Self::Vector>;
    /// returns false if the Aabb is initialized with any value (including just one point)
    fn is_empty(&self) -> bool;
    fn add_point(&mut self, vec: Self::Vector);
    fn add_aabb(&mut self, other: &Self);
    /// Uniformly pads the AABB around its center.
    /// - Positive `delta` = expand outward.
    /// - Negative `delta` = shrink inward (clamped to center).
    fn pad(&mut self, vec: Self::Vector);
    /// Faster but less strict padding. Simply adds `delta` to each side.
    /// - Can invert the AABB if `delta` is too negative.
    /// - Useful when you know `delta` is always positive or handled externally.
    fn fast_pad(&mut self, vec: Self::Vector);
    /// returns (inf, inf) when is_empty() is true
    fn min(&self) -> Self::Vector;
    /// returns (-inf, -inf) when is_empty() is true
    fn max(&self) -> Self::Vector;
    /// returns (nan, nan) when is_empty() is true
    fn center(&self) -> Self::Vector;
    fn contains_point_inclusive(&self, point: Self::Vector) -> bool;
    /// returns true if this aabb entirely contains 'other' (inclusive)
    fn contains_aabb_inclusive(&self, other: &Self) -> bool;
    /// returns the extents of this aabb. (min, max, delta)
    /// returns (+inf, -inf, nan) when is_empty() is true
    fn extents(&self) -> (Self::Vector, Self::Vector, Self::Vector);
    /// returns the convex hull defined by this AABB
    fn convex_hull(&self) -> Vec<Self::Vector>;
    /// Applies and assigns the return value of the closure on min and max
    fn apply<F>(&mut self, f: F)
    where
        F: Fn(Self::Vector) -> Self::Vector;
}

/// A simple 3d axis aligned bounding box
pub trait Aabb3: Sync + Send + Copy + Clone + Debug + Sized + PartialEq + Default {
    type Vector: GenericVector3;

    /// Creates an AABB from a single point (degenerate AABB)
    fn from_point(point: Self::Vector) -> Self;
    /// Creates an AABB enclosing two points (min and max)
    fn from_corners(min: Self::Vector, max: Self::Vector) -> Self;
    /// Creates an AABB from a center and half-extents
    fn from_center_and_half_extents(center: Self::Vector, half_extents: Self::Vector) -> Self;
    /// Creates an AABB from a center and full size
    fn from_center_and_size(center: Self::Vector, size: Self::Vector) -> Self;
    /// Creates an AABB from an iterator of points (borrowed or owned).
    /// Does not consume the original data.
    fn from_points<I>(points: I) -> Self
    where
        I: IntoIterator,
        I::Item: Borrow<Self::Vector>;
    /// returns false if the Aabb is initialized with any value (including just one point)
    fn is_empty(&self) -> bool;
    /// extends the boundaries of the AABB with the position of the point
    fn add_point(&mut self, point: Self::Vector);
    fn add_aabb(&mut self, other: &Self);
    /// Uniformly pads the AABB around its center.
    /// - Positive `delta` = expand outward.
    /// - Negative `delta` = shrink inward (clamped to center).
    fn pad(&mut self, vec: Self::Vector);
    /// Faster but less strict padding. Simply adds `delta` to each side.
    /// - Can invert the AABB if `delta` is too negative.
    /// - Useful when you know `delta` is always positive or handled externally.
    fn fast_pad(&mut self, vec: Self::Vector);
    /// returns (inf, inf, inf) when is_empty() is true
    fn min(&self) -> Self::Vector;
    /// returns (-inf, -inf, -inf) when is_empty() is true
    fn max(&self) -> Self::Vector;
    /// returns (nan, nan, nan) when is_empty() is true
    fn center(&self) -> Self::Vector;
    /// returns true if the point lies inside the AABB
    fn contains_point_inclusive(&self, point: Self::Vector) -> bool;

    /// returns true if this aabb entirely contains 'other' (inclusive)
    fn contains_aabb_inclusive(&self, other: &Self) -> bool;
    /// returns the extents of this aabb. (min, max, delta)
    fn extents(&self) -> (Self::Vector, Self::Vector, Self::Vector);

    /// Try to figure out what axes defines the plane.
    /// If the AABB delta of one axis (a) is virtually nothing compared to
    /// the widest axis (b) while the third axis (c) is comparable to (b)
    /// by some fraction, we assume that (a) isn't part of the plane.
    ///
    /// It's not possible to compare to zero exactly because blender
    /// leaves some decimal in coordinates that's supposed to be zero.
    fn get_plane(&self) -> Option<Plane>;
    /// Try to figure out what axes defines the plane.
    /// If the AABB delta of one axis (a) is virtually nothing compared to
    /// the widest axis (b) while the third axis (c) is comparable to (b)
    /// by some fraction, we assume that (a) isn't part of the plane.
    ///
    /// It's not possible to compare to zero exactly because blender
    /// leaves some decimal in coordinates that's supposed to be zero.
    fn get_plane_relaxed(
        &self,
        epsilon: <Self::Vector as HasXY>::Scalar,
        max_ulps: u32,
    ) -> Option<Plane>;
    /// Applies and assigns the return value of the closure on min and max
    fn apply<F>(&mut self, f: F)
    where
        F: Fn(Self::Vector) -> Self::Vector;
}