BoundingBox

Struct BoundingBox 

Source
pub struct BoundingBox { /* private fields */ }
Expand description

A rectilinear, 2-dimensional bounding box.

A 2-dimensional rectilinear bounding box is described by four values: minimum x-value, maximum x-value, minimum y-value and and maximum y-value. This struct can be created either from any type which implements ToBoundingBox or from the constructors new or try_new. The values defining a bounding box (xmin, xmax, ymin, ymax) are called “extremas”.

Since a bounding box only consists of four f64 values (32 bytes), it is cheap to copy, hence it implements the Copy trait.

Implementations§

Source§

impl BoundingBox

Source

pub fn new(xmin: f64, xmax: f64, ymin: f64, ymax: f64) -> Self

Generates a bounding box from minimum and maximum x- and y-values.

§Panics

Panics if xmin > xmax or if ymin > ymax.

§Examples
use bounding_box::BoundingBox;

let _ = BoundingBox::new(0.0, 1.0, 0.0, 1.0);

This example panics because xmin > xmax.

use bounding_box::BoundingBox;

let _ = BoundingBox::new(2.0, 1.0, 0.0, 1.0);
Source

pub fn try_new(xmin: f64, xmax: f64, ymin: f64, ymax: f64) -> Option<Self>

Like BoundingBox::new, but returns None instead of panicking if xmin > xmax or if ymin > ymax.

§Examples
use bounding_box::BoundingBox;

assert!(BoundingBox::try_new(0.0, 1.0, 0.0, 1.0).is_some());
assert!(BoundingBox::try_new(2.0, 1.0, 0.0, 1.0).is_none());
Source

pub fn xmin(&self) -> f64

Returns the minimum x-value of the bounding box.

Source

pub fn xmax(&self) -> f64

Returns the maximum x-value of the bounding box.

Source

pub fn ymin(&self) -> f64

Returns the minimum y-value of the bounding box.

Source

pub fn ymax(&self) -> f64

Returns the maximum y-value of the bounding box.

Source

pub fn try_set_xmin(&mut self, val: f64) -> bool

Fallible sets a new value for xmin. If the new value is bigger than xmax, the old value is left unchanged and this function returns false. Otherwise, it returns true and the old value is replaced by the new value.

§Examples
use bounding_box::BoundingBox;

let mut bb = BoundingBox::new(0.0, 1.0, 0.0, 1.0);

assert_eq!(bb.xmin(), 0.0);
assert!(bb.try_set_xmin(0.5));
assert_eq!(bb.xmin(), 0.5);

assert!(!bb.try_set_xmin(1.5));
assert_eq!(bb.xmin(), 0.5);
Source

pub fn try_set_xmax(&mut self, val: f64) -> bool

Fallible sets a new value for xmax. If the new value is smaller than xmin, the old value is left unchanged and this function returns false. Otherwise, it returns true and the old value is replaced by the new value.

§Examples
use bounding_box::BoundingBox;

let mut bb = BoundingBox::new(0.0, 1.0, 0.0, 1.0);

assert_eq!(bb.xmax(), 1.0);
assert!(bb.try_set_xmax(0.5));
assert_eq!(bb.xmax(), 0.5);

assert!(!bb.try_set_xmax(-0.5));
assert_eq!(bb.xmax(), 0.5);
Source

pub fn try_set_ymin(&mut self, val: f64) -> bool

Fallible sets a new value for ymin. If the new value is bigger than ymax, the old value is left unchanged and this function returns false. Otherwise, it returns true and the old value is replaced by the new value.

§Examples
use bounding_box::BoundingBox;

let mut bb = BoundingBox::new(0.0, 1.0, 0.0, 1.0);

assert_eq!(bb.ymin(), 0.0);
assert!(bb.try_set_ymin(0.5));
assert_eq!(bb.ymin(), 0.5);

assert!(!bb.try_set_ymin(1.5));
assert_eq!(bb.ymin(), 0.5);
Source

pub fn try_set_ymax(&mut self, val: f64) -> bool

Fallible sets a new value for ymax. If the new value is smaller than ymin, the old value is left unchanged and this function returns false. Otherwise, it returns true and the old value is replaced by the new value.

§Examples
use bounding_box::BoundingBox;

let mut bb = BoundingBox::new(0.0, 1.0, 0.0, 1.0);

assert_eq!(bb.ymax(), 1.0);
assert!(bb.try_set_ymax(0.5));
assert_eq!(bb.ymax(), 0.5);

