1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use crate::{
    components::{HalfSizes2D, Position2D},
    datatypes::Vec2D,
};

use super::Boxes2D;

impl Boxes2D {
    /// Creates new [`Boxes2D`] with [`Self::half_sizes`] centered around the local origin.
    #[inline]
    pub fn from_half_sizes(half_sizes: impl IntoIterator<Item = impl Into<HalfSizes2D>>) -> Self {
        Self::new(half_sizes)
    }

    /// Creates new [`Boxes2D`] with [`Self::centers`] and [`Self::half_sizes`].
    #[inline]
    pub fn from_centers_and_half_sizes(
        centers: impl IntoIterator<Item = impl Into<Position2D>>,
        half_sizes: impl IntoIterator<Item = impl Into<HalfSizes2D>>,
    ) -> Self {
        Self::new(half_sizes).with_centers(centers)
    }

    /// Creates new [`Boxes2D`] with [`Self::half_sizes`] created from (full) sizes.
    ///
    /// TODO(#3285): Does *not* preserve data as-is and instead creates half-sizes from the input data.
    #[inline]
    pub fn from_sizes(sizes: impl IntoIterator<Item = impl Into<Vec2D>>) -> Self {
        Self::new(sizes.into_iter().map(|wh| {
            let wh = wh.into();
            HalfSizes2D::new(wh.x() / 2.0, wh.y() / 2.0)
        }))
    }

    /// Creates new [`Boxes2D`] with [`Self::centers`] and [`Self::half_sizes`] created from centers and (full) sizes.
    ///
    /// TODO(#3285): Does *not* preserve data as-is and instead creates half-sizes from the input data.
    #[inline]
    pub fn from_centers_and_sizes(
        centers: impl IntoIterator<Item = impl Into<Position2D>>,
        sizes: impl IntoIterator<Item = impl Into<Vec2D>>,
    ) -> Self {
        Self::from_sizes(sizes).with_centers(centers)
    }

    /// Creates new [`Boxes2D`] with [`Self::centers`] and [`Self::half_sizes`] created from minimums and (full) sizes.
    ///
    /// TODO(#3285): Does *not* preserve data as-is and instead creates centers and half-sizes from the input data.
    pub fn from_mins_and_sizes(
        mins: impl IntoIterator<Item = impl Into<Vec2D>>,
        sizes: impl IntoIterator<Item = impl Into<Vec2D>>,
    ) -> Self {
        let boxes = Self::from_sizes(sizes);
        let centers: Vec<_> = mins
            .into_iter()
            .zip(boxes.half_sizes.iter())
            .map(|(min, half_size)| {
                let min = min.into();
                Position2D::new(min.x() + half_size.x(), min.y() + half_size.y())
            })
            .collect();
        boxes.with_centers(centers)
    }
}