assert!(!bb.try_set_ymax(-0.5));
assert_eq!(bb.ymax(), 0.5);
Source

pub fn from_vertices<'a, T: Into<[f64; 2]>, I: Iterator<Item = T>>( verts: I, ) -> Option<Self>

Creates a bounding box from an iterator over vertices.

If the iterator is empty, this function returns None.

use bounding_box::BoundingBox;

let verts = vec![
    [1.0, 0.0],
    [-5.0, 2.0],
    [3.0, -12.3],
    [7.0, 0.0],
    [2.0, 11.0],
    [1.0, -6.0],
];

 let bb = BoundingBox::from_vertices(verts.into_iter()).expect("iterator yields at least one elment");
 assert_eq!(bb.xmin(), -5.0);
 assert_eq!(bb.xmax(), 7.0);
 assert_eq!(bb.ymin(), -12.3);
 assert_eq!(bb.ymax(), 11.0);
Source

pub fn from_bounded_entities<'a, T: ToBoundingBox + ?Sized + 'a, I: Iterator<Item = &'a T>>( entities: I, ) -> Option<Self>

Creates a bounding box from an iterator over any types implementing ToBoundingBox.

If the iterator is empty, this function returns None.

use bounding_box::{BoundingBox, ToBoundingBox};

struct Circle {
    center: [f64; 2],
    radius: f64
}

impl ToBoundingBox for Circle {
    fn bounding_box(&self) -> BoundingBox {
        return BoundingBox::new(self.center[0] - self.radius,
                                self.center[0] + self.radius,
                                self.center[1] - self.radius,
                                self.center[1] + self.radius);
    }
}

let c1 = Circle {center: [0.0, 0.0], radius: 1.0};
let c2 = Circle {center: [0.0, 2.0], radius: 1.0};
let c3 = Circle {center: [0.0, 2.0], radius: 2.0};

let bb = BoundingBox::from_bounded_entities([&c1, &c2, &c3].into_iter()).expect("iterator has at least one element");
assert_eq!(bb.xmin(), -2.0);
assert_eq!(bb.xmax(), 2.0);
assert_eq!(bb.ymin(), -1.0);
assert_eq!(bb.ymax(), 4.0);
Source

pub fn union(&self, other: &BoundingBox) -> BoundingBox

Creates the union of two bounding boxes.

The union of two bounding boxes is the minimum bounding box which contains both bounding boxes.

§Examples
use bounding_box::BoundingBox;

let bb1 = BoundingBox::new(-1.0, 3.5, 2.0, 3.0);
let bb2 = BoundingBox::new(-5.0, 2.5, -1.0, 5.0);
let bb = bb1.union(&bb2);

assert_eq!(bb.xmin(), -5.0);
assert_eq!(bb.xmax(), 3.5);
assert_eq!(bb.ymin(), -1.0);
assert_eq!(bb.ymax(), 5.0);
Source

pub fn contains_point<T: Into<[f64; 2]>>(&self, point: T) -> bool

Returns true if self contains a given point.

A point is also seen as included if it is located on the edge of a bounding box.

§Examples
use bounding_box::BoundingBox;

let bb = BoundingBox::new(0.0, 1.0, 0.0, 1.0);

assert!(bb.contains_point([0.5, 0.5]));
assert!(bb.contains_point([0.0, 0.0]));
assert!(bb.contains_point([0.0, 0.0]));
assert!(!bb.contains_point([-1.0, 0.0]));
assert!(!bb.contains_point([0.0, 2.0]));
     
Source

pub fn approx_contains_point<T: Into<[f64; 2]>>( &self, point: T, epsilon: f64, max_ulps: u32, ) -> bool

Like BoundingBox::contains_point, but with absolute and ULPs tolerances.

This variant of BoundingBox::contains_point allows specifying an absolute and an ULP tolerance. These tolerances are used to check if the given point lies “approximately” on an edge of the bounding box. This check is performed using the ulps_eq macro of the approx crate. Please see its documentation.

§Examples
use bounding_box::BoundingBox;

let bb = BoundingBox::new(0.0, 1.0, 0.0, 1.0);

// Exact check: Point is outside the bounding box
assert!(!bb.contains_point([1.0001, 1.0]));

// Check using tolerances: Point is inside bounding box
assert!(bb.approx_contains_point([1.0001, 1.0], 1e-3, 0));

// Check using a finer tolerance: Point is outside the bounding box
assert!(!bb.approx_contains_point([1.0001, 1.0], 1e-6, 0));
Source

pub fn contains(&self, other: &Self) -> bool

Returns true if self contains other.

A bounding box contains another bounding box, if the latter can be placed inside the former. This is true even if the boxes share some extremums. This also means that a bounding box always contains itself (see examples).

§Examples
use bounding_box::BoundingBox;

// bb1 contains bb2, but not the other way around
let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(0.2, 0.8, 0.2, 0.8);
assert!(bb1.contains(&bb2));
assert!(!bb2.contains(&bb1));

// bb1 contains itself
assert!(bb1.contains(&bb1));

// bb1 and bb2 share a border
let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(0.2, 1.0, 0.2, 0.8);
assert!(bb1.contains(&bb2));

// bb1 and bb2 are separated from each other, and therefore neither of one contains the other
let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(2.0, 3.0, 2.0, 3.0);
assert!(!bb1.contains(&bb2));
assert!(!bb2.contains(&bb1));
Source

pub fn approx_contains(&self, other: &Self, epsilon: f64, max_ulps: u32) -> bool

Like BoundingBox::contains, but with absolute and ULPs tolerances.

This variant of BoundingBox::contains allows specifying an absolute and an ULP tolerance. These tolerances are used to check if the extremas of the boxes are “approximately” equal. This check is performed using the ulps_eq macro of the approx crate. Please see its documentation.

use bounding_box::BoundingBox;

// bb1 contains bb2 depending on the selected tolerances
let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(0.0, 1.0001, 0.0, 0.5);

assert!(!bb1.contains(&bb2));
assert!(bb1.approx_contains(&bb2, 1e-3, 0));
assert!(!bb1.approx_contains(&bb2, 1e-6, 0));
Source

pub fn approx_eq(&self, other: &Self, epsilon: f64, max_ulps: u32) -> bool

Check if the two bounding boxes are approximately equal. This check is performed using the ulps_eq macro of the approx crate. Please see its documentation.

use bounding_box::BoundingBox;

// bb1 contains bb2 depending on the selected tolerances
let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(0.0, 1.0001, 0.0, 1.0);

assert!(!bb1.eq(&bb2));
assert!(bb1.approx_eq(&bb2, 1e-3, 0));
assert!(!bb1.approx_eq(&bb2, 1e-6, 0));
Source

pub fn intersects(&self, other: &Self) -> bool

Returns true if the bounding boxes intersect.

The boxes are NOT intersecting if they are just touching.

§Examples
use bounding_box::BoundingBox;

// bb1 and bb2 intersect
let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(-1.0, 1.0, 0.2, 0.8);
assert!(bb1.intersects(&bb2));

 // bb1 and bb2 do not intersect
let bb1 = BoundingBox::new(-1.0, 3.5, 2.0, 3.0);
let bb2 = BoundingBox::new(-5.0, 2.5, -1.0, 1.0);
assert!(!bb1.intersects(&bb2));

// bb2 is contained in bb1
let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(0.2, 1.0, 0.2, 0.8);
assert!(bb1.intersects(&bb2));

// bb1 is contained in bb2
let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(0.2, 1.0, 0.2, 0.8);
assert!(bb2.intersects(&bb1));

// bb1 touches bb2 => no intersection
let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(1.0, 2.0, 0.0, 1.0);
assert!(!bb2.intersects(&bb1));
Source

pub fn touches(&self, other: &Self) -> bool

Check if the bounding boxes are touching.

The bounding boxes are touching if they share at least one extremum and are not intersecting each other.

§Examples
use bounding_box::BoundingBox;

// bb1 touches bb2 => no intersection
let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(1.0, 2.0, 0.0, 1.0);
assert!(bb2.touches(&bb1));

// bb1 is included in bb2 and two edges are touching
let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(0.0, 2.0, 0.0, 1.0);
assert!(!bb2.touches(&bb1));

let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(1.0001, 2.0, 0.0, 1.0);
assert!(!bb2.touches(&bb1));
Source

pub fn approx_touches(&self, other: &Self, epsilon: f64, max_ulps: u32) -> bool

Like BoundingBox::touches, but with absolute and ULPs tolerances.

This variant of BoundingBox::touches allows specifying an absolute and an ULP tolerance. These tolerances are used to check if the boxes share at least one extremas “approximately”. This check is performed using the ulps_eq macro of the approx crate. Please see its documentation.

§Examples
use bounding_box::BoundingBox;

let bb1 = BoundingBox::new(0.0, 1.0, 0.0, 1.0);
let bb2 = BoundingBox::new(1.0001, 2.0, 0.0, 1.0);
assert!(!bb1.touches(&bb2));
assert!(bb1.approx_touches(&bb2, 1e-3, 0));
assert!(!bb1.approx_touches(&bb2, 1e-6, 0));
Source

pub fn width(&self) -> f64

Returns the width of the bounding box.

§Examples
use bounding_box::BoundingBox;

let bb = BoundingBox::new(-1.0, 1.0, 2.0, 7.0);
assert_eq!(bb.width(), 2.0);
Source

pub fn height(&self) -> f64

Returns the height of the bounding box.

§Examples
use bounding_box::BoundingBox;

let bb = BoundingBox::new(-1.0, 1.0, 2.0, 7.0);
assert_eq!(bb.height(), 5.0);
Source

pub fn center(&self) -> [f64; 2]

Returns the center of the bounding box.

§Examples
use bounding_box::BoundingBox;

let bb = BoundingBox::new(-1.0, 1.0, 2.0, 7.0);
assert_eq!(bb.center(), [0.0, 4.5]);
Source

pub fn translate<T: Into<[f64; 2]>>(&mut self, shift: T)

Translates the bounding box by the given shift.

§Examples
use bounding_box::BoundingBox;

let mut bb = BoundingBox::new(0.0, 1.0, 1.0, 2.0);
bb.translate([1.0, -1.0]);
assert_eq!(bb.xmin(), 1.0);
assert_eq!(bb.xmax(), 2.0);
assert_eq!(bb.ymin(), 0.0);
assert_eq!(bb.ymax(), 1.0);
Source

pub fn scale(&mut self, factor: f64)

Scales the width and height of self while keeping the center fixed.

The bounding box is scaled by multiplying its width and height by the factor and then recalculating the extremas by adding / subtracting half the width / height from the center.

§Examples
use bounding_box::BoundingBox;

let mut bb = BoundingBox::new(0.0, 1.0, 2.0, 4.0);

assert_eq!(bb.center(), [0.5, 3.0]);
assert_eq!(bb.width(), 1.0);
assert_eq!(bb.height(), 2.0);

bb.scale(2.0);

assert_eq!(bb.center(), [0.5, 3.0]);
assert_eq!(bb.width(), 2.0);
assert_eq!(bb.height(), 4.0);

assert_eq!(bb.xmin(), -0.5);
assert_eq!(bb.xmax(), 1.5);
assert_eq!(bb.ymin(), 1.0);
assert_eq!(bb.ymax(), 5.0);
Source

pub fn remove_singular_dimensions(&mut self, add_to_extr: f64)

Remove any singular dimensions by “buffering” them with add_to_extr.

The value add_to_extr is applied to both the minimum and the maximum value of a singular dimension. For example, if the bounding box width is 0 (xmin = xmax) and add_to_extr = 1.0, the new width will be 2.0.

§Examples
use bounding_box::BoundingBox;

let mut bb = BoundingBox::new(0.0, 0.0, -1.0, 1.0);
assert_eq!(bb.width(), 0.0);

bb.remove_singular_dimensions(1.0);
assert_eq!(bb.width(), 2.0);
assert_eq!(bb.xmin(), -1.0);
assert_eq!(bb.xmax(), 1.0);

// =================================================

let mut bb = BoundingBox::new(-1.0, 1.0, 2.0, 2.0);
assert_eq!(bb.height(), 0.0);

bb.remove_singular_dimensions(3.0);
assert_eq!(bb.height(), 6.0);
assert_eq!(bb.ymin(), -1.0);
assert_eq!(bb.ymax(), 5.0);
Source

pub fn is_finite(&self) -> bool

Returns true if the bounding box is finite.

§Examples
use std::f64::INFINITY;
use bounding_box::BoundingBox;

assert!(BoundingBox::new(0.0, 1.0, 0.0, 1.0).is_finite());
assert!(!BoundingBox::new(0.0, INFINITY, 0.0, 1.0).is_finite());

Trait Implementations§

Source§

impl Clone for BoundingBox

Source§

fn clone(&self) -> BoundingBox

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for BoundingBox

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for BoundingBox

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<T: ToBoundingBox> From<T> for BoundingBox

Source§

fn from(value: T) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for BoundingBox

Source§

fn eq(&self, other: &BoundingBox) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for BoundingBox

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Copy for BoundingBox

Source§

impl StructuralPartialEq for BoundingBox

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